Android广播接收者使用总结

匿名 (未验证) 提交于 2019-12-03 00:26:01

Ŀ¼

但是只有广播接收者可以使用java代码的方法来动态注册
BroadcastReceiver是用于接收广播的组件用于组件与组件之间进行通信,可以跨应用程序传递.如操作系统电池电量低会发送一个广播,这样我们的程序里面可以去监听这个广播,可以关 闭程序里面比较耗电的功能,提示用户注意保存进度什么的,还如其它安装新应用等,还有普通应 用程序,例如启动特定线程,文件下载完毕等。

广播的发送的一般应用场合:发送频率低的情况可以使用,数据量小的情况可以使用。

在onReceive方法内,我们可以获取随广播而来的Intent中的数据,这非常重要,就像无线电一样,包含很多有用的信息。 在创建完我们的BroadcastReceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址。没有注册广播地址的BroadcastReceiver就像一个缺少选台按钮的收音机,虽然功能俱备,但也无法收到电台的信号。所以创建类后就要对BroadcastReceiver进行注册。

public class MyBroadcastReceiver extends BroadcastReceiver {     @Override     public void onReceive(Context context, Intent intent) {       //对接收到的广播进行处理,intent里面包含数据     }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

静态注册是在AndroidManifest.xml文件中配置的

