• BroadcastReceiver 用于接收广播


     BroadcastReceiver 用于异步接收广播Intent。主要有两大类,用于接收广播的:

    • 正常广播 Normal broadcasts(用 Context.sendBroadcast()发送)是完全异步的。它们都运行在一个未定义的顺序,通常是在同一时间。这样会更有效,但意味着receiver不能包含所要使用的结果或中止的API。  
    • 有序广播 Ordered broadcasts(用 Context.sendOrderedBroadcast()发送)每次被发送到一个receiver。所谓有序,就是每个receiver执行后可以传播到下一个receiver,也可以完全中止传播——不传播给其他receiver。 而receiver运行的顺序可以通过matched intent-filter 里面的android:priority来控制,当priority优先级相同的时候,Receiver以任意的顺序运行。
     
        要注意的是,即使是Normal broadcasts,系统在某些情况下可能会恢复到一次传播给一个receiver。 特别是receiver可能需要创建一个进程,为了避免系统超载,只能一次运行一个receiver。
     
        Broadcast Receiver 并没有提供可视化的界面来显示广播信息。可以使用Notification和Notification Manager来实现可视化的信息的界面,显示广播信息的内容,图标及震动信息。
     
    生命周期
        一个BroadcastReceiver 对象只有在被调用onReceive(Context, Intent)的才有效的,当从该函数返回后,该对象就无效的了,结束生命周期。
        因此从这个特征可以看出,在所调用的onReceive(Context, Intent)函数里,不能有过于耗时的操作,不能使用线程来执行。对于耗时的操作,请start service来完成。因为当得到其他异步操作所返回的结果时,BroadcastReceiver 可能已经无效了。
     
    发送广播
        事件的广播比较简单,构建Intent对象,可调用sendBroadcast(Intent)方法将广播发出。另外还有sendOrderedBroadcast(),sendStickyBroadcast()等方法,请查阅API Doc。
        1.new Intent with action name 
            Intent intent = new Intent(String action);
          或者 只是new Intent, 然后
            intent.setAction(String action);
     
        2.set data等准备好了后,in activity,
            sendBroadcast(Intent); // 发送广播
     
    接收广播
        通过定义一个继承BroadcastReceiver类来实现,继承该类后覆盖其onReceiver方法,并在该方法中响应事件。
    1. public class SMSReceiver extends BroadcastReceiver {   
    2.   
    3.         @Override   
    4.         public void onReceive(Context context, Intent intent) {   
    5.                 // get data from SMS intent    
    6.                 Bundle bundle = intent.getExtras();   
    7.                 if (bundle != null){   
    8.                         // get message by "pdus"    
    9.                         Object[] objArray = (Object[]) bundle.get("pdus");   
    10.   
    11.                         // rebuild SMS    
    12.                         SmsMessage[] messages = new SmsMessage[objArray.length];   
    13.                         for (int i=0; i < objArray.length; i++){   
    14.                                 messages[i] = SmsMessage.createFromPdu((byte[])objArray[i]);   
    15.   
    16.                                 StringBuilder str = new StringBuilder("from: ");   
    17.                                 str.append(messages[i].getDisplayOriginatingAddress());   
    18.                                 str.append("\nmessage:\n");   
    19.                                 str.append(messages[i].getDisplayMessageBody());   
    20.   
    21.                                 Toast.makeText(context, str.toString(), Toast.LENGTH_LONG)   
    22.                                                 .show();   
    23.                         }   
    24.                 }   
    25.         }   
    26. }  
    public class SMSReceiver extends BroadcastReceiver { 
    
            @Override 
            public void onReceive(Context context, Intent intent) { 
                    // get data from SMS intent 
                    Bundle bundle = intent.getExtras(); 
                    if (bundle != null){ 
                            // get message by "pdus" 
                            Object[] objArray = (Object[]) bundle.get("pdus"); 
    
                            // rebuild SMS 
                            SmsMessage[] messages = new SmsMessage[objArray.length]; 
                            for (int i=0; i < objArray.length; i++){ 
                                    messages[i] = SmsMessage.createFromPdu((byte[])objArray[i]); 
    
                                    StringBuilder str = new StringBuilder("from: "); 
                                    str.append(messages[i].getDisplayOriginatingAddress()); 
                                    str.append("\nmessage:\n"); 
                                    str.append(messages[i].getDisplayMessageBody()); 
    
                                    Toast.makeText(context, str.toString(), Toast.LENGTH_LONG) 
                                                    .show(); 
                            } 
                    } 
            } 
    }
    注册Receiver
       注册有两种方式:
       1. 静态方式,在AndroidManifest.xml的application里面定义receiver并设置要接收的action。
    1. <receiver android:name=".SMSReceiver">   
    2.         <intent-filter>   
    3.                 <action android:name="android.provider.Telephony.SMS_RECEIVED" />   
    4.         </intent-filter>   
    5. </receiver>  
    <receiver android:name=".SMSReceiver"> 
            <intent-filter> 
                    <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
            </intent-filter> 
    </receiver>

     2. 动态方式, 在activity里面调用函数来注册,和静态的内容差不多。一个形参是receiver,另一个是IntentFilter,其中里面是要接收的action。
    1. public class HelloDemo extends Activity {      
    2.         private BroadcastReceiver receiver;      
    3.   
    4.         @Override   
    5.         protected void onStart() {   
    6.                 super.onStart();   
    7.   
    8.                 receiver = new CallReceiver();   
    9.                 registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE"));   
    10.         }   
    11.   
    12.         @Override   
    13.         protected void onStop() {   
    14.                 unregisterReceiver(receiver);   
    15.                 super.onStop();   
    16.         }   
    17. }  
    public class HelloDemo extends Activity {    
            private BroadcastReceiver receiver;    
    
            @Override 
            protected void onStart() { 
                    super.onStart(); 
    
                    receiver = new CallReceiver(); 
                    registerReceiver(receiver, new IntentFilter("android.intent.action.PHONE_STATE")); 
            } 
    
            @Override 
            protected void onStop() { 
                    unregisterReceiver(receiver); 
                    super.onStop(); 
            } 
    }
       一个receiver可以接收多个action的,即可以有多个intent-filter,需要在onReceive里面对intent.getAction(action name)进行判断。
     
        个人推荐使用静态注册方式,由系统来管理receiver,而且程序里的所有receiver,可以在xml里面一目了然。而动态注册方式,隐藏在代码中,比较难发现。
        而且动态注册,需要特别注意的是,在退出程序前要记得调用Context.unregisterReceiver()方法。一般在activity的onStart()里面进行注册, onStop()里面进行注销。官方提醒,如果在Activity.onResume()里面注册了,就必须在Activity.onPause()注销。
     
    Permission权限
      要接收某些action,需要在AndroidManifest.xml里面添加相应的permission。例如接收SMS:
    1. uses-permission android:name="android.permission.RECEIVE_SMS" />  
    uses-permission android:name="android.permission.RECEIVE_SMS" />

    下面给出动态注册的接收来电的广播处理的CallReceiver的代码:
       一种方式是直接读取intent.getStringExtra("incoming_number")来获取来电号码:
    1. public class CallReceiver extends BroadcastReceiver {   
    2.   
    3.         @Override   
    4.         public void onReceive(Context context, Intent intent) {   
    5.                 TelephonyManager teleManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);   
    6.                    
    7.                 switch(teleManager.getCallState()){   
    8.                 case TelephonyManager.CALL_STATE_RINGING: //响铃    
    9.                         Toast.makeText(context, "Ringing: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();   
    10.                         break;   
    11.                 case TelephonyManager.CALL_STATE_OFFHOOK: //接听    
    12.                         Toast.makeText(context, "OffHook: " + intent.getStringExtra("incoming_number"), Toast.LENGTH_LONG).show();   
    13.                         break;   
    14.                 case TelephonyManager.CALL_STATE_IDLE: //挂断    
    15.                         Toast.makeText(m_context, "Idle: " + incomingNumber, Toast.LENGTH_LONG).show();   
    16.                         break;   
    17.                 }   
    18.         }   
    19. }  
  • 相关阅读:
    win10自带邮箱应用无法查看qq邮箱应用解决办法
    Ubuntu紫色背景颜色代码
    VMware中对Linux虚拟机的网络配置静态IP的配置
    CentOS 7在VMware 12中共享文件看不见的问题?
    C++中让人忽视的左值和右值
    C++ allocator类学习理解
    C++11新特性 -----> 右值引用 &&
    重新认识new
    关于C++中nothrow的某某某
    stopPropagation, preventDefault 和 return false 的区别
  • 原文地址:https://www.cnblogs.com/ggzjj/p/2857288.html
Copyright © 2020-2023  润新知