安卓基礎之BroadcastReceiver

1、靜態廣播註冊

MainActivity.java
public class MainActivity extends AppCompatActivity {

    @BindView(R.id.btn_send)
    Button mBtnSend;
    @BindView(R.id.btn_unregister)
    Button mBtnUnregister;
    @BindView(R.id.btn_register)
    Button mBtnRegister;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
    }

    @OnClick({R.id.btn_send})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_send:
                Intent intent = new Intent();
                //注意setAction與AndroidManifest中的action對應
                intent.setAction("com.toly1994.aii_broadcastreceiver.StaticBR");
                intent.putExtra("msg" , "張風捷特烈");
                sendBroadcast(intent);
                break;
        }
    }
}
靜態註冊廣播接受者:StaticBR.java
/**
 * 做者:張風捷特烈
 * 時間:2018/4/14:16:22
 * 郵箱:1981462002@qq.com
 * 說明:靜態註冊廣播接受者
 */
public class StaticBR extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        String msg = intent.getStringExtra("msg");
        ToastUtil.show(context, msg + "\n第一個簡單廣播建立成功!");
    }
}
靜態註冊:app/src/main/AndroidManifest.xml
<receiver android:name=".StaticBR">
            <intent-filter>
                <action android:name="com.toly1994.aii_broadcastreceiver.MyBroadcastReceiver"/>
            </intent-filter>
        </receiver>
經測試,Android8.0沒法收到靜態廣播,Android7.0能夠法收到靜態廣播
靜態註冊一大好處是能夠跨程序使用,A程序中的BroadcastReceiver能夠在B程序中使用
Android8.0靜態廣播解決方案:intent.setComponent(new ComponentName(包全名,類全名))
intent.setComponent(new ComponentName("com.toly1994.aii_broadcastreceiver",
                        "com.toly1994.aii_broadcastreceiver.StaticBR"));

2、動態註冊

在未註冊以前,點擊發送無效果,在註冊後點擊發送有效果,在註銷以後點擊無效果。
點擊的三個核心代碼見下。

動態註冊廣播.gif

註冊方法:
IntentFilter filter = new IntentFilter();
filter.addAction("com.toly1994.aii_broadcastreceiver.register");
mReceiver = new StaticBR();
registerReceiver(mReceiver, filter);
發送方法:
Intent intent = new Intent();
//注意setAction與AndroidManifest中的action對應
intent.setAction("com.toly1994.aii_broadcastreceiver.register");
intent.putExtra("msg", "張風捷特烈");
sendBroadcast(intent);
註銷方法:
if (mReceiver != null) {
    unregisterReceiver(mReceiver);
    mReceiver = null;
}
附錄:佈局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/btn_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="16dp"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:text="發送廣播"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/btn_unregister"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="16dp"
        android:text="註銷廣播"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/btn_register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="註冊廣播"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

3、安卓基礎之BroadcastReceiver有序廣播

先講個場景小故事:
從前,有個小男孩撿到一顆漂亮的石頭,他想去賣,價格1元。
男孩(Boy)大喊:"我有一個漂亮的石頭,只賣1元",一個石匠買了這個石頭。
石匠(Stonemason)大喊:"我有一個漂亮的石頭,只賣1000元。"一個雕刻家買了這個石頭。
雕刻家(Graver)大喊:"我有一個漂亮的石頭,只賣10w元。"一個寶石家買了這個石頭。
寶石家(RubyMan)大喊:"我有一個漂亮的石頭,只賣1000w元。"收藏家買了這個石頭。
收藏家(Collector)不喊了,靜靜地收藏起來。男孩用一元買了一個棒棒糖,開心地吃着。故事結束。

按照這個順序,只要某我的不喊了,任何一個環節均可以被打斷,而致使石頭的價格出現差別。這就是有序廣播的做用。

有序廣播.gif

1.男孩廣播接收者:BR1_Boy.java
public class BR1_Boy extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到發送廣播攜帶的數據
        String content = getResultData();
        //[2]展現到Toast上
        Toast.makeText(context, "男孩:" + content, Toast.LENGTH_LONG).show();
//        [2.1]終止廣播
//        abortBroadcast();
        //[3]傳遞數據
        setResultData("我有一個漂亮的石頭,只賣1000元");
    }
}
2.石匠廣播接收者:BR2_Stonemason.java
public class BR2_Stonemason extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到發送廣播攜帶的數據
        String content = getResultData();
        //[2]展現到Toast上
        Toast.makeText(context, "石匠:" + content, Toast.LENGTH_LONG).show();
