我将使用一个特定的api,TelephonyManager.getDeviceId作为示例。我想实现的是绕过TelephonyManager.getDeviceId但仍然获得设备的imei。我是Java和Android的新手。使用Android绑定器的Java反射确实令人头痛......
我研究了TelephonyManager的源代码,发现它是通过IPhoneSubinfo来做的。TelephonyManager souce code
例如,getDeviceId,其在TelephonyManager中的代码主要是
{return getSubscriberInfo().getDeviceId();}
和getSubscriberInfo主要是(它实际上返回一个活页夹代理。)
{return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));}
以下是我要做的事情:
step1,获取TelephonyManager实例。
步骤2,使用反射来获取TelephonyManger的私有方法getSubscriberInfo,设置可访问,然后调用此方法获取IPoneSubInfo实例。
步骤3,使用反射获取IPhoneSubInfo的公共方法getDeviceId,调用此方法获取deviceid。
在此期间,TelephonyManager的getDeviceId永远不会被调用,这是我想要做的。但是在步骤3中,来自IphoneSubInfo的getDeviceId的返回的deviceid为null ...并且为null。 toString()引发异常。
有什么问题?如果有关于这个主题的文档或博客文章,欢迎。
所有代码在这里,代码告诉一切:
TelephonyManager tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
Method TelephonyManager_private_getSubscriberInfo = tel.getClass().getDeclaredMethod("getSubscriberInfo");
TelephonyManager_private_getSubscriberInfo.setAccessible(true);
Object iphonesubinfo = TelephonyManager_private_getSubscriberInfo.invoke(tel);
log(iphonesubinfo.toString());
Method getDeviceId = iphonesubinfo.getClass().getDeclaredMethod("getDeviceId");
log(getDeviceId.toString());
getDeviceId.setAccessible(true);
Object deviceid = getDeviceId.invoke(iphonesubinfo); // why di is null :(
log("deviceid:" + deviceid.toString());
}catch (NoSuchMethodException e){
log("TelephonyManager_private_getSubscriberInfo noSuchMethodException");
e.printStackTrace();
}catch (IllegalAccessException e){
log("TelephonyManager_private_getSubscriberInfo IllegalAccessException");
e.printStackTrace();
}catch (InvocationTargetException e){
log("TelephonyManager_private_getSubscriberInfo InvocationTargetException");
e.printStackTrace();
}