Android開發-Broadcast廣播接收者

  • 2017-1-5 14:25
  • PHP二次開發
  • 閱讀(1915)
  • 評論(2
  • 來源:互聯網
  • 摘要: 現實中:電臺要發布消息,通過廣播把消息廣播出去,使用收音機,就可以收聽廣播,得知這條消息。Android中:系統在運行過程中,會產生許多事件,那么某些事件產生時,比如:電量改變、收發短信、撥打電話、屏幕解鎖 ...
    現實中:電臺要發布消息,通過廣播把消息廣播出去,使用收音機,就可以收聽廣播,得知這條消息。
    Android中:系統在運行過程中,會產生許多事件,那么某些事件產生時,比如:電量改變、收發短信、撥打電話、屏幕解鎖、開機,系統會發送廣播。

                      只要應用程序接收到這條廣播,就知道系統發生了相應的事件,從而執行相應的代碼。使用廣播接收者,就可以收聽廣播。
                      系統中任何應用只要注冊了對應了Receiver,就會接收到此Broadcast。

    ###創建廣播接收者
    1. 定義java類繼承BroadcastReceiver
    2. 在清單文件中定義receiver節點,定義name屬性,指定廣播接收者java類的全類名
    3. 在intent-filter的節點中,指定action子節點,action的值必須跟要接受的廣播中的action匹配,比如,如果要接受打電話廣播,
    那么action的值必須指定為
            <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
    * 因為打電話廣播中所包含的action,就是"android.intent.action.NEW_OUTGOING_CALL",所以我們定義廣播接收者時,
      action必須與其匹配,才能收到這條廣播
    * 即便廣播接收者所在進程已經被關閉,當系統發出的廣播中的action跟該廣播接收者的action匹配時,系統會啟動該廣播接收者所在的進程,
      并把廣播發給該廣播接收者。

     使用服務注冊廣播接收者
    * Android四大組件都要在清單文件中注冊
    * 廣播接收者比較特殊,既可以在清單文件中注冊,也可以直接使用代碼注冊
    * 有的廣播接收者,必須代碼注冊
        * 電量改變
        * 屏幕鎖屏和解鎖

    * 注冊廣播接收者

            //創建廣播接收者對象
            receiver = new ScreenOnOffReceiver();
            //通過IntentFilter對象指定廣播接收者接收什么類型的廣播
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(Intent.ACTION_SCREEN_ON);
            
            //注冊廣播接收者
            registerReceiver(receiver, filter);
    * 解除注冊廣播接收者

            unregisterReceiver(receiver);
    * 解除注冊之后,廣播接收者將失去作用

    小案例:

    #IP撥號器
    > 原理:接收撥打電話的廣播,修改廣播內攜帶的電話號碼
    * 定義廣播接收者接收打電話廣播
        public class CallReceiver extends BroadcastReceiver {
            //當廣播接收者接收到廣播時,此方法會調用
            @Override
            public void onReceive(Context context, Intent intent) {
                //拿到用戶撥打的號碼
                String number = getResultData();
                //修改廣播內的號碼
                setResultData("17951" + number);
            }
        }
    * 在清單文件中定義該廣播接收者接收的廣播類型

            <receiver android:name="com.itheima.ipdialer.CallReceiver">
                <intent-filter >
                    <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
                </intent-filter>
            </receiver>
    * 接收打電話廣播需要權限

            <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    * 即使廣播接收者的進程沒有啟動,當系統發送的廣播可以被該接收者接收時,系統會自動啟動該接收者所在的進程。

     

    #短信攔截器
    >系統收到短信時會產生一條廣播,廣播中包含了短信的號碼和內容

    * 系統發送短信廣播時,是怎么把短信內容存入廣播的,我們就只能怎么取出來
    * 如果短信過長,那么發送時會拆分成多條短信發送,那么短信廣播中就會包含多條短信
    * 定義廣播接收者接收短信廣播
            public void onReceive(Context context, Intent intent) {
            //拿到廣播里攜帶的短信內容
            Bundle bundle = intent.getExtras();
            Object[] objects = (Object[]) bundle.get("pdus");
            for(Object ob : objects ){
                //通過object對象創建一個短信對象
                SmsMessage sms = SmsMessage.createFromPdu((byte[])ob);
                System.out.println(sms.getMessageBody());
                System.out.println(sms.getOriginatingAddress());
            }
        }
    * 系統創建廣播時,把短信存放到一個數組,然后把數據以pdus為key存入bundle,再把bundle存入intent
    * 清單文件中配置廣播接收者接收的廣播類型,注意要設置優先級屬性,要保證優先級高于短信應用,才可以實現攔截
            <receiver android:name="com.itheima.smslistener.SmsReceiver">
                <intent-filter android:priority="1000">
                    <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
                </intent-filter>
            </receiver>
    * 添加權限
            <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    * 4.0以后廣播接收者安裝以后必須手動啟動一次,否則不生效
    * 4.0以后廣播接收者如果被手動關閉,就不會再啟動了

     

    #監聽SD卡狀態
    * 清單文件中定義廣播接收者接收的類型,監聽SD卡常見的三種狀態,所以廣播接收者需要接收三種廣播
             <receiver android:name="com.itheima.sdcradlistener.SDCardReceiver">
                <intent-filter >
                    <action android:name="android.intent.action.MEDIA_MOUNTED"/>
                    <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
                    <action android:name="android.intent.action.MEDIA_REMOVED"/>
                    <data android:scheme="file"/>
                </intent-filter>
            </receiver>
    * 廣播接收者的定義

            public class SDCardReceiver extends BroadcastReceiver {
                @Override
                public void onReceive(Context context, Intent intent) {
                    // 區分接收到的是哪個廣播
                    String action = intent.getAction();
                        
                    if(action.equals("android.intent.action.MEDIA_MOUNTED")){
                        System.out.println("sd卡就緒");
                    }
                    else if(action.equals("android.intent.action.MEDIA_UNMOUNTED")){
                        System.out.println("sd卡被移除");
                    }
                    else if(action.equals("android.intent.action.MEDIA_REMOVED")){
                        System.out.println("sd卡被拔出");
                    }
                }
            }

     


    #勒索軟件
    * 接收開機廣播,在廣播接收者中啟動勒索的Activity
    * 清單文件中配置接收開機廣播

            <receiver android:name="com.itheima.lesuo.BootReceiver">
                <intent-filter >
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
            </receiver>
    * 權限

            <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    * 定義廣播接收者

            @Override
            public void onReceive(Context context, Intent intent) {
                //開機的時候就啟動勒索軟件
                Intent it = new Intent(context, MainActivity.class);        
                context.startActivity(it);
            }
    * 以上代碼還不能啟動MainActivity,因為廣播接收者的啟動,并不會創建任務棧,那么沒有任務棧,就無法啟動activity
    * 手動設置創建新任務棧的flag

            it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


    #監聽應用的安裝、卸載、更新
    > 原理:應用在安裝卸載更新時,系統會發送廣播,廣播里會攜帶應用的包名
    * 清單文件定義廣播接收者接收的類型,因為要監聽應用的三個動作,所以需要接收三種廣播

            <receiver android:name="com.itheima.app.AppReceiver">
                <intent-filter >
                    <action android:name="android.intent.action.PACKAGE_ADDED"/>
                    <action android:name="android.intent.action.PACKAGE_REPLACED"/>
                    <action android:name="android.intent.action.PACKAGE_REMOVED"/>
                    <data android:scheme="package"/>
                </intent-filter>
            </receiver>
    * 廣播接收者的定義

            public void onReceive(Context context, Intent intent) {
                //區分接收到的是哪種廣播
                String action = intent.getAction();
                //獲取廣播中包含的應用包名
                Uri uri = intent.getData();
                if(action.equals("android.intent.action.PACKAGE_ADDED")){
                    System.out.println(uri + "被安裝了");
                }
                else if(action.equals("android.intent.action.PACKAGE_REPLACED")){
                    System.out.println(uri + "被更新了");
                }
                else if(action.equals("android.intent.action.PACKAGE_REMOVED")){
                    System.out.println(uri + "被卸載了");
                }
            }

     

    #廣播的兩種類型
    * 無序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,并且是沒有先后順序(同時收到)
    * 有序廣播:所有跟廣播的intent匹配的廣播接收者都可以收到該廣播,但是會按照廣播接收者的優先級來決定接收的先后順序
        * 優先級的定義:-1000~1000
        * 最終接收者:所有廣播接收者都接收到廣播之后,它才接收,并且一定會接收
        * abortBroadCast:阻止其他接收者接收這條廣播,類似攔截,只有有序廣播可以被攔截

    PHP技術交流QQ群:422137578

    除非注明,文章均為 PHP二次開發 原創,轉載請注明本文地址:http://www.fujvln.live/article-2546-1.html

    相關閱讀

    發表評論

    最新評論

    引用 斗獸棋下載   2019-4-12 09:12
    學習了
    引用 在家兼職網賺   2019-4-12 09:11
    感謝博主分享這么好的文章

    查看全部評論(2)

    用戶名:  *

    郵 箱:  *

    網 址: 注意加上“http://”哦!