Android的广播Receiver动态注册和静态注册示例

广播接收器注册一共有两种形式 : 静态注册和动态注册.

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

1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低。

2.动态注册广播不是 常驻型广播 ,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。

静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。

3.在同一个优先级下,谁先启动的快,谁将先接收到广播。

下面这个Demo,界面如下,注册两个动态接收器(接收自定义广播和系统广播)和注册静态广播(接收自定义静态和广播、手机USB的插拔事件、接收短信并读取短信息)

工程目录如下:注意看代码中的注释

xml布局文件(activity_main.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
  
 <Button
   android:id="@+id/send_static"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="发送自定义静态注册广播"/>
  
 <Button android:id="@+id/send_dynamic"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="发送自定义动态注册广播"/>
  
 <Button
   android:id="@+id/send_system"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="发送系统动态注册广播"/>
  
</LinearLayout>

Manifest.xml如下,这里面定义的权限信息和注册的广播

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
<?xml version="1.0" encoding="utf-8"?>
 package="com.nii.receiver" >
  
 <!--监听短信息-->
 <uses-permission android:name="android.permission.RECEIVE_SMS" />
 <uses-permission android:name="android.permission.READ_SMS" />
  
 <application
  android:allowBackup="true"
  android:icon="@mipmap/ic_launcher"
  android:label="@string/app_name"
  android:supportsRtl="true"
  android:theme="@style/AppTheme" >
  <activity android:name=".MainActivity" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
  
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>
  
  <!-- 注册自定义静态广播接收器 -->
  <receiver android:name=".StaticReceiver">
   <intent-filter>
    <action android:name="com.byread.static" />
   </intent-filter>
  </receiver>
  
  <!-- 注册系统静态广播接收器 -->
  <receiver android:name=".SystemReceiver">
   <intent-filter>
    <action android:name="android.intent.action.BATTERY_LOW" />
    <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    <action android:name="android.hardware.usb.action.USB_STATE"/>
  </intent-filter>
  </receiver>
  
  
 </application>
  
</manifest>

MainActivity.Java

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.nii.receiver;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.nii.receiver.type.RequestPermissionType;
import com.nii.receiver.util.PermissionUtil;
  
public class MainActivity extends AppCompatActivity
{
  
 /**
  * 发送静态广播按钮
  */
 private Button sendStaticBtn;
  
 /**
  * 发送动态广播按钮
  */
 private Button sendDynamicBtn;
  
 /**
  * 发送系统广播按钮
  */
 private Button sendSystemBtn;
  
 /**
  * 静态action
  */
 private static final String STATICACTION = "com.byread.static";
  
 /**
  * 动态action
  */
 private static final String DYNAMICACTION = "com.byread.dynamic";
  
 /**
  * USB设备连接
  */
 private static final String SYSTEMACTION = Intent.ACTION_POWER_CONNECTED;
  
 private Context mContext;
  
 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  this.mContext = this;
  
  sendStaticBtn = (Button) findViewById(R.id.send_static);
  sendDynamicBtn = (Button) findViewById(R.id.send_dynamic);
  sendSystemBtn = (Button) findViewById(R.id.send_system);
  sendStaticBtn.setOnClickListener(new MyOnClickListener());
  sendDynamicBtn.setOnClickListener(new MyOnClickListener());
  sendSystemBtn.setOnClickListener(new MyOnClickListener());
  
  //申请读取短信的权限
  PermissionUtil.requestPermission(mContext, Manifest.permission.READ_SMS,
    RequestPermissionType.REQUEST_CODE_ASK_READ_SMS);
  
  PermissionUtil.requestPermission(mContext, Manifest.permission.RECEIVE_SMS,
    RequestPermissionType.REQUEST_CODE_ASK_RECEIVE_SMS);
 }
 class MyOnClickListener implements View.OnClickListener
 {
  @Override
  public void onClick(View v)
  {
   // 发送自定义静态注册广播消息
   if (v.getId() == R.id.send_static)
   {
    Log.e("MainActivity", "发送自定义静态注册广播消息");
    Intent intent = new Intent();
    intent.setAction(STATICACTION);
    intent.putExtra("msg", "接收静态注册广播成功!");
    sendBroadcast(intent);
   }
   // 发送自定义动态注册广播消息
   else if (v.getId() == R.id.send_dynamic)
   {
    Log.e("MainActivity", "发送自定义动态注册广播消息");
    Intent intent = new Intent();
    intent.setAction(DYNAMICACTION);
    intent.putExtra("msg", "接收动态注册广播成功!");
    sendBroadcast(intent);
   }
   // 发送系统动态注册广播消息。当手机连接充电设备时会由系统自己发送广播消息。
   else if (v.getId() == R.id.send_system)
   {
    Log.e("MainActivity", "发送系统动态注册广播消息");
    Intent intent = new Intent();
    intent.setAction(SYSTEMACTION);
    intent.putExtra("msg", "正在充电。。。。");
   }
  }
 }
  
 @Override
 protected void onStart()
 {
  super.onStart();
  Log.e("MainActivity", "注册广播事件");
  
  // 注册自定义动态广播消息
  IntentFilter filter_dynamic = new IntentFilter();
  filter_dynamic.addAction(DYNAMICACTION);
  registerReceiver(dynamicReceiver, filter_dynamic);
  
  // 注册系统动态广播消息
  IntentFilter filter_system = new IntentFilter();
  filter_system.addAction(SYSTEMACTION);
  registerReceiver(systemReceiver, filter_system);
 }
  
 private BroadcastReceiver dynamicReceiver = new BroadcastReceiver()
 {
  
  @Override
  public void onReceive(Context context, Intent intent)
  {
   Log.e("MainActivity", "接收自定义动态注册广播消息");
   if (intent.getAction().equals(DYNAMICACTION))
   {
    String msg = intent.getStringExtra("msg");
    Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
   }
  }
 };
  
 private BroadcastReceiver systemReceiver = new BroadcastReceiver()
 {
  @Override
  public void onReceive(Context context, Intent intent)
  {
   Log.e("MainActivity", "接收系统动态注册广播消息");
   if (intent.getAction().equals(SYSTEMACTION))
   {
    String msg = intent.getStringExtra("msg");
    Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
   }
  }
 };
}

