Because the system API does not provide us with the call management service interface itelephony, We have to obtain this service interface through abnormal means. (through itelephony in the source code. aidl helps us generate telephone management service interfaces, so that we can use the system operation phone function ).
For example,> end a call:
1> copy the itelephony. aidl file used in the package structure to your project.
(Because Android. telephony. neighboringcellinfo. aidl is introduced, it is also introduced to your project)
To stop a call, you must have the <uses-Permission Android: Name = "android. Permission. call_phone"/> permission
Try { // Obtain the getservice method object of the system service through reflection. Method method = Class.Forname("Android. OS. servicemanager ") . Getmethod ("getservice", String. Class ); // Execute this method to obtain an ibinder object Ibinder binder = (ibinder) method. Invoke (null, new object [] {Telephony_service}); // Convert to a specific service class (itelephony) interface object Itelephony telephony = itelephony. stub.Asinterface(Binder ); // End the call Telephony. endcall (); // From the top, it is done through reflection. The following is a normal practice> follow the steps below to do it // IbinderBindr= Servicemanager. getservice (telephony_service ); // Itelephony telephony2 = itelephony. stub. asinterface (binder ); // Telephony2.endcall (); } Catch (exception e ){ E. printstacktrace (); } |
Let's take a look at how it works to operate the telephone management function.
First, we need to know that all service classes are interacting with the Service Manager. the Service Manager incorporates all services into its management scope. the underlying services and tools in the system framework interact with the manager.
I used the servicemanager system framework to provide the service manager to get the binder object of the itelephony service.
All services in the servicemanager system framework are running later. To get these services, you must use getservice to get them.
Public static ibinder getservice (string name) {// get the service's ibinder object
Try {
Ibinder service =Scache. Get (name); // first find the ibinder of this service from the cache
If (service! = NULL ){
Return service;
} Else {// if it is null, use the Service Manager interface to implement the getservice method of the class to get the service you want.
ReturnGetiservicemanager(). Getservice (name );
}
} Catch (RemoteException e ){
Log.E(Tag, "Error in getservice", e );
}
Return NULL;
}
Public static void addservice (stringname, ibinder Service) {// append a service to the Service Manager
Public static ibinder checkservice (string name )..... // Retrieve an existing service
Public static string [] listservices () throwsremoteexception // list the existing services
Next let's take a look at the class contextimplextends context class
@ Override
Public object getsystemservice (string name ){
If (Window_service. Equals (name )){
Returnwindowmanagerimpl.Getdefault();
} Else if (Activity_service. Equals (name )){
Returngetactivitymanager ();
} Else if (Telephony_service. Equals (name )){
Return gettelephonymanager ();
..... Below
Private telephonymanager gettelephonymanager (){
Synchronized (msync ){
If (mtelephonymanager = NULL ){
Mtelephonymanager = new telephonymanager (getoutercontext ());
}
}
Return mtelephonymanager;
}
The following is the construction method of the telephonymanager class.
/** @ Hide */
Public telephonymanager (context ){
Mcontext = context;
Mregistry = itelephonyregistry. stub.Asinterface(Servicemanager.Getservice(
"Telephony. Registry "));
}
Privateiphonesubinfo getsubscriberinfo (){
// Get it each time because that process crashes a lot
Returniphonesubinfo. stub.Asinterface(Servicemanager.Getservice("Iphonesubinfo "));
}
Private itelephony getitelephony (){
Return itelephony. stub.Asinterface(Servicemanager.Getservice(Context.Telephony_service));
}
Public void listen (phonestatelistener listener, int events ){
String pkgfordebug = mcontext! = NULL? Mcontext. getpackagename (): "<Unknown> ";
Try {
Boolean policynow = (getitelephony ()! = NULL );
Mregistry. Listen (pkgfordebug, listener. Callback, events, policynow );
} Catch (RemoteException ex ){
// System process dead
} Catch (nullpointerexception ex ){
// System process dead
}
}
In the telephonymanager class, only the service manager is used to obtain different service providers and provide some basic phone information and registration callback for phone status listening. This function is not provided for phone suspension.
How does the system end the call ...?
The method for hanging up the phone was not found at last, but it was found in the itelephony. aidl File
/**
* End call or go to the home screen
*
* @ Return whether it hung up
*/
Booleanendcall ();
We know that the aidl file is the android Interface Description Language. The process in the Android system cannot share memory. Therefore, we need to provide some mechanisms for data communication between different processes. to allow other applications to access the services provided by this application, the android system uses Remote Procedure Call (RPC. this cross-process access service is called the aidl (Android Interface Definition Language) service.
This means that we can use this aidl to access the endcall function provided by the itelephony interface.
After loading, use itelephony telephony2 = itelephony. stub. asinterface (binder); converts the binder object to the proxy object of the corresponding server, and then ends the call through the proxy of the itelephony service class.