天天看點

android之旅15 廣播與廣播接收者: 接收系統廣播

  • 廣播的意義其實就是告訴多個APP同一事件,是普通一對一事件的擴充
  • 電量改變、收發短信、開機、電話、螢幕解鎖等,都是廣播
  • 廣播接收者是四大元件之一。注意不是廣播
  • 四大元件的都要在清單檔案manifest檔案中定義,注意和Activity同級
  • 注意權限的問題,接收打電話、短信侵犯了隐私
  • 廣播實際上是先發一條廣播,廣播接收者先收到廣播,可以修改廣播資料,最後發給實際生效的Activity
  • 廣播存活的程序就是部署所在的application,即使該程序被殺死了,當廣播發出時,系統會啟動這個程序,然後發廣播給該程序。 這種監測者的實作方式是為了給系統節省資源,沒必要一直開着這種監測程序
  • 如果廣播接收者程序是使用者手動關閉(app info下的FORCE STOP,見下圖),那就不會再次啟動,4.0之後的特性
  • 廣播實際上也是通過Intent發送的
  • 廣播接收者程序如果從來沒有啟動過,4.0以後就不會生效
    android之旅15 廣播與廣播接收者: 接收系統廣播

電話短信接收者

<application>
    <activity>
    </activity>
    <receiver android:name="packageName.ClassName">
        <intent-filter>
        <action ---- 指定接收什麼類型的廣播,這裡值是表示往外打電話的廣播
        android:name="android.intent.action.NEW_OUTGOING_CALL"/>   
        </intent-filter>
    </receiver>
    <receiver android:name="packageName.ClassName">
        <intent-filter android:priority="1000"> -- 定義優先級,優先級[-1000,1000]
        <action ---- 接收收短信的廣播,這個不提示,操蛋
        android:name="android.provider.Telephony.SMS_RECEIVED"/>   
        </intent-filter>
    </receiver>

</application>
           
// 電話接收者
public class CallReceiver extends BroadcastReceiver{
    public void onReceive(Context c, Intent intent){
        // 會帶過來撥打的電話号碼
        String number = getResultData();

        //廣播接收者不是Context子類,是以把Context傳進來
        String str1 = context.getSharedPreferences("ip", Context.MODE_PRIVATE).getString("str1");
        number = str1+number;
        setResultData(number); //将資料設定給廣播
    }   
}
           
// 短信接收者
public class SmsReceiver extends BroadcastReceiver{
    public void onReceiver(Context context Intent intent){
        Bundle bundle = intent.getExtras();
         //短信的抽象叫做pdus, pdu是協定資料單元,每個object表示一條短信
        Object[] objects = bundle.get("pdus");
        for(Object o : objects){//多條短信原因:内容超過營運商規定長度
            SmsMessage sms = SmsMessage.createFromPdu((byte[])o);
            //sms就是短信的所有東西。。包括位址,短信内容等
            if (sms.getOriginatingAddress().equals("39393")){
            //短信應用和短信是兩回事,收到短信這個事件會發廣播,
            //短信應用收到廣播然後顯示出來
                abortBroadcast(); //丢棄廣播,低優先級接收者就收不到了
            }
        }
    }
}
           

SD卡狀态廣播接收

  • 廣播也是通過Intent傳遞的,SD卡廣播定義的時候就有data,是以需要完全比對,是以定義了一個data
<!--同一個Receiver接收多個廣播的寫法-->
<intent-filter>
   <action android:name="android.intent.action.MEDIA_MOUNTED"/>
   <action android:name="android.intent.action.MEDIA_REMOVED"/>
   <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
   <data android:scheme="file"/>
</intent-filter>
           
public class SDCardCast extends BroadcastReceiver{
    public void onReceive(Context context, Intent){
        String str = intent.getAction();
        if ("android.intent.action.MEDIA_MOUNTED".equals(str)){

        }else if(){
            //業務邏輯.......
        }
    }
}
           

開機廣播接收者

// BOOT_COMPLETED是廣播Action的名字
public class BootReceiver extends BroadcastReceiver{
    public void onReceive(Context context, Intent intent){
        Intent it = new Intent(context, XXX.class);
        //在context外部啟動Activity必須設定這個flag,實際就是建立一個新的Activity棧
        it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(it);
    }
}
           

應用狀态廣播

  • 應用狀态有三種:安裝、更新、解除安裝
// PACKAGE_ADDED\PAGEAGE_REMOVED\PACKAGE_REPLACED
//intent-fliter還要定義一個data android:scheme="package"
public class AppStatusReceiver extends BroadcastReceiver{
    public void onReceive(Context c, Intent it){
        String action = it.getAction();
        Uri uri = it.getData();
        if (action.equals("PACKAGE_ADDED")){
            System.out.println(uri.toString());
        }else if(){
            /*
                其他邏輯.....
            */
        }
    }
}
           
  • 總結下:
  • 定義類繼承BroadcastReceiver
  • manifest中定義Receiver,并通過intent-filter中的action定義接收廣播類型
  • 權限添加