Pourquoi ITelephony.aidl œuvres?

j'ai vu certains messages SO qui ont discuté sur la façon de mettre fin à un appel téléphonique programmtiquement, par exemple, celui-ci . Oui, les gens se concentrent sur le résultat mais personne n'explique vraiment la raison pourquoi ça marche?

j'ai essayé le code, il fonctionne bien. Mais j'aimerais en savoir plus sur ce qui se passe en dessous. Pourquoi en créant L'Itéléphonie .aidl , l'androïde caché interne ITelephony l'interface est exposée dans notre projet? Comment a-t-on créé ITelephony.aidl & le java généré automatiquement (/gen/ITelephony.java) lien vers interface d'android ITelephony ? Est-ce uniquement à cause de la correspondance des noms (Nom du paquet et nom du fichier aidl)?

TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);

Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);

//Why does the android internal ITelephony interface is exposed after created the ITelephony.aidl?
com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService.endCall(); 
27
demandé sur Community 2013-09-24 12:55:27

2 réponses

en fait, ajouter ITelephony.aidl à votre projet n'est pas nécessaire, c'est juste une commodité. Vous pourriez tout aussi bien le faire de cette façon:

TelephonyManager tm = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()

sous les couvertures ceci tous les travaux utilisant Java reflection pour accéder aux méthodes privées (c'est-à-dire non publiquement documentées). Vous pouvez trouver quelles méthodes sont là, et ce qu'elles font, en lisant le code source D'Android open-source (C.-à-d. publiquement disponible). Une fois que vous savez ce qui est là et ce qu'il fait, vous pouvez utiliser réflexion pour y arriver, même si elle est"cachée".

la classe TelephonyManager est implémentée en utilisant un service à distance. Si vous souhaitez demander le TelephonyManager pour faire quelque chose pour vous, vous appelez une méthode sur le TelephonyManager (qui est la partie publiquement documentée) et à l'interne il fait un appel au service de téléphonie à distance pour faire réellement le travail. Ceci est fait en utilisant AIDL, qui est une sorte d ' "appel de procédure à distance". Le service à distance peut faire des choses qui ne sont pas exposées publiquement via la classe TelephonyManager . Ce que vous faites ici est d'obtenir le côté client de l'interface "remote procedure call" en utilisant getITelephony() . Ceci renvoie un objet de type ITelephony . Cette classe a une méthode appelée endCall() . Une fois que nous avons l'objet de type ITelephony , nous pouvons obtenir son objet de Classe et ensuite obtenir la méthode endCall() de la Classe. Une fois que nous avons la méthode, nous la rendre accessible et que l'appeler. La méthode endCall() est du côté client de la télécommande appel de procédure. La méthode envoie maintenant un message au service telephony manager (qui tourne sur un serveur distant) et lui demande de mettre fin à l'appel.

étant donné que le code source du ITelephony.aidl est disponible au public, vous pouvez mettre le code source dans votre projet et votre IDE générera ITelephony.java (qui contient le côté client de l'appel de procédure à distance) à partir de ITelephony.aidl . Vous pouvez alors juste import que et votre IDE sera maintenant au courant de la ITelephony classe et ses méthodes. Cela permet au compilateur de générer le byte-code correct lors de la compilation de votre projet. Lorsque vous exécutez ce code sur un appareil Android, vous appelez pour Android-cadre pour obtenir le ITelephony objet, puis vous jeter aux com.android.internal.telephony.ITelephony . Dès lors, Vous pouvez accéder aux méthodes et aux champs de l'objet en utilisant le ITelephony.java généré aussi longtemps que le code Java que vous avez pour ITelephony correspond à la définition de classe réelle de l'objet retourné ITelephony . Si les définitions de classe ne correspondent pas, la VM va lancer une exception appropriée.

j'espère que cela répondra à votre question. Je n'étais pas vraiment sûr de ce que tu savais déjà à propos de ça, donc peut-être que j'ai mentionné des choses que tu sais déjà. Si oui, désolé à ce sujet. Si ce n'est pas clair, veuillez indiquer exactement ce que vous ne comprenez pas.

75
répondu David Wasser 2013-09-24 18:21:04

en fait, en ajoutant ITelephony.aidl à votre projet n'est pas nécessaire, c'est juste une commodité. Vous pourriez tout aussi bien le faire de cette façon: réponse correcte

0
répondu venkatkural 2018-09-24 06:58:13