StaticReceiver.java

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
package com.nii.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.widget.Toast;
  
/**
 * Created by wzj on 2017/2/19.
 */
public class StaticReceiver extends BroadcastReceiver
{
  
 /**
  * 接收广播
  * @param context context
  * @param intent intent
  */
 @Override
 public void onReceive(Context context, Intent intent)
 {
  String msg = intent.getStringExtra("msg");
  Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
 }
}

SystemReceiver.java这里面处理一些系统的事件

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.nii.receiver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.telephony.SmsMessage;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.Toast;
import com.nii.receiver.util.DialogUtil;
  
import java.util.Date;
  
/**
 * Created by wzj on 2017/2/19.
 */
public class SystemReceiver extends BroadcastReceiver
{
  
 /**
  * 接收系统静态广播
  *
  * @param context context
  * @param intent intent
  */
 @Override
 public void onReceive(Context context, Intent intent)
 {
  if (intent.getAction().equals(Intent.ACTION_BATTERY_LOW))
  {
   Log.e("SystemReceiver", "电量低提示");
   Toast.makeText(context, "您的手机电量偏低,请及时充电", Toast.LENGTH_SHORT).show();
  }
  else if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
  {
   if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
   {
    Bundle bundle = intent.getExtras();
    if (bundle != null)
    {//如果数据不为空
     //获得收到的短信数据
     Object[] objArray = (Object[]) bundle.get("pdus");
     //根据objArray的大小创建一个SmsMessage数组,用于封装短信内容
     SmsMessage[] smsMessage = new SmsMessage[objArray.length];
     StringBuffer sb = new StringBuffer();
     sb.append("时间:" + new DateFormat().format("yyyy - MM - dd hh.mm.ss", new Date()));
  
     //遍历smsMessage数组取出所有短信
     for (int i = 0; i < smsMessage.length; i++)
     {
      //将每条字节类型的短信数据转换成SmsMessage对象
      smsMessage[i] = SmsMessage.createFromPdu((byte[]) objArray[i]);
      //获取短信发送地址
      sb.append("发送者:" + smsMessage[i].getOriginatingAddress());
      //获取短信内容
      sb.append("短信内容:" + smsMessage[i].getDisplayMessageBody() + "\n");
     }
  
     DialogUtil.showPrompt(context,sb.toString());
     Toast.makeText(context, sb.toString(), Toast.LENGTH_LONG).show();
    }
   }
  }
  else if(intent.getAction().equals("android.hardware.usb.action.USB_STATE"))
  {
   if (intent.getExtras().getBoolean("connected"))
   {
    Toast.makeText(context, "USB插入", Toast.LENGTH_LONG).show();
   }
   else
   {
    Toast.makeText(context, "USB拔出", Toast.LENGTH_LONG).show();
   }
  }
 }
}

