2010-01-04 4 views
20

J'essaie d'utiliser la réflexion pour accéder à certaines fonctionnalités non publiées de l'API de téléphonie. Actuellement j'ai du mal à instancier un objet serviceManager qui est nécessaire pour obtenir le service "téléphone" comme un classeur que je peux ensuite utiliser pour instancier un objet de téléphonie qui est nécessaire pour passer un appel, terminer un appel, etc ...Réflexion pour accéder aux fonctionnalités de téléphonie avancées

actuellement quand je fais l'appel

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

retourne un NullPointerException. Je crois que cela a à voir avec la création d'un nouveau liant au lieu d'envoyer le classeur approprié (que je ne suis pas sûr dont l'un est approprié)

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

« Actuellement, je ne parviens pas à instancier un objet ServiceManager » est la seule information que vous donnez l'erreur ou un problème. Vous nous avez donné le code. Maintenant, dites-nous ce qu'il fait ou ne fait pas, ce qui est inattendu, et comment vous savez que cela ne fonctionne pas correctement. –

Répondre

5

En procédant comme suit

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

vous obtiendrez un Instance ServiceManagerProxy, puis le prochain problème se produit sur la ligne

telephonyCall.invoke(telephonyObject, number); 
1

Oui, c'est possible! J'ai passé 24 heures à enquêter et à découvrir, et j'ai trouvé une solution "fraîche"!

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

Tous ceux qui veulent développer leur logiciel de contrôle d'appel visite ce point de départ:
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

Il y a un projet. et il y a des commentaires importants (et des crédits). En bref: copier le fichier aidl, ajouter des autorisations pour manifester, copier-coller la source pour la gestion de la téléphonie.

Quelques informations supplémentaires pour vous: Vous ne pouvez envoyer des commandes AT que si vous êtes rooté. Ensuite, vous pouvez arrêter le processus système et envoyer des commandes, mais vous aurez besoin d'un redémarrage pour permettre à votre téléphone de recevoir et d'envoyer des appels.

Je suis très heureux! Maintenant, mon Shake2MuteCall recevra une mise à jour!

+2

salut. Je suis le développeur de Mylock. Je voulais juste vous informer que cela ne fonctionne plus sur 2.3 et nous cherchons comment nous pouvons accomplir le même résultat en supposant que la permission de super utilisateur root. Je n'ai pas trouvé cette méthode, un de mes amis Tedd est tombé dessus et a trouvé le moyen d'appliquer la réflexion à l'itéléphonie. – mylock

+0

Cela fonctionne pour moi sur 4.2 – AlBeebe

+0

Hey @AlBeebe Le lien ci-dessus ne fonctionne pas maintenant, Pouvez-vous s'il vous plaît partager les fichiers et la source d'aide à la gestion de la téléphonie? Cela m'aidera beaucoup. –

3

J'ai une solution. Changement:

String serviceManagerName = "android.os.IServiceManager"; 

à:

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

Cela fonctionne pour moi !! :) –

Questions connexes