2010-01-04 4 views
20

리플렉션을 사용하여 전화 통신 API의 일부 게시되지 않은 기능에 액세스하려고합니다. 현재 serviceManager 개체를 인스턴스화하는 데 문제가 있습니다.이 개체는 "전화"서비스를 바인더로 사용하여 전화, 끝내기 등의 작업을 수행하는 데 필요한 전화 통신 개체를 인스턴스화하는 데 사용할 수 있습니다.고급 전화 기능에 액세스하기위한 반사

내가 전화

serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { new Binder() }); 

을 할 때

현재는 NullPointerException이 반환합니다. 나는 이것이 당신이 얻을 것이다

Binder tmpBinder = new Binder(); 
tmpBinder.attachInterface(null, "fake"); 
serviceManagerObject = tempInterfaceMethod.invoke(null, new Object[] { tmpBinder }); 

를 다음을 수행하여 (하나는 적절한있는 내가 확실하지 오전) 적절한 바인더

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); 

} 
+0

오류 또는 문제에 대해주는 유일한 정보는 "현재 나는 데 문제가 ServiceManager에 객체를 인스턴스화하는 데 문제". 우리에게 코드를 주셨습니다. 이제는 그것이하고있는 일과하지 않는 일을 예기치 않게 알려주고 올바르게 작동하지 않는다는 것을 어떻게 알 수 있습니까? –

답변

5

을 새로운 바인더를 만드는 대신 전송과 관련이있다 생각 ServiceManagerProxy 인스턴스가 있으면 다음 호가 발생합니다.

telephonyCall.invoke(telephonyObject, number); 
1

예, 가능합니다. 조사하고 발견하는 데 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

프로젝트가있다. 중요한 논평 (및 학점)이 있습니다.

간단히 말해서 : 복사 보조 파일을 사용하여 매니페스트에 대한 사용 권한을 추가하고 전화 통신 관리를 위해 원본을 복사하여 붙여 넣습니다.

몇 가지 더 많은 정보 : 루팅 된 경우에만 AT 명령을 보낼 수 있습니다. 그런 다음 시스템 프로세스를 중단하고 명령을 보낼 수 있지만 전화를 받고 전화를 보내려면 재부팅해야합니다.

매우 기쁩니다! 이제 내 Shake2MuteCall이 업데이트됩니다!

+2

안녕하세요. 나는 mylock의 개발자 다. 2.3에서 더 이상 작동하지 않는다는 것을 알려 드리고자합니다. 우리는 수퍼 유저 루트 권한을 가정하고 동일한 결과를 얻을 수있는 방법을 연구하고 있습니다. 나는이 방법을 생각해 내지 못했고, 내 친구 Tedd가 그것을 발견하고 itlelephony에 반영을 적용하는 길을 찾았다. – mylock

+0

이것은 나를 4.2시에 작동합니다 – AlBeebe

+0

안녕하세요 @AlBeebe 위의 링크가 작동하지 않습니다. 전화 통신을위한 보조 파일과 자료를 공유해주십시오. 그것은 나를 많이 도울 것입니다. –

3

나는 해결책이있다. 변경 :

String serviceManagerName = "android.os.IServiceManager"; 

에 :

String serviceManagerName = "android.os.ServiceManager"; 
+0

이 작품은 나를 위해 !! :) –