如何访问 android系统hide的类或接口

两种方法 :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

如何访问 android系统hide的类或接口_第1张图片

3.将classes.jar重命名为framework.jar并添加到Android Studio项目的libs目录下。

如何访问 android系统hide的类或接口_第2张图片

4.在build.gradle中的dependencies中,添加:

compileOnly files('libs/framework.jar')

5.在build.gradle中的Android节点设置编译参数   可以解决编译时找不到符号的错误 

gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
        Set fileSet = options.bootstrapClasspath.getFiles()
        List newFileList =  new ArrayList<>();
        //JAVA语法,可连续调用,输入参数建议为相对路径
        newFileList.add(new File("libs/framework.jar"))
        //最后将原始参数添加
        newFileList.addAll(fileSet)
        options.bootstrapClasspath = files(
                newFileList.toArray()
        )
    }
}

如何访问 android系统hide的类或接口_第3张图片

  • 或者在工程的根目录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。


你可能感兴趣的:(android,android,studio,java)