sendBroadcastAsUser——Calling a method in the system process

Posted skiwnchhw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sendBroadcastAsUser——Calling a method in the system process相关的知识,希望对你有一定的参考价值。

4.2中android加入了多用户 

改换这几种调用方式 

public void startActivityAsUser(Intent intent, UserHandle user); 
public void sendBroadcastAsUser(Intent intent, UserHandle user); 
public ComponentName startServiceAsUser(Intent service, UserHandle user); 
public boolean stopServiceAsUser(Intent service, UserHandle user); 

UserHandle.ALL 
UserHandle.CURRENT 
UserHandle.CURRENT_OR_SELF 

UserHandle.OWNER

延伸阅读

先看下面代码

 

private void broadcastCallStateChanged(int state, String incomingNumber) {
    //... ...省略
    //TelephonyManager.ACTION_PHONE_STATE_CHANGED 即"android.intent.action.PHONE_STATE"
    Intent intent = new Intent(TelephonyManager.ACTION_PHONE_STATE_CHANGED);

    //PhoneConstants.STATE_KEY 即字符串"state"
    intent.putExtra(PhoneConstants.STATE_KEY, DefaultPhoneNotifier.convertCallState(state).toString());

    //如果incomingNumber不为空则添加到intent的Extra中,对应的key为"incoming_number"
    if (!TextUtils.isEmpty(incomingNumber)) {
        intent.putExtra(TelephonyManager.EXTRA_INCOMING_NUMBER, incomingNumber);
    }
    
    //MTK Dual SIM support,对应key为"simId"
    if (FeatureOption.MTK_GEMINI_SUPPORT) {
        intent.putExtra(PhoneConstants.GEMINI_SIM_ID_KEY, mySimId);
    }

    //发送广播,接收者为所有人,接收者需要有READ_PHONE_STATE权限
    mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
            android.Manifest.permission.READ_PHONE_STATE);
}

 

在Android 4.0之前,并非使用sendBroadcastAsUser,而是使用sendBroadcast(intent, android.Manifest.permission.READ_PHONE_STATE)发起广播通知,两者相比,前者多了一个UserHandle.ALL的参数,该参数系Google在Android中添加用于区分用户组的标志。

        在Android 4.2 之后Android引入多用户支持,目前Android平台多用户仅支持平板设备。虽然在Android 4.2 中我们已经可以看到Android多用户支持的影子,但直到Android 4.4 google还是没有正式推出。因为Android 平板和手机共用一套代码,因此这里简单的提一下Android 4.4中多用户所支持的用户组。

        Android 4.4 用户分为:UserHandle.ALL、UserHandle.CURRENT、UserHandle.CURRENT_OR_SELF、UserHandle.OWNER四种类型,每种类型的handle不同。详细描述如下:

[java] view plaincopy
 
  1. /** A user handle to indicate all users on the device */  
  2. //设备上所有用户均可接收到广播  
  3. // handle = -1  
  4. UserHandle.ALL  
  5.   
  6. /** A user handle to indicate the current user of the device */  
  7. //设备上当前用户可接收到广播  
  8. // handle = -2  
  9. UserHandle.CURRENT  
  10.   
  11. /** A user handle to indicate that we would like to send to the current 
  12.  *  user, but if this is calling from a user process then we will send it 
  13.  *  to the caller‘s user instead of failing wiht a security exception */  
  14. //handle = -3  
  15. //设备上当前用户或者该应用所属用户可接收到广播  
  16. UserHandle.CURRENT_OR_SELF  
  17.   
  18. /** A user handle to indicate the primary/owner user of the device */  
  19. // handle = 0  
  20. //设备所有者可接收到广播  
  21. UserHandle.OWNER  

这里的广播范围可以排序为:UserHandle.ALL > UserHandle.OWNER > UserHandle.CURRENT_OR_SELF > UserHandle.CURRENT。注意UserHandle.ALL包含了所有用户,而OWNER仅仅是设备持有者(注意guest用户)。

阅读更多:

http://blog.csdn.net/yihongyuelan/article/details/32324335

Android 4.4 Kitkat Phone工作流程浅析(九)__状态通知流程分析

 

概要

 

         当手机Modem状态改变后会将状态变化信息通知到上层,通过《Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析》和《Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程》的分析,我们知道了Phone状态的类型,以及这些状态的上报流程,而本文主要分析Phone状态改变之后是如何通知到三方应用的。

         Phone状态对于三方应用来讲主要包括:TelephonyManager.CALL_STATE_IDLE、TelephonyManager.CALL_STATE_RINGING、TelephonyManager.CALL_STATE_OFFHOOK三种。对于三方应用,通常使用两种方法来获知Phone状态的改变即:

①监听Phone状态改变广播;

②使用PhoneStateListener监听Phone状态。PhoneStateListener不仅能监听Phone状态改变,同时还能监听数据连接状态、Phone服务状态等状态改变信息;

两种方法所对应的相关代码如下:

 