//        [2.1]終止廣播
//        abortBroadcast();
        //[3]傳遞數據
        setResultData("我有一個漂亮的石頭,只賣10W元");
    }
}
3.雕刻家廣播接收者:BR3_Graver.java
public class BR3_Graver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到發送廣播攜帶的數據
        String content = getResultData();
        //[2]展現到Toast上
        Toast.makeText(context, "雕刻家:" + content, Toast.LENGTH_LONG).show();
//        [2.1]終止廣播
//        abortBroadcast();
        //[3]傳遞數據
        setResultData("我有一個漂亮的石頭,只賣1000W元");
    }
}
4.寶石家廣播接收者:BR4_RubyMan.java
public class BR4_RubyMan extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到發送廣播攜帶的數據
        String content = getResultData();
        //[2]展現到Toast上
        Toast.makeText(context, "寶石家:" + content, Toast.LENGTH_LONG).show();
//        [2.1]終止廣播
//        abortBroadcast();
        //[3]傳遞數據
        setResultData("我有一個漂亮的石頭,價值1000W元");
    }
}
5.收藏家廣播接收者:BR5_Collector.java
/**
 * 最終的receiver 不須要再清單文件裏面配置
 */
public class BR5_Collector extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String content = getResultData();
        Toast.makeText(context, "收藏家:" + content, Toast.LENGTH_LONG).show();
    }
}
6.記得註冊:app/src/main/AndroidManifest.xml
<receiver android:name=".stone.BR1_Boy"></receiver>
<receiver android:name=".stone.BR2_Stonemason"></receiver>
<receiver android:name=".stone.BR3_Graver"></receiver>
<receiver android:name=".stone.BR4_RubyMan"></receiver>

7.StoneStoryActivity.java
public class StoneStoryActivity extends AppCompatActivity {

    @BindView(R.id.id_btn_send)
    Button mIdBtnSend;
    @BindView(R.id.id_btn_reg)
    Button mIdBtnReg;
    private BR1_Boy mBr1_boy;
    private BR2_Stonemason mBr2_stonemason;
    private BR3_Graver mBr3_graver;
    private BR4_RubyMan mBr4_rubyMan;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_story);
        ButterKnife.bind(this);
    }

    @OnClick({R.id.id_btn_send, R.id.id_btn_reg})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.id_btn_send:
                Intent intent_order = new Intent();
                intent_order.setAction("www.toly1994.com");
                sendOrderedBroadcast(intent_order, null,
                        new BR5_Collector(), null, 1, 
                        "我有一個漂亮的石頭,只賣1元", null);
                break;
            case R.id.id_btn_reg://動態註冊全部
                IntentFilter filter = new IntentFilter();
                filter.addAction("www.toly1994.com");
                mBr1_boy = new BR1_Boy();
                mBr2_stonemason = new BR2_Stonemason();
                mBr3_graver = new BR3_Graver();
                mBr4_rubyMan = new BR4_RubyMan();
                registerReceiver(mBr1_boy, filter);
                registerReceiver(mBr2_stonemason, filter);
                registerReceiver(mBr3_graver, filter);
                registerReceiver(mBr4_rubyMan, filter);
                break;
        }
    }
}

有序廣播.png

8.若是石匠截斷,不喊了,直接賣給收藏家
public class BR2_Stonemason extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到發送廣播攜帶的數據
        String content = getResultData();
        //[2]展現到Toast上
        Toast.makeText(context, "石匠:" + content, Toast.LENGTH_LONG).show();
//        [2.1]終止廣播
        abortBroadcast();
        //[3]傳遞數據
        setResultData("我有一個漂亮的石頭,價值1000元");
    }
}
附錄、activity_story.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StoneStoryActivity">

    <Button
        android:id="@+id/id_btn_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="發送廣播"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <Button
        android:id="@+id/id_btn_reg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginTop="8dp"
        android:text="註冊全部廣播"
        app:layout_constraintBottom_toBottomOf="@+id/id_btn_send"
        app:layout_constraintStart_toEndOf="@+id/id_btn_send"
        app:layout_constraintTop_toTopOf="@+id/id_btn_send"
        app:layout_constraintVertical_bias="1.0"/>
