2010-01-04 10 views
20

Sto tentando di utilizzare la riflessione per accedere ad alcune funzionalità non pubblicate dell'API di telefonia. Attualmente sto riscontrando problemi nell'istanziare un oggetto serviceManager necessario per ottenere il servizio "telefono" come raccoglitore che posso quindi utilizzare per istanziare un oggetto di telefonia necessario per effettuare una chiamata, una fine chiamata, ecc ...Riflesso per accedere alle funzioni di telefonia avanzate

attualmente quando faccio la chiamata

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

restituisce un NullPointerException. Credo che questo abbia a che fare con la creazione di un nuovo Binder invece di inviare il legante appropriata (che non sono sicuro di cui uno è appropriato)

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

"Attualmente sto avendo difficoltà un'istanza di un oggetto ServiceManager" è l'unica informazione che si stanno dando sull'errore o un problema. Ci hai dato il codice. Ora dicci cosa sta facendo o non farlo è inaspettato e come sai che non funziona correttamente. –

risposta

5

Facendo il seguente

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

si otterrà un Istanza ServiceManagerProxy, quindi il problema successivo si verifica sulla riga

telephonyCall.invoke(telephonyObject, number); 
1

Sì, è possibile! Ho trascorso 24 ore di ricerche e scoperte e ho trovato una soluzione "fresca"!

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

Chiunque voglia sviluppare il proprio software di controllo delle chiamate visita questo punto di partenza:
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

C'è un progetto. e ci sono commenti importanti (e crediti).

In breve: copia il file aidl, aggiungi le autorizzazioni per manifest, copia-incolla l'origine per la gestione della telefonia.

Altre informazioni per voi: è possibile inviare comandi AT solo se si è rootati. Quindi è possibile interrompere il processo di sistema e inviare i comandi, ma è necessario un riavvio per consentire al telefono di ricevere e inviare chiamate.

Sono molto felice! Ora il mio Shake2MuteCall riceverà un aggiornamento!

+2

ciao. Sono lo sviluppatore di Mylock. volevo solo informarti che questo non funziona più su 2.3 e stiamo studiando come possiamo ottenere lo stesso risultato assumendo il permesso di root per superutente. Non mi è venuto in mente questo metodo, un mio amico Tedd l'ha trovato e ha elaborato il modo di applicare il riflesso all'italità. – mylock

+0

Questo funziona per me al 4.2 – AlBeebe

+0

Ehi @AlBeebe Il link qui sopra non funziona, puoi condividere i file di aiuto e la fonte per la gestione della telefonia? Mi aiuterà molto. –

3

Ho una soluzione. Cambio:

String serviceManagerName = "android.os.IServiceManager"; 

a:

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

Questo funziona per me !! :) –

Problemi correlati