RequestPermissionType.java是权限请求的时候,Qequest Code(请求码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.nii.receiver.type;
  
/**
 * Created by wzj on 2017/2/19.
 */
public interface RequestPermissionType
{
 /**
  * 请求打电话的权限码
  */
 int REQUEST_CODE_ASK_CALL_PHONE = 100;
  
 /**
  * 请求接收短信息
  */
 int REQUEST_CODE_ASK_RECEIVE_SMS = 101;
  
 /**
  * 请求读短信
  */
 int REQUEST_CODE_ASK_READ_SMS = 102;
}

DialogUtil.java是界面弹窗工具类

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.nii.receiver.util;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.WindowManager;
/**
 * 对话框工具箱
 *
 * @author xiaopan
 */
public class DialogUtil
{
 /**
  * 显示一个对话框
  *
  * @param context     上下文对象,最好给Activity,否则需要android.permission.SYSTEM_ALERT_WINDOW
  * @param title      标题
  * @param message     消息
  * @param confirmButton    确认按钮
  * @param confirmButtonClickListener 确认按钮点击监听器
  * @param centerButton    中间按钮
  * @param centerButtonClickListener 中间按钮点击监听器
  * @param cancelButton    取消按钮
  * @param cancelButtonClickListener 取消按钮点击监听器
  * @param onShowListener    显示监听器
  * @param cancelable     是否允许通过点击返回按钮或者点击对话框之外的位置关闭对话框
  * @param onCancelListener   取消监听器
  * @param onDismissListener   销毁监听器
  * @return 对话框
  */
 public static AlertDialog showAlert(Context context, String title, String message,
          String confirmButton, DialogInterface.OnClickListener confirmButtonClickListener,
          String centerButton, DialogInterface.OnClickListener centerButtonClickListener,
          String cancelButton, DialogInterface.OnClickListener cancelButtonClickListener,
          DialogInterface.OnShowListener onShowListener, boolean cancelable,
          DialogInterface.OnCancelListener onCancelListener,
          DialogInterface.OnDismissListener onDismissListener)
 {
  AlertDialog.Builder promptBuilder = new AlertDialog.Builder(context);
  if (title != null)
  {
   promptBuilder.setTitle(title);
  }
  if (message != null)
  {
   promptBuilder.setMessage(message);
  }
  if (confirmButton != null)
  {
   promptBuilder.setPositiveButton(confirmButton, confirmButtonClickListener);
  }
  if (centerButton != null)
  {
   promptBuilder.setNeutralButton(centerButton, centerButtonClickListener);
  }
  if (cancelButton != null)
  {
   promptBuilder.setNegativeButton(cancelButton, cancelButtonClickListener);
  }
  promptBuilder.setCancelable(true);
  if (cancelable)
  {
   promptBuilder.setOnCancelListener(onCancelListener);
  }
  
  AlertDialog alertDialog = promptBuilder.create();
  if (!(context instanceof Activity))
  {
   alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
  }
  alertDialog.setOnDismissListener(onDismissListener);
  alertDialog.setOnShowListener(onShowListener);
  alertDialog.show();
  return alertDialog;
 }
  
  
 /**
  * 显示一个对话框
  *
  * @param context     上下文对象,最好给Activity,否则需要android.permission.SYSTEM_ALERT_WINDOW
  * @param title      标题
  * @param message     消息
  * @param confirmButtonClickListener 确认按钮点击监听器
  * @param cancelButtonClickListener 取消按钮点击监听器
  * @return 对话框
  */
 public static AlertDialog showConfirm(Context context, String title, String message,
          DialogInterface.OnClickListener confirmButtonClickListener,
          DialogInterface.OnClickListener cancelButtonClickListener)
 {
  return showAlert(context, title, message, "Yes",
    confirmButtonClickListener, null, null, "No", cancelButtonClickListener, null, true, null, null);
 }
  
  
 /**
  * 显示一个提示框
  *
  * @param context  上下文对象,最好给Activity,否则需要android.permission.SYSTEM_ALERT_WINDOW
  * @param message  提示的消息
  * @param confirmButton 确定按钮的名字
  */
 public static AlertDialog showPrompt(Context context, String message, String confirmButton)
 {
  return showAlert(context, null, message, confirmButton, null, null, null, null, null, null, true, null, null);
 }
  
  
  
 /**
  * 显示一个提示框
  *
  * @param context 上下文对象,最好给Activity,否则需要android.permission.SYSTEM_ALERT_WINDOW
  * @param message 提示的消息
  */
 public static AlertDialog showPrompt(Context context, String message)
 {
  return showAlert(context, null, message, "OK", null, null, null, null, null, null, true, null, null);
 }
}

PermissionUtil.java是权限申请工具类

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
package com.nii.receiver.util;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
  
/**
 * Created by wzj on 2017/2/19.
 */
public abstract class PermissionUtil
{
 /**
  * 请求权限
  * @param mContext mContext
  * @param permission permission
  * @param requestCode requestCode
  */
 public static void requestPermission(Context mContext,String permission,int requestCode)
 {
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
  {
   return;
  }
  
  int checkCallPhonePermission = ContextCompat.checkSelfPermission(mContext,permission);
  
  if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED)
  {
   ActivityCompat.requestPermissions((Activity) mContext, new String[]{permission},requestCode);
  }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

posted @ 2019-06-14 21:06  天涯海角路  阅读(1231)  评论(0)    收藏  举报