Phone Status Monitoring Mechanism

Source: Internet
Author: User
1. Listen to the phone status

There are two ways to listen to the phone status on a mobile phone:

1. register and receive broadcasts
Androidmenifest. XML: <er Android: Name = "calllistener"> <intent-filter> <action Android: Name = "android. intent. action. phone_state "/> <action Android: Name =" android. intent. action. new_outgoing_call "/> </intent-filter> </Cycler> permission <uses-Permission Android: Name =" android. permission. read_phone_state "/> broadcast: public class calllistener extends broadcastreceiver {@ override public void onreceive (context, intent ){}}
2. Register phonestatelistener
// Obtain the corresponding system service telephonymanager TM = (telephonymanager) getsystemservice (context. telephony_service );
// Create listenermyphonecalllistener myphonecalllistener = new myphonecalllistener (); // register the listener to set the listener's state TM. listen (myphonecalllistener, phonestatelistener. listen_call_state); // implement the phonestatelistener listener and implement the corresponding method public class myphonecalllistener extends phonestatelistener {@ override public void oncallstatechanged (INT state, string incomingnumber) {Switch (state) {// call Status case telephonymanager. call_state_offhook: break; // call Status case telephonymanager. call_state_ringing: break; // case telephonymanager in idle state. call_state_idle: break;} super. oncallstatechanged (State, incomingnumber );}}

Telephonymanager is used here, so if the registration process is implemented and what is the triggering process.

The core of framework layer telephony processing is the RIL class. Various state changes at the network layer are passed to the listener.

The Application Layer needs to listen to the phone state in many places. The following describes how this process is implemented.

Class inheritance structure:

    

 

2. Implementation Mechanism of listening to phone status

 

 

Phone state listen sequence chart:

  

1 phonenotifier and phone

The Telephony layer of the Framework is initialized in phonefactory:

