两种方法 :1. 反射 2. 狸猫换太子 把系统的class.jar 导入项目的libs文件夹 使用该jar包
1.反射
获取u盘路径
public static String getUDiskPath() {
StorageManager mStorageManager = getContext().getSystemService(StorageManager.class);
if (mStorageManager != null) {
try {
Class storeManagerClazz = null;
try {
storeManagerClazz = Class.forName("android.os.storage.StorageManager");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method getVolumesMethod = storeManagerClazz.getMethod("getVolumes");
List<?> volumeInfos = (List<?>) getVolumesMethod.invoke(mStorageManager);
Class volumeInfoClazz = Class.forName("android.os.storage.VolumeInfo");
Method getFsUuidMethod = volumeInfoClazz.getMethod("getFsUuid");
Field pathField = volumeInfoClazz.getDeclaredField("path");
if(volumeInfos != null){
for(Object volumeInfo:volumeInfos){
String uuid = (String)getFsUuidMethod.invoke(volumeInfo);
if(uuid != null){
String pathString = (String)pathField.get(volumeInfo);
return pathString;
}
}
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return null;
}
2.替换jar包
1.获取Android源码并进行编译。
2..编译完毕后,取出out\target\common\obj\JAVA_LIBRARIES\framework_intermediates路径下的classes.jar
3.将classes.jar重命名为framework.jar并添加到Android Studio项目的libs目录下。
4.在build.gradle中的dependencies中,添加:
compileOnly files('libs/framework.jar')
5.在build.gradle中的Android节点设置编译参数 可以解决编译时找不到符号的错误
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
Set<File> fileSet = options.bootstrapClasspath.getFiles()
List<File> newFileList = new ArrayList<>();
//JAVA语法,可连续调用,输入参数建议为相对路径
newFileList.add(new File("libs/framework.jar"))
//最后将原始参数添加
newFileList.addAll(fileSet)
options.bootstrapClasspath = files(
newFileList.toArray()
)
}
}
- 或者在工程的根目录build.gradle中找到allprojects,加入如下代码(新版本无效)
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar')
}
}
allprojects {
tasks.withType(JavaCompile) {
options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\framework.jar')
}
}
7.配置依赖优先级,否则Android studio默认引用配置的Android sdk进行编译,可以解决点击方法名,无法跳转的问题
def imlFile = file("\\..\\.idea\\modules\\app\\"+rootProject.name+'.'+projectDir.name+'.iml')
def imlFile = file("\\..\\.idea\\modules\\"+projectDir.name+"\\"+rootProject.name+'.'+projectDir.name+'.main.iml')
preBuild {
doLast {
//def imlFile = file(project.name + ".iml") //AndroidStudio 3.x 适用
//Android studio4.0的app.iml文件路径为项目/.idea/modules/app/app.iml。早期版本,app.iml文件在项目根目录下
//def imlFile = file("\\..\\.idea\\modules\\app\\app.iml")
def imlFile = file("\\..\\.idea\\modules\\app\\DiagnoseDemoTest.app.main.iml" )
println 'path=' + projectDir.absolutePath
// println 'Change ' + project.name + '.iml order'
try {
def parsedXml = (new XmlParser()).parse(imlFile)
def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
println 'api =' + android.compileSdkVersion.substring("android-".length())
def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
// nop, iml not found
e.printStackTrace();
}
}
}
这个 task 在编译之前, 自动更改.idea/modules/app/DiagnoseDemoTest.app.iml,将下面代码会移动最后,才能在编译时使用我们引入的 framework.jar。
<orderEntry type="jdk" jdkName="Android API 30 Platform" jdkType="Android SDK" />