时间:2022-03-16 09:50:54 | 栏目:Android代码 | 点击:次
广播接收器注册一共有两种形式 : 静态注册和动态注册.
两者及其接收广播的区别:
1.动态注册的广播 永远要快于 静态注册的广播,不管静态注册的优先级设置的多高,不管动态注册的优先级有多低。
2.动态注册广播不是 常驻型广播 ,也就是说广播跟随activity的生命周期。注意: 在activity结束前,移除广播接收器。
静态注册是常驻型 ,也就是说当应用程序关闭后,如果有信息广播来,程序也会被系统调用自动运行。
3.在同一个优先级下,谁先启动的快,谁将先接收到广播。
下面这个Demo,界面如下,注册两个动态接收器(接收自定义广播和系统广播)和注册静态广播(接收自定义静态和广播、手机USB的插拔事件、接收短信并读取短信息)
工程目录如下:注意看代码中的注释
xml布局文件(activity_main.xml)
<?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如下,这里面定义的权限信息和注册的广播
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" 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
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
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这里面处理一些系统的事件
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(请求码)
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是界面弹窗工具类
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是权限申请工具类
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); } } }