 <receiver android:name="com.hua.bcreceiver.MyBroadcastReceiver" > <intent-filter>   <action android:name="android.intent.action.MY_BROADCAST" />    <category android:name="android.intent.category.DEFAULT" />   </intent-filter>        </receiver>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6


所以,记得在 特定的地方执行解除注册操作。

MyBroadcastReceiver mbcr = new MyBroadcastReceiver(); IntentFilter filter = new IntentFilter();          filter.addAction(MyBroadcastReceiver.MY_BC_FIRST); registerReceiver(mbcr, filter);// 注册2)解除注册代码,一般在页面销毁时操作  @Override   protected void onDestroy() {          unregisterReceiver(mbcr);          mbcr = null;          super.onDestroy();      }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9


动作意图action,那么,就可以接收到系统发过来的广播信息,比如手机接收到短信,手机底层是会发送一条广播,查看手机系统内是否有符合条件的广播接收者,如果有就会向它发送信息。。。
静态注册的广播的程序运行一次后,以后能一直保持广播接收的状态,只要有对应的广播就能接收它的广播信息。而动态注册的广播需要程序在运行中才能接收广播。

在静态代码块中定义:

<intent-filter android:priority="999">
  • 1

使用动态java代码设置:
filter.setPriority(999);


那么priority的最大值是多少呢?



所有我们要知道优先级1000并不是最高的优先级,不信的话你可以试试看效果。



普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的 接收动作。

主要代码:
Intent intent = new Intent(“myBroadcastReceiver”);
intent.putExtra(“msg”, “这是MainActivity页面发送的广播―-》》”);
sendBroadcast(intent);

只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。可以在广播注册时使用intent-filter里面的android: priority=”xxx”去解决或在java代码中用setPriority(xxx)来设置。

主要代码:
Intent intent = new Intent(“myBroadcastReceiver”);
intent.putExtra(“msg”, “这是MainActivity页面发送的广播―-》》”);
sendOrderedBroadcast(intent,null);//如果是该自定义的广播接收者发送广播,第二个参数一般为null



无序广播是不可被截断的,每一个广播接收者都可以收到这个无序广播发送的广播信息;而无序广播时候根据优先级数的大小来判断谁先接收到广播信息,并且可以选择是否截断这个广播信息,如果在某个广播接收者截断信息,在它的优先级之下的广播接收者都接收不到广播信息。

有序广播才能拦截。

主要展示一下使用步骤和过程的代码!
这里的程序实在两个程序中的,但是也可以写在多个程序中,或单个程序中。程序的效果是一样的。因为BroadcastReceiver任何时候都可以接收广播消息,而发送广播消息,只要有上下文的地方都可以。

静态广播接收者的接收测试

package com.lwz.receiver;  import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast;  /**  * 广播接收者的使用  * 这里使用的是静态注册的方法,等待接收广播  */  public class MyBroadcastReceiver extends BroadcastReceiver {     @Override     public void onReceive(Context context, Intent intent) {         Log.e("Receiver", "这是静态的广播接受者(优先级500)---》" + intent.getStringExtra("msg"));         Toast.makeText(context, "这是使用静态的方法来创建的广播(优先级500)接受者收到消息", Toast.LENGTH_SHORT).show();         abortBroadcast();     } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
package com.lwz.receiver;  import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast;  /**  * 广播接收者的使用  * 这里使用的是静态注册的方法,等待接收广播  */  public class MyBroadcastReceiver2 extends BroadcastReceiver {       @Override     public void onReceive(Context context, Intent intent) {          Log.e("Receiver", "这是静态的广播接受者(优先级999)---》" + intent.getStringExtra("msg"));         Toast.makeText(context, "这是使用静态的方法来创建的广播接受者(优先级999)收到消息", Toast.LENGTH_SHORT).show();         //截断广播         abortBroadcast();         //报错 BroadcastReceiver trying to return result during a non-ordered broadcast         //好像是要有序广播才能截断      }   }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  <receiver android:name=".MyBroadcastReceiver">             <intent-filter android:priority="500">                 <action android:name="myBroadcastReceiver" />                 <category android:name="android.intent.category.DEFAULT" />             </intent-filter>         </receiver>         <receiver android:name=".MyBroadcastReceiver2">             <intent-filter android:priority="999">                 <action android:name="myBroadcastReceiver" />                 <category android:name="android.intent.category.DEFAULT" />             </intent-filter>         </receiver>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

注意这里的广播接收者1和2,基本数据是相同的,但是优先级不同。

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical">      <TextView         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:layout_gravity="center_horizontal"         android:text="广播的发送" />      <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:onClick="sendToSXL"         android:text="给静态注册的广播发送信息" />      <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:onClick="sendToJava"         android:text="给动态注册的广播发送信息" />      <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:onClick="sendOrderToXML"         android:text="给静态注册的广播接收者发送有序广播信息" />      <Button         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:onClick="sendOrderToJava"         android:text="给动态注册的广播接收者发送有序广播信息" />  </LinearLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

根据上面按钮的命名,应该知道这些按钮要发送的广播类型!

package com.lwz.receiver;  import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View;  /**  * 本类用来发送广播  */ public class MainActivity extends AppCompatActivity {      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);     }      //给静态广播发送信息     public void sendToSXL(View view) {         //发送广播使用sendBroadcast,需要指定Intent的action来说明发送什么样的广播。         //Intent里面的参数是action,要和静态注册的广播的actin对应         Intent intent = new Intent("myBroadcastReceiver");         intent.putExtra("msg", "这是MainActivity页面发送的广播----》》");         sendBroadcast(intent);      }      //给动态广播发送信息     public void sendToJava(View view) {         //发送广播使用sendBroadcast,需要指定Intent的action来说明发送什么样的广播。         //Intent里面的参数是action,要和动态注册的广播的actin对应         Intent intent = new Intent("javaReceiver");         intent.putExtra("msg", "这是MainActivity页面发送的广播----》》");         sendBroadcast(intent);     }      //给静态注册的广播发送有序广播信息     public void sendOrderToXML(View view) {         //发送有序广播使用sendOrderedBroadcast,需要指定Intent的action来说明发送什么样的广播。         //Intent里面的参数是action,要和静态注册的广播的actin对应         Intent intent = new Intent("myBroadcastReceiver");         intent.putExtra("msg", "这是MainActivity页面发送的广播----》》");         sendOrderedBroadcast(intent,null);      }     //给静态注册的广播发送有序广播信息     public void sendOrderToJava(View view) {         //发送广播使用sendOrderedBroadcast,需要指定Intent的action来说明发送什么样的广播。         //Intent里面的参数是action,要和静态注册的广播的actin对应         Intent intent = new Intent("javaReceiver");         intent.putExtra("msg", "这是MainActivity页面发送的广播----》》");         sendOrderedBroadcast(intent,null);      }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59




动态广播接收者的测试

 package com.lwz.receiver2;  import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast;  /**  * 这里使用动态的方法来创建一个广播接受者  * 动态的广播接收者必须在程序启动后才能接收广播,静态的广播不需要启动就可以接收!  */  public class BroadcastReceiveForjava extends BroadcastReceiver {     @Override     public void onReceive(Context context, Intent intent) {         Log.e("Receiver", "这是使用动态的方法来创建的广播接受者1)----》" + intent.getStringExtra("msg"));         Toast.makeText(context, "这是使用动态的方法来创建的广播接受者1收到消息", Toast.LENGTH_SHORT).show();        abortBroadcast();     } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

package com.lwz.receiver2;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

/**
* 这里使用动态的方法来创建一个广播接受者
* 动态的广播接收者必须在程序启动后才能接收广播,静态的广播不需要启动就可以接收!
*/

public class BroadcastReceiveForjava2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e(“Receiver”, “这是使用动态的方法来创建的广播接受者2―-》” + intent.getStringExtra(“msg”));
Toast.makeText(context, “这是使用动态的方法来创建的广播接受者2收到消息”, Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}

package com.lwz.receiver2;  import android.content.IntentFilter; import android.os.Bundle; import android.support.v7.app.AppCompatActivity;  /**  * 这里使用动态的方法来创建一个广播接受者  * 动态的广播接收者必须在程序启动后才能接收广播,静态的广播不需要启动就可以接收!  * 动态广播的类创建之后要去使用代码注册才能生效  * 另外动态注册后要在某一个时间去解除绑定,否者会报错!  */ public class MainActivity extends AppCompatActivity {      //定义广播接收者     BroadcastReceiveForjava receiver;     BroadcastReceiveForjava2 receiver2;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         //创建广播接收者对象         receiver = new BroadcastReceiveForjava();         receiver2 = new BroadcastReceiveForjava2();         //注册广播接收者,需要一个意图对象,也需要action参数,这里是定义Action参数         IntentFilter filter = new IntentFilter("javaReceiver");         IntentFilter filter2 = new IntentFilter("javaReceiver");         //动态设置广播的优先级         filter.setPriority(999);         filter2.setPriority(10);         //注册广播,         // 动态广播拦截?先注册者先收到消息???         registerReceiver(receiver2, filter);         registerReceiver(receiver, filter);     }      @Override     protected void onDestroy() {         //在适当的时候要解除广播接收者的绑定         unregisterReceiver(receiver);         unregisterReceiver(receiver2);         super.onDestroy();     } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45















无序广播不能截断,有序广播能被高优先级的广播接收者截断。不管是对静态的广播接收者还是对动态的广播接收者都是一样的。

package com.lwz.phoneData;  import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.SmsMessage; import android.util.Log; import android.widget.Toast;  import java.text.SimpleDateFormat; import java.util.Date;  /**  * 创建一个短信拦截广播接收者  */  public class SMSBroadcastReceiver extends BroadcastReceiver {     private static final String action = "android.provider.Telephony.SMS_RECEIVED";      @Override     public void onReceive(Context context, Intent intent) {         if (intent.getAction().equals(action)) {             Object[] pduses = (Object[]) intent.getExtras().get("pdus");             String mobile = "";             String content = "";             String time = "";             System.out.println(pduses.length);             for (Object pdus : pduses) {                 byte[] pdusmessage = (byte[]) pdus;                 SmsMessage sms = SmsMessage.createFromPdu(pdusmessage);                 mobile = sms.getOriginatingAddress();// 发送短信的手机号码                 content = sms.getMessageBody(); // 短信内容                 Date date = new Date(sms.getTimestampMillis());// 发送日                期                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");                 time = format.format(date); // 得到发送时间             }             Toast.makeText(context, context.getResources().getString(R.string.app_name), Toast.LENGTH_LONG).show();             String show = "发送者:" + mobile + " 内容:" + content + "      时间:" + time;             Toast.makeText(context, show, Toast.LENGTH_LONG).show();         }         Log.e("TAG","拦截短信");         abortBroadcast();     }  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
<receiver android:name=".SMSBroadcastReceiver">             <intent-filter android:priority="1001">               <action android:name="android.provider.Telephony.SMS_RECEIVED" />                 <category android:name="android.intent.category.DEFAULT" />             </intent-filter>         </receiver>  这里action的属性值必须正确,否则不能监听到这个广播! 这里还要添加手机权限: <uses-permission android:name="android.permission.RECEIVE_SMS" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

1.Intent.ACTION_AIRPLANE_M;

2.Intent.ACTION_BATTERY_CH;


3.Intent.ACTION_AIRPLANE_MODE_CHANGED;

4.Intent.ACTION_BATTERY_CHANGED;


5.Intent.ACTION_BATTERY_LOW;

6 .Intent.ACTION_BATTERY_OKAY;

7.Intent.ACTION_BOOT_COMPLETED;

8.Intent.ACTION_CAMERA_BUTTON;

9.Intent.ACTION_CLOSE_SYSTEM_DIALOGS;

10.Intent.ACTION_CONFIGURATION_CHANGED;

11.Intent.ACTION_DATE_CHANGED;

12.Intent.ACTION_DEVICE_STORAGE_LOW;

13.Intent.ACTION_DEVICE_STORAGE_OK;

14.Intent.ACTION_DOCK_EVENT;

frameworks\base\services\java\com\android\server\DockObserver.java
15.Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;

16.Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;

17.Intent.ACTION_GTALK_SERVICE_CONNECTED;

18.Intent.ACTION_GTALK_SERVICE_DISCONNECTED;

19.Intent.ACTION_HEADSET_PLUG;

20.Intent.ACTION_INPUT_METHOD_CHANGED;

21.Intent.ACTION_LOCALE_CHANGED;

22.Intent.ACTION_MANAGE_PACKAGE_STORAGE;

23. Intent.ACTION_MEDIA_BAD_REMOVAL;

24.Intent.ACTION_MEDIA_BUTTON;

25. Intent.ACTION_MEDIA_CHECKING;

26.Intent.ACTION_MEDIA_EJECT;

27.Intent.ACTION_MEDIA_MOUNTED;

28.Intent.ACTION_MEDIA_NOFS;

29. Intent.ACTION_MEDIA_REMOVED;

30.Intent.ACTION_MEDIA_SCANNER_FINISHED;

31.Intent.ACTION_MEDIA_SCANNER_SCAN_FILE;

32.Intent.ACTION_MEDIA_SCANNER_STARTED;

33. Intent.ACTION_MEDIA_SHARED;

34.Intent.ACTION_MEDIA_UNMOUNTABLE;
35.Intent.ACTION_MEDIA_UNMOUNTED

36.Intent.ACTION_NEW_OUTGOING_CALL;
37. Intent.ACTION_PACKAGE_ADDED;



38.Intent.ACTION_PACKAGE_CHANGED;

39.Intent.ACTION_PACKAGE_DATA_CLEARED;


40.Intent.ACTION_PACKAGE_INSTALL;

41.Intent.ACTION_PACKAGE_REMOVED;

42.Intent.ACTION_PACKAGE_REPLACED;

43.Intent.ACTION_PACKAGE_RESTARTED;

44.Intent.ACTION_POWER_CONNECTED;

45.Intent.ACTION_POWER_DISCONNECTED;

46.Intent.ACTION_PROVIDER_CHANGED;
47.Intent.ACTION_REBOOT;

48.Intent.ACTION_SCREEN_OFF;

49. Intent.ACTION_SCREEN_ON;

50.Intent.ACTION_SHUTDOWN;

51. Intent.ACTION_TIMEZONE_CHANGED;

52.Intent.ACTION_TIME_CHANGED;

53.Intent.ACTION_TIME_TICK;

54. Intent.ACTION_UID_REMOVED;

55. Intent.ACTION_UMS_CONNECTED;
设备已进入USB大容量储存状态时发出的广播?
56.Intent.ACTION_UMS_DISCONNECTED;

57.Intent.ACTION_USER_PRESENT;
58.Intent.ACTION_WALLPAPER_CHANGED;

发送频率低的可以使用 数据量小在可使用 intent携带的数据不能太大 广播的操作一定要在5秒钟内完成(10秒不能完成,ANR),如果耗时时间太长,开启服务。



两种发送方法









两者及其接收广播的区别:

(1)动态注册广播不是常驻型广播,也就是说广播跟随Activity的生命周期。注意在Activity结束前,移除广播接收器。 静态注册是常驻型,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
(注:静态注册的广播,即使Activity销毁了,仍然可以收到广播。更牛掰的是即使杀死进程,仍然可以收到广播,关于这点不同的手机测试的结果是不同的,为了验证这个问题,我用的是google的nexus手机测试的。
  在Android中,有一些action是不支持静态注册的:
    android.intent.action.SCREEN_ON
    android.intent.action.SCREEN_OFF
    android.intent.action.BATTERY_CHANGED
    android.intent.action.CONFIGURATION_CHANGED
    android.intent.action.TIME_TICK)

(2)当广播为有序广播时:优先级高的先接收(不分静态和动态)。同优先级的广播接收器,动态优先于静态

(3)同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后注册的。

(4)当广播为默认广播时:无视优先级,动态广播接收器优先于静态广播接收器。同优先级的同类广播接收器,静态:先扫描的优先于后扫描的,动态:先注册的优先于后册的。

        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">             </div> 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!