</android.support.constraint.ConstraintLayout>

4、BroadcastReceiver實現鎖、開屏、短信監聽

1.按電源鍵,屏幕鎖屏,再按電源鍵屏幕打開。在Activity開啓時註冊廣播用來監聽屏幕的關閉,Activity關閉時移除廣播。
2.這裏只能在該Activity中監聽,退出後BroadcastReceiver被註銷,後面將會結合Service加強應用範圍
3.後面也會結合傳感器進行搖晃開屏,暗環境鎖屏功能
4.短信監聽,能夠當收到短信時處理,好比提醒、備份、上傳網絡、刪除、自動回覆等

BroadcastReceiver實現鎖屏及開屏監聽.gif

1:InnerActivity.java
public class InnerActivity extends AppCompatActivity {
    private ScreenReceiver mScreenReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gary);
        ButterKnife.bind(this);
        regist();
    }

    /**
     * 動態的去註冊屏幕解鎖和鎖屏的廣播
     */
    private void regist() {
        // [1]動態的去註冊屏幕解鎖和鎖屏的廣播
        mScreenReceiver = new ScreenReceiver();
        // [2]建立intent-filter對象
        IntentFilter filter = new IntentFilter();
        // [3]添加要註冊的action
        filter.addAction("android.intent.action.SCREEN_OFF");
        filter.addAction("android.intent.action.SCREEN_ON");
        // [4]註冊廣播接收者
        registerReceiver(mScreenReceiver, filter);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //當activity銷燬的時候  取消註冊廣播接收者
        unregisterReceiver(mScreenReceiver);
    }
}
2:廣播接收者:ScreenReceiver.java
public class ScreenReceiver extends BroadcastReceiver {

    private static final String TAG = "ScreenReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取到當前廣播的事件類型
        String action = intent.getAction();
        //[2]對當前廣播事件類型作一個判斷
        if ("android.intent.action.SCREEN_OFF".equals(action)) {
            Log.i(TAG, "屏幕鎖屏了");
        } else if ("android.intent.action.SCREEN_ON".equals(action)) {
            Log.i(TAG, "屏幕解鎖了");
        }
    }
}

短信監聽
一、InnerActivity#regist
//註冊短信廣播接收者
IntentFilter smsFilter = new IntentFilter();
smsFilter.addAction("android.provider.Telephony.SMS_RECEIVED");
mSmsReceiver = new SmsReceiver();
registerReceiver(mSmsReceiver, smsFilter);
二、InnerActivity#onDestroy
unregisterReceiver(mSmsReceiver);//註銷短信廣播接收者
三、短信廣播接收者:SmsReceiver.java
public class SmsReceiver extends BroadcastReceiver {

    //當短信到來的時候 就會執行這個方法
    @Override
    public void onReceive(Context context, Intent intent) {
        //[1]獲取發短信送的號碼  和內容
        Object[] objects = (Object[]) intent.getExtras().get("pdus");
        for (Object pdu : objects) {
            //[2]獲取smsmessage實例
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
            //[3]獲取發送短信的內容
            String body = smsMessage.getMessageBody();
            Date date = new Date(smsMessage.getTimestampMillis());//時間
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //[4]獲取發送者
            String address = smsMessage.getOriginatingAddress();
            String receiveTime = format.format(date);
            Log.e("SmsReceiver", "body:" + body + "---" + address+"---"+receiveTime);
        }
    }
}
四、添加權限
<!--添加權限-->
    <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
    <uses-permission android:name="android.permission.READ_SMS"></uses-permission>
五、安卓5.1,實驗結果以下:(6.0以上注意動態權限)
E/SmsReceiver: body:hello---+8613167727310---2018-08-24 21:50:13

後記、

1.聲明:
1.本文由張風捷特烈原創,轉載請註明
2.歡迎廣大編程愛好者共同交流
3.我的能力有限,若有不正之處歡迎你們批評指證,一定虛心改正
4.看到這裏,感謝你的喜歡與支持
2.鏈接傳送門:

更多安卓技術歡迎訪問:安卓技術棧
個人github地址:歡迎star
張風捷特烈我的網站:http://www.toly1994.comjava

3.聯繫我
QQ:1981462002 郵箱:1981462002@qq.com 微信:zdl1994328
相關文章
相關標籤/搜索