In fact, adding ITelephony.aidl to your project is not required, it's just a convenience. You could also do it like this:
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);
Under covers, everything works using Java reflection to access private (i.e., not publicly documented) methods. You can find out what methods exist and what they do by reading open source (i.e.: public) source code. When you find out what is there and what it is doing, you can use the reflection to get to it, even if it is "hidden."
The TelephonyManager class is implemented using a remote service. If you want to ask TelephonyManager to do something for you, you call the method on TelephonyManager (which is the publicly documented part) and internally it makes a call to the telephony service to actually do the job. This is done using AIDL, which is a kind of "remote procedure call". A remote service can perform actions that were not published publicly through the TelephonyManager class. What you are doing here is to get the βremote procedure callβ client interface using getITelephony() . This returns an object of type ITelephony . This class has a method called endCall() . When we have an object of type ITelephony , we can get its class object, and then get the endCall() method from the class. Once we get this method, we will make it available and we will not call it. The endCall() method is on the client side of the remote procedure call. Now the method sends a message to the telephony manager service (which runs on the remote server) and asks her to end the call.
Since the source code for ITelephony.aidl is public, you can put the source code in your project, and your IDE will generate ITelephony.java (which contains the client part of the remote procedure call) from ITelephony.aidl , then you can simply import and your IDE now learns about the ITelephony class and its methods. This allows the compiler to generate the correct bytecode when compiling your project. When you run this code on an Android device, you call it in the Android framework to get the ITelephony object, and then you added it to com.android.internal.telephony.ITelephony . From now on, you can access the methods and fields of the object using the generated ITelephony.java if the Java code that you have for ITelephony matches the actual definition of the class of the returned ITelephony object. If the class definitions do not match, the VM will throw an appropriate exception.
Hope this answers your question. I was not exactly sure how much you already knew about this, so maybe I mentioned what you already know. If so, sorry. If this is not clear, indicate what exactly you do not understand.
David Wasser Sep 24 '13 at 18:21 2013-09-24 18:21
source share