对于在系统源码中有些类被@hide了。我们在做apk开发时无法像其他类一样 直接调用。所以我们有以下方法:
1.反射
2.放到系统源码下编译
3.用系统签名打包apk
先说说第一种吧 反射:
主要是利用java 中java.lang.Object下的Method类
Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
Method允许在匹配要调用的实参与基础方法的形参时进行扩展转换;但如果要进行收缩转换,则会抛出IllegalArgumentException。
public static boolean[] deviceHasKeys(int[] keyCodes) {
boolean[] ret = new boolean[keyCodes.length];
IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
try {
wm.hasKeys(keyCodes, ret);
} catch (RemoteException e) {
// no fallback; just return the empty array
}
return ret;
}
其中 IWindowManager ServiceManageer均为隐藏类,
要想这样用,有两个方法:
1是修改framwork 让其不为hide class 从而可以使用
2是使用java的映射机制。
下面是使用映射后,对应的代码:
public static boolean[] deviceHasKeys(int[] keyCodes) {
boolean[] ret = new boolean[keyCodes.length];
Method method;
String methodName = "hasKeys";//haskey 为隐藏类的隐藏method
try {
method = Class.forName("android.view.IWindowManager.Stub").getMethod(methodName, String.class);
try {
method.invoke(Class.forName("android.view.IWindowManager.Stub"),keyCodes,ret);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ret;
}
说说第三种引用系统签名打包apk
因为我们的 apk有隐藏类。先生成apk,然后用系统签名文件在build/target/product/security下的platform.pk8和platform.x509.pem这2个文件打包apk(可能根据系统不同。文件名不一样)。然后用java命令打包apk:
java -jar signapk.jar platform.x509.pem platform.pk8 D:\xxx.apk D:\xxxSigned.apk
后一个apk为签名后 的apk