Android的廣播Receiver動(dòng)態(tài)注冊(cè)和靜態(tài)注冊(cè)示例
廣播接收器注冊(cè)一共有兩種形式 : 靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè).
兩者及其接收廣播的區(qū)別:
1.動(dòng)態(tài)注冊(cè)的廣播 永遠(yuǎn)要快于 靜態(tài)注冊(cè)的廣播,不管靜態(tài)注冊(cè)的優(yōu)先級(jí)設(shè)置的多高,不管動(dòng)態(tài)注冊(cè)的優(yōu)先級(jí)有多低。
2.動(dòng)態(tài)注冊(cè)廣播不是 常駐型廣播 ,也就是說廣播跟隨activity的生命周期。注意: 在activity結(jié)束前,移除廣播接收器。
靜態(tài)注冊(cè)是常駐型 ,也就是說當(dāng)應(yīng)用程序關(guān)閉后,如果有信息廣播來,程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行。
3.在同一個(gè)優(yōu)先級(jí)下,誰先啟動(dòng)的快,誰將先接收到廣播。
下面這個(gè)Demo,界面如下,注冊(cè)兩個(gè)動(dòng)態(tài)接收器(接收自定義廣播和系統(tǒng)廣播)和注冊(cè)靜態(tài)廣播(接收自定義靜態(tài)和廣播、手機(jī)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="發(fā)送自定義靜態(tài)注冊(cè)廣播"/>
<Button android:id="@+id/send_dynamic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發(fā)送自定義動(dòng)態(tài)注冊(cè)廣播"/>
<Button
android:id="@+id/send_system"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發(fā)送系統(tǒng)動(dòng)態(tài)注冊(cè)廣播"/>
</LinearLayout>
Manifest.xml如下,這里面定義的權(quán)限信息和注冊(cè)的廣播
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nii.receiver" >
<!--監(jiān)聽短信息-->
<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>
<!-- 注冊(cè)自定義靜態(tài)廣播接收器 -->
<receiver android:name=".StaticReceiver">
<intent-filter>
<action android:name="com.byread.static" />
</intent-filter>
</receiver>
<!-- 注冊(cè)系統(tǒng)靜態(tài)廣播接收器 -->
<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
{
/**
* 發(fā)送靜態(tài)廣播按鈕
*/
private Button sendStaticBtn;
/**
* 發(fā)送動(dòng)態(tài)廣播按鈕
*/
private Button sendDynamicBtn;
/**
* 發(fā)送系統(tǒng)廣播按鈕
*/
private Button sendSystemBtn;
/**
* 靜態(tài)action
*/
private static final String STATICACTION = "com.byread.static";
/**
* 動(dòng)態(tài)action
*/
private static final String DYNAMICACTION = "com.byread.dynamic";
/**
* USB設(shè)備連接
*/
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());
//申請(qǐng)讀取短信的權(quán)限
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)
{
// 發(fā)送自定義靜態(tài)注冊(cè)廣播消息
if (v.getId() == R.id.send_static)
{
Log.e("MainActivity", "發(fā)送自定義靜態(tài)注冊(cè)廣播消息");
Intent intent = new Intent();
intent.setAction(STATICACTION);
intent.putExtra("msg", "接收靜態(tài)注冊(cè)廣播成功!");
sendBroadcast(intent);
}
// 發(fā)送自定義動(dòng)態(tài)注冊(cè)廣播消息
else if (v.getId() == R.id.send_dynamic)
{
Log.e("MainActivity", "發(fā)送自定義動(dòng)態(tài)注冊(cè)廣播消息");
Intent intent = new Intent();
intent.setAction(DYNAMICACTION);
intent.putExtra("msg", "接收動(dòng)態(tài)注冊(cè)廣播成功!");
sendBroadcast(intent);
}
// 發(fā)送系統(tǒng)動(dòng)態(tài)注冊(cè)廣播消息。當(dāng)手機(jī)連接充電設(shè)備時(shí)會(huì)由系統(tǒng)自己發(fā)送廣播消息。
else if (v.getId() == R.id.send_system)
{
Log.e("MainActivity", "發(fā)送系統(tǒng)動(dòng)態(tài)注冊(cè)廣播消息");
Intent intent = new Intent();
intent.setAction(SYSTEMACTION);
intent.putExtra("msg", "正在充電。。。。");
}
}
}
@Override
protected void onStart()
{
super.onStart();
Log.e("MainActivity", "注冊(cè)廣播事件");
// 注冊(cè)自定義動(dòng)態(tài)廣播消息
IntentFilter filter_dynamic = new IntentFilter();
filter_dynamic.addAction(DYNAMICACTION);
registerReceiver(dynamicReceiver, filter_dynamic);
// 注冊(cè)系統(tǒng)動(dòng)態(tài)廣播消息
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", "接收自定義動(dòng)態(tài)注冊(cè)廣播消息");
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", "接收系統(tǒng)動(dòng)態(tài)注冊(cè)廣播消息");
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這里面處理一些系統(tǒng)的事件
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
{
/**
* 接收系統(tǒng)靜態(tài)廣播
*
* @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, "您的手機(jī)電量偏低,請(qǐng)及時(shí)充電", 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)
{//如果數(shù)據(jù)不為空
//獲得收到的短信數(shù)據(jù)
Object[] objArray = (Object[]) bundle.get("pdus");
//根據(jù)objArray的大小創(chuàng)建一個(gè)SmsMessage數(shù)組,用于封裝短信內(nèi)容
SmsMessage[] smsMessage = new SmsMessage[objArray.length];
StringBuffer sb = new StringBuffer();
sb.append("時(shí)間:" + new DateFormat().format("yyyy - MM - dd hh.mm.ss", new Date()));
//遍歷smsMessage數(shù)組取出所有短信
for (int i = 0; i < smsMessage.length; i++)
{
//將每條字節(jié)類型的短信數(shù)據(jù)轉(zhuǎn)換成SmsMessage對(duì)象
smsMessage[i] = SmsMessage.createFromPdu((byte[]) objArray[i]);
//獲取短信發(fā)送地址
sb.append("發(fā)送者:" + smsMessage[i].getOriginatingAddress());
//獲取短信內(nèi)容
sb.append("短信內(nèi)容:" + 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是權(quán)限請(qǐng)求的時(shí)候,Qequest Code(請(qǐng)求碼)
package com.nii.receiver.type;
/**
* Created by wzj on 2017/2/19.
*/
public interface RequestPermissionType
{
/**
* 請(qǐng)求打電話的權(quán)限碼
*/
int REQUEST_CODE_ASK_CALL_PHONE = 100;
/**
* 請(qǐng)求接收短信息
*/
int REQUEST_CODE_ASK_RECEIVE_SMS = 101;
/**
* 請(qǐng)求讀短信
*/
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;
/**
* 對(duì)話框工具箱
*
* @author xiaopan
*/
public class DialogUtil
{
/**
* 顯示一個(gè)對(duì)話框
*
* @param context 上下文對(duì)象,最好給Activity,否則需要android.permission.SYSTEM_ALERT_WINDOW
* @param title 標(biāo)題
* @param message 消息
* @param confirmButton 確認(rèn)按鈕
* @param confirmButtonClickListener 確認(rèn)按鈕點(diǎn)擊監(jiān)聽器
* @param centerButton 中間按鈕
* @param centerButtonClickListener 中間按鈕點(diǎn)擊監(jiān)聽器
* @param cancelButton 取消按鈕
* @param cancelButtonClickListener 取消按鈕點(diǎn)擊監(jiān)聽器
* @param onShowListener 顯示監(jiān)聽器
* @param cancelable 是否允許通過點(diǎn)擊返回按鈕或者點(diǎn)擊對(duì)話框之外的位置關(guān)閉對(duì)話框
* @param onCancelListener 取消監(jiān)聽器
* @param onDismissListener 銷毀監(jiān)聽器
* @return 對(duì)話框
*/
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;
}
/**
* 顯示一個(gè)對(duì)話框
*
* @param context 上下文對(duì)象,最好給Activity,否則需要android.permission.SYSTEM_ALERT_WINDOW
* @param title 標(biāo)題
* @param message 消息
* @param confirmButtonClickListener 確認(rèn)按鈕點(diǎn)擊監(jiān)聽器
* @param cancelButtonClickListener 取消按鈕點(diǎn)擊監(jiān)聽器
* @return 對(duì)話框
*/
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);
}
/**
* 顯示一個(gè)提示框
*
* @param context 上下文對(duì)象,最好給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);
}
/**
* 顯示一個(gè)提示框
*
* @param context 上下文對(duì)象,最好給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是權(quán)限申請(qǐng)工具類
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
{
/**
* 請(qǐng)求權(quán)限
* @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);
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
玩轉(zhuǎn)Kotlin 徹底弄懂Lambda和高階函數(shù)
這篇文章主要幫助大家徹底弄懂Lambda和高階函數(shù),玩轉(zhuǎn)Kotlin,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Android 實(shí)現(xiàn)頁面跳轉(zhuǎn)
android使用Intent來實(shí)現(xiàn)頁面跳轉(zhuǎn),接下來通過本文給大家分享Android 實(shí)現(xiàn)頁面跳轉(zhuǎn)的實(shí)例代碼,需要的的朋友參考下吧2017-09-09
Adapter模式實(shí)戰(zhàn)之重構(gòu)鴻洋集團(tuán)的Android圓形菜單建行
這篇文章主要介紹了Adapter模式實(shí)戰(zhàn)之重構(gòu)鴻洋集團(tuán)的Android圓形菜單建行的相關(guān)資料,需要的朋友可以參考下2016-03-03
Android編程實(shí)現(xiàn)長(zhǎng)按彈出選項(xiàng)框View進(jìn)行操作的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)長(zhǎng)按彈出選項(xiàng)框View進(jìn)行操作的方法,結(jié)合實(shí)例形式分析了Android事件響應(yīng)及彈窗的功能、布局相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
Android自定義View之簡(jiǎn)約風(fēng)歌詞控件實(shí)戰(zhàn)指南
一些接觸Android不久的朋友對(duì)自定義View都有一絲畏懼感,總感覺這是一個(gè)比較高級(jí)的技術(shù),但其實(shí)自定義View并不復(fù)雜,有時(shí)候只需要簡(jiǎn)單幾行代碼就可以完成了,這篇文章主要給大家介紹了關(guān)于Android自定義View之簡(jiǎn)約風(fēng)歌詞控件的相關(guān)資料,需要的朋友可以參考下2021-07-07
詳解Recyclerview item中有EditText使用刷新遇到的坑
這篇文章主要介紹了詳解Recyclerview item中有EditText使用刷新遇到的坑,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
Android實(shí)現(xiàn)手機(jī)壁紙改變的方法
這篇文章主要介紹了Android實(shí)現(xiàn)手機(jī)壁紙改變的方法,以完整實(shí)例形式分析了Android手機(jī)壁紙改變的方法,包括頁面布局及屬性設(shè)置的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09
Android編程實(shí)現(xiàn)根據(jù)不同日期計(jì)算天數(shù)差的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)根據(jù)不同日期計(jì)算天數(shù)差的方法,涉及Android調(diào)用日期類Calendar實(shí)現(xiàn)時(shí)間運(yùn)算的相關(guān)技巧,需要的朋友可以參考下2016-03-03