[java] view plaincopy
 
  1. //1.注册广播监听Phone状态改变  
  2. //1.1 动态注册广播  
  3. public class MainActivity extends Activity {  
  4.     private PhoneStateChangedReceiver mPhoneStateChangedReceiver;     
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.   
  10.         //Dynamic register the broadcast  
  11.         IntentFilter filter = new IntentFilter();  
  12.   
  13.         //"android.intent.action.PHONE_STATE"  
  14.         filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);  
  15.   
  16.         //"android.intent.action.NEW_OUTGOING_CALL"  
  17.         filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);  
  18.   
  19.         mPhoneStateChangedReceiver = new PhoneStateChangedReceiver();  
  20.         registerReceiver(mPhoneStateChangedReceiver, filter);  
  21.     }  
  22.   
  23.     @Override  
  24.     protected void onDestroy() {  
  25.         //unregister the broadcast when activity destroyed  
  26.         unregisterReceiver(mPhoneStateChangedReceiver);  
  27.         super.onDestroy();  
  28.     }  
  29.   
  30.     //内部类广播  
  31.     public static class PhoneStateChangedReceiver extends BroadcastReceiver {  
  32.         @Override  
  33.         public void onReceive(Context context, Intent intent) {  
  34.   
  35.              //Action is "android.intent.action.PHONE_STATE"  
  36.              //or "android.intent.action.NEW_OUTGOING_CALL"  
  37.              String action = intent.getAction();  
  38.              Log.i("Seven","action is "+action);  
  39.   
  40.              if (Intent.ACTION_NEW_OUTGOING_CALL.equals(action)) {  
  41.              //"android.intent.extra.PHONE_NUMBER"  
  42.              String outgoingNum = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);  
  43.              Log.i("Seven""It‘s outgoing call. Number is:"+outgoingNum);  
  44.              return;  
  45.              }  
  46.   
  47.              //State is RINGING/OFFHOOK/IDLE  
  48.              String state = intent.getStringExtra("state");  
  49.   
  50.              //Only state is Ringing can get the incoming_number  
  51.              String incomingNum = intent.getStringExtra("incoming_number");  
  52.   
  53.              //MTK add for dual SIM support  
  54.              String simId = intent.getStringExtra("simId");  
  55.   
  56.              Log.i("Seven""state is "+state);  
  57.              Log.i("Seven""incomingNum is "+incomingNum);  
  58.              Log.i("Seven""simId is "+simId);  
  59.         }  
  60.     }  
  61. }  
  62.   
  63. //1.2 静态注册广播  
  64. //与动态注册的区别主要是需要在AndroidManifest.xml中添加<receiver>标签  
  65. <receiver   
  66.     android:name="com.seven.androidphonestatelistenerdemo.MainActivity$PhoneStateChangedReceiver" >  
  67.     <intent-filter>  
  68.         <action android:name="android.intent.action.PHONE_STATE" />  
  69.         <action android:name="android.intent.action.NEW_OUTGOING_CALL" />  
  70.     </intent-filter>  
  71. </receiver>  
  72.   
  73. //注意:无论是静态还是动态注册均需要添加相应的权限  
  74. <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
  75. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />  
  76.   
  77. 2.使用PhoneStateListener监听Phone状态改变  
  78. @Override  
  79. protected void onCreate(Bundle savedInstanceState) {  
  80.     super.onCreate(savedInstanceState);  
  81.     setContentView(R.layout.activity_main);  
  82.     //TELEPHONY_SERVICE equals "phone"  
  83.     TelephonyManager mTelephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
  84.     mTelephonyManager.listen(new PhoneStateListener(){  
  85.     @Override  
  86.     public void onCallStateChanged(int state, String incomingNumber) {  
  87.         switch (state) {  
  88.         case TelephonyManager.CALL_STATE_IDLE:  
  89.             Log.i("Seven","Call state is IDLE");  
  90.             break;  
  91.         case TelephonyManager.CALL_STATE_RINGING:  
  92.             Log.i("Seven","Call state is RINGING");  
  93.             break;  
  94.         case TelephonyManager.CALL_STATE_OFFHOOK:  
  95.             Log.i("Seven","Call state is OFFHOOK");  
  96.             break;  
  97.         default:  
  98.             break;  
  99.         }  
  100.         super.onCallStateChanged(state, incomingNumber);  
  101.     }  
  102.      }, PhoneStateListener.LISTEN_CALL_STATE);  
  103. }  

        以上两种方法均可实现监听Phone状态的改变,通过广播的方式可以监听"去电状态"和"Phone状态"改变,而如果通过PhoneStateListener则只能监听Phone状态改变。这里我们先以MT流程为例,从代码的执行流程上分析Phone状态改变后是如何通知到三方应用的,后文也会顺带分析去电广播的发起流程。

        通过前面文章的分析,我们知道Phone状态的改变是Modem发起的,之后通过framework、TeleService并最终通过InCallUI表现到界面上,整个流程如图1:

技术分享图片
图 1 MT调用流程

        通过图1可以知道,所有的状态都是从Modem发起并经过Telephony Framework处理之后再向上传递的,也是正是在Telephony Framework中,系统将Phone相关状态告知给了三方应用。

状态通知发起流程

        当Phone状态改变之后,RILJ将相关信息反馈到GsmCallTracker的handleCallProgressInfo()方法中 (AOSP是handlePollCalls) 进行相关的处理。在该方法中会进行Phone状态的转换,在上一篇文章《Android 4.4 Kitkat Phone工作流程浅析(八)__Phone状态分析》中我们有详细分析,这里不再详细解释。

        在handleCallProgressInfo()的updatePhoneState()方法中进行Call.State(Internal)和PhoneConstants.State转换时,有如下代码:

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://www.cnblogs.com/captainbed
















以上是关于sendBroadcastAsUser——Calling a method in the system process的主要内容,如果未能解决你的问题,请参考以下文章

R语言do.call函数和call函数实战

面试必备!JS:call详解以及自己手写call

面试必备!JS:call详解以及自己手写call

面试必备!JS:call详解以及自己手写call

汇编语言中的call是啥意思

汇编call的问题