Я пытаюсь использовать отражение для получения доступ к некоторым неопубликованным функциям телефонии API. В настоящее время я испытываю затруднения при инстанцировании a serviceManager
объект, который необходим для получения "телефонного" сервиса как редактора связей, который я могу затем использовать для инстанцирования объекта телефонии, который необходим, чтобы позвонить, закончить вызов, и т.д...
в настоящее время, когда я выполняю вызов
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { new Binder() });
это возвращает nullPointerException. Я полагаю, что это имеет отношение к созданию нового Редактора связей вместо того, чтобы отправить соответствующий редактор связей (который я не уверен, из которых является соответствующим),
public void placeReflectedCall() throws ClassNotFoundException,
SecurityException, NoSuchMethodException, IllegalArgumentException,
IllegalAccessException, InvocationTargetException,
InstantiationException {
String serviceManagerName = "android.os.IServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class telephonyClass;
Class telephonyStubClass;
Class serviceManagerClass;
Class serviceManagerStubClass;
Class serviceManagerNativeClass;
Class serviceManagerNativeStubClass;
Method telephonyCall;
Method telephonyEndCall;
Method telephonyAnswerCall;
Method getDefault;
Method[] temps;
Constructor[] serviceManagerConstructor;
// Method getService;
Object telephonyObject;
Object serviceManagerObject;
String number = "1111111111";
telephonyClass = Class.forName(telephonyName);
telephonyStubClass = telephonyClass.getClasses()[0];
serviceManagerClass = Class.forName(serviceManagerName);
serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
Method getService = // getDefaults[29];
serviceManagerClass.getMethod("getService", String.class);
Method tempInterfaceMethod = serviceManagerNativeClass.getMethod(
"asInterface", IBinder.class);
// this does not work
serviceManagerObject = tempInterfaceMethod.invoke(null,
new Object[] { new Binder() });
IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject,
"phone");
Method serviceMethod = telephonyStubClass.getMethod("asInterface",
IBinder.class);
telephonyObject = serviceMethod
.invoke(null, new Object[] { retbinder });
telephonyCall = telephonyClass.getMethod("call", String.class);
telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyAnswerCall = telephonyClass.getMethod("answerRingingCall");
telephonyCall.invoke(telephonyObject, number);
}
Делая следующее
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { tmpBinder });
вы получите экземпляр ServiceManagerProxy, затем на линии
telephonyCall.invoke(telephonyObject, number);
Да, это возможно! Я потратил 24 часа на исследования и открытия, и я нашел "свежее" решение!
// "cheat" with Java reflection to gain access to
// TelephonyManager's ITelephony getter
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);
Любой, кто хочет разработать свое программное обеспечение для контроля вызовов, посетите эту стартовую точку:
http://www.google.com/codesearch/p?hl=en#zvQ8rp58BUs/trunk/phone/src/i4nc4mp/myLock/phone/CallPrompt.java&q=itelephony%20package:http://mylockforandroid%5C.googlecode%5C.com&d=0
Там есть проект. и там есть важные комментарии (и кредиты).
Вкратце: скопировать файл aidl, добавить разрешения в манифест, скопировать-вставить исходники для управления телефонией.
Еще немного информации для вас: Вы можете отправлять AT-команды, только если вы рутированы. Тогда вы можете убить системный процесс и отправлять команды, но вам потребуется перезагрузка, чтобы телефон мог принимать и отправлять звонки.
Я очень счастлив! Теперь мой Shake2MuteCall получит обновление!
У меня есть решение. Изменение:
String serviceManagerName = "android.os.IServiceManager";
на:
String serviceManagerName = "android.os.ServiceManager";