Public static void makedefaphone phone (context) {sphonenotifier = new defaultphonenotifier (); // create a commandsinterface instance scommandsinterface = new RIL (context, networkmode, cdmasubphone ); // create the phone instance and the proxy object proxyphone sproxyphone = new phoneproxy (New gsmphone (context, scommandsinterface, sphonenotifier);} public gsmphone (context, commandsinterface CI, phonenotifier notifier, boolean unittestmode) {// notifier super (notifier, context, CI, unittestmode );}

When the phone parent class is created, the phonenotifier object is passed to the phonebase class:

Protected phonebase (phonenotifier notifier, context, commandsinterface CI, Boolean unittestmode) {// Save the notifier object reference this. mnotifier = notifier; this. mcontext = context; mlogoff = logoff. mylooper (); MCM = CI; // phonebase is a handler registered to listen for MCM. setoncallring (this, event_call_ring, null );}

Here we can see that gsmphone stores a reference of a phonenotifier object, and phonebase is a handler,

However, it is not registered to the mcallstateregistrants table of RIL to listen for phone status changes, nor in phonebase.

We can see that mnotifier is used to trigger a notification in the phonestatelistener. listen_call_state state.

In fact, the Code shows that the status of the phone is not directly controlled and determined by rIL, but is similar to gsmcalltracker for various status listening to make a comprehensive judgment of the notification.

Let's take a look at the inheritance structure of this class:

    

 

This class is also quite complex. Let's look at this function first:

Gsmcalltracker:

Private void updatephonestate () {Phone. State oldstate = State; // you can check whether the status has changed ...... If (State! = Oldstate) {// gsmphone. yyphonestatechanged ();}}

Gsmphone:

Void policyphonestatechanged () {// This is the phonenotifier -- defaultphonenotifier mnotifier. policyphonestate (this) passed during the creation of the gsmphone );} 

From here, we will go to the defaultphonenotifier derived class of phonenotifier, and notify its registered listener of status changes.

Defaultphonenotifier:

Public void policyphonestate (Phone sender) {call ringingcall = sender. getringingcall (); string incomingnumber = ""; if (ringingcall! = NULL & ringingcall. getearliestconnection ()! = NULL) {incomingnumber = ringingcall. getearliestconnection (). getaddress ();} Try {// Remote Call to notify call state mregistry.Notifycallstate(Convertcallstate (sender. getstate (), incomingnumber);} catch (RemoteException ex) {// system process is dead }}

Listener is registered for status listening in telephonyregistry.

2 telephonyregistry and phonestatelistener

Let's take a look at the class inheritance structure related to phonenotifier:

Servicemanager. addservice ("telephony. Registry", new telephonyregistry (context ));

The core class here is telephonyregistry, inherited from itelephonyregistry. stub, which runs in systemserver,

As a framework layer service, you can use the binder process to communicate with each other and provide status registration listening and status change notifications.

In the above method of listening to the phone status, it is implemented by inheriting the phonestatelistener; the inheritance structure contains an iphonestatelistener, which is a class automatically generated by the aidl file.

The aidl file automatically generates the interfaces and classes required for inter-process communication based on the established framework. The automatically generated class inheritance structure relationships are as follows:

    

Let's take a look at the class phonestatelistener to be rewritten for listening:

    

Phonestatelistener holds the iphonestatelistener. Stub object callback, because we want to implement the process of listening to the phone status and

The process that notifies the phone status change is not in the same process. To implement cross-process communication, binder must be used.

  Therefore, the listener registered in the telephonyregistry service is a binder object of iPhone statelistener. stub.

3 phone status monitoring registration

Registration process:

// Obtain the corresponding system service telephonymanager TM = (telephonymanager) getsystemservice (context. telephony_service); // create listener myphonecalllistener = new myphonecalllistener (); // register the listener to set the listener state TM. listen (myphonecalllistener, phonestatelistener. listen_call_state );

Obtain the contextimpl. Java that is running in the current process.

Registerservice (telephony_service, new servicefetcher () {public object createservice (contextimpl CTX) {return New telephonymanager (CTX. getoutercontext () ;}}); // telephonymanager remote proxy service object telephonyregistry: Public void listen (phonestatelistener listener, int events) {// register the listening object sregistry. listen (pkgfordebug, listener. callback, events, policynow );}

 

Telephonymanager remote proxy service object telephonyregistry:

    

 

The registration object is completed in the telephonyregistry service:

public void listen(String pkgForDebug, IPhoneStateListener callback, int events,            boolean notifyNow) {    synchronized (mRecords) {  // register  Record r = null;  find_and_add:   {    IBinder b = callback.asBinder();    final int N = mRecords.size();    for (int i = 0; i < N; i++) {        r = mRecords.get(i);        if (b == r.binder) {            break find_and_add;        }}  // ArrayList< Record >    r = new Record();    r.binder = b;    r.callback = callback;    r.pkgForDebug = pkgForDebug;    mRecords.add(r);      }}
4. Trigger Notification status changes
Public void policyphonestate (Phone sender) {// remote object telephonyregistry mregistry. policycallstate (convertcallstate (sender. getstate (), incomingnumber );}

TelephonyregistryNotification of service trigger status change:

Public void policycallstate (INT state, string incomingnumber) {synchronized (mrecords) {mcallstate = State; mcallincomingnumber = incomingnumber; For (record R: mrecords) {If (R. events & phonestatelistener. listen_call_state )! = 0) {// remote object callback R. Callback. oncallstatechanged (State, incomingnumber) ;}}// send broadcast broadcastcallstatechanged (State, incomingnumber );}

  Here we can see two ways to notify the phone status to change: interface callback and send Broadcast

Interface callback:Call back of the iphonestatelistener instance in phonestatelistener

Iphonestatelistener callback = new iphonestatelistener. stub () {public void oncallstatechanged (INT state, string incomingnumber) {// handler sends messages asynchronously to process messages. obtain (mhandler, listen_call_state, state, 0, incomingnumber ). sendtotarget () ;}} handler mhandler = new handler () {public void handlemessage (Message MSG) {Switch (MSG. what) {Case listen_call_state: // call the subclass myphonecalllistener interface phonestatelistener. this. oncallstatechanged (MSG. arg1, (string) MSG. OBJ); break ;}}}

Send broadcast:

Private void broadcastcallstatechanged (INT state, string incomingnumber) {// action: Android. intent. action. phone_state is the action intent = new intent (telephonymanager. action_phone_state_changed); intent. putextra (phone. state_key, defaultphonenotifier. convertcallstate (state ). tostring (); If (! Textutils. isempty (incomingnumber) {intent. putextra (telephonymanager. Protocol, incomingnumber);} mcontext. sendbroadcast (intent, Android. manifest. Permission. read_phone_state );}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.