1. 程式人生 > >Android 廣播(讓其他應用無法接收)

Android 廣播(讓其他應用無法接收)

android 廣播實現讓其他應用無法接受的廣播有兩種方法:

  1. 本地廣播
  2. 為廣播新增許可權

    本地廣播

    本地廣播:
    只在程式內部進行傳遞的廣播,傳送和接收都只在本程式有效。
    示例程式碼:

public class MainActivity extends AppCompatActivity {  
    private IntentFilter intentFilter;  
    private LocalReceiver localReceiver;  
    //本地廣播資料型別例項。  
    private LocalBroadcastManager localBroadcastManager;  


    @Override
public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); supportRequestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); //獲取本地廣播例項。 localBroadcastManager=LocalBroadcastManager.getInstance(this
); Button button=(Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent=new Intent("com.example.tangyi.receiver5.LOCAL_BROADCAST"); //傳送本地廣播。
localBroadcastManager.sendBroadcast(intent); } }); //新建intentFilter並給其action標籤賦值。 intentFilter=new IntentFilter(); intentFilter.addAction("com.example.tangyi.receiver5.LOCAL_BROADCAST"); //建立廣播接收器例項,並註冊。將其接收器與action標籤進行繫結。 localReceiver=new LocalReceiver(); localBroadcastManager.registerReceiver(localReceiver,intentFilter); } @Override public void onDestroy(){//在onDestroy()方法中取消註冊。 super.onDestroy(); //取消註冊呼叫的是unregisterReceiver()方法,並傳入接收器例項。 localBroadcastManager.unregisterReceiver(localReceiver); } class LocalReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context,Intent intent){ Toast.makeText(context,"這是本地廣播接收器",Toast.LENGTH_SHORT).show(); } } }

**本地廣播是無法通過靜態註冊來實現的。
因為靜態註冊是為了讓程式未啟動也能接收廣播。本地廣播是在本程式內進行
傳遞,肯定是已經啟動了,因此也完全不需要靜態註冊。**

給廣播新增許可權

在Android應用開發中,有時會遇到以下兩種情況,

  1. 一些敏感的廣播並不想讓第三方的應用收到 ;

  2. 要限制自己的Receiver接收某廣播來源,避免被惡意的同樣的ACTION的廣播所幹擾。

在這些場景下就需要用到廣播的許可權限制:

第一種場景: 誰有權收我的廣播?

在這種情況下,可以在自己應用發廣播時新增引數宣告Receiver所需的許可權。

首先,在Androidmanifest.xml中定義新的許可權RECV_XXX(自定義的許可權都需要先宣告),例如:

<permission android:name = "com.android.permission.RECV.XXX"/>

然後,在Sender app傳送廣播時將此許可權作為引數傳入,如下:

sendBroadcast("com.andoird.XXX_ACTION", "com.android.permission.RECV_XXX");

這樣做之後就使得只有具有permission許可權的Receiver才能接收此廣播要接收該廣播,在Receiver應用的AndroidManifest.xml中要新增對應的RECV_XXX許可權。
例如:

<users-permission android:name = "com.android.permission.RECV.XXX"/>

第二種場景: 誰有權給我發廣播?

在這種情況下,需要在Receiver app的 tag中宣告一下Sender app應該具有的許可權。

首先同上,在AndroidManifest.xml中定義新的許可權SEND_XXX,例如:

<permission android:name = "com.android.permission.SEND.XXX"/>

然後,在Receiver app的Androidmanifest.xml中的tag裡新增許可權SEND_XXX的宣告,如下:

<receiver android:name=".XXXReceiver"   
          android:permission="com.android.permission.SEND_XXX">   
    <intent-filter>  
         <action android:name="com.android.XXX_ACTION" />   
    </intent-filter>  
</receiver>

這樣一來,該Receiver便只能接收來自具有該send_permission許可權的應用發出的廣播。
要傳送這種廣播,需要在Sender app的AndroidManifest.xml中也宣告使用該許可權即可,如下:

<users-permission android:name = "com.android.permission.SEND.XXX"/>

動態註冊廣播新增許可權
第一步:自己定義許可權,並且使用自定義許可權

<uses-permission android:name="com.cn.customview.permissions.MY_BROADCAST" />

<permission
    android:name="com.cn.customview.permissions.MY_BROADCAST"
    android:protectionLevel="signature" >
</permission>

給這個應用程式定義了一個permissions並且uses-permission申明使用,這是這個應用就有了這個許可權,並且應用內部的註冊的動態廣播也擁有了這個許可權。

第二步:定義註冊廣播

    private static final String BROADCAST_PERMISSION_DISC = "com.cn.customview.permissions.MY_BROADCAST";
    private static final String BROADCAST_ACTION_DISC = "com.cn.customview.permissions.my_broadcast";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.broadcast_permissions_activity);
        ButterKnife.bind(this);
        // 註冊廣播接收
        BroadcastReceiver receiveBroadCast = new ReceiveBroadCast();
        IntentFilter filter = new IntentFilter();
        filter.addAction(BROADCAST_ACTION_DISC); // 只有持有相同的action的接受者才能接收此廣播
        registerReceiver(receiveBroadCast, filter,BROADCAST_PERMISSION_DISC,null);
    }

    public class ReceiveBroadCast extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(BroadcastPermissionsActivity.this,
                    "receive broadcast", 0).show();
        }

    }

註冊一個廣播,並且申明,這個廣播需要BROADCAST_PERMISSION_DISC許可權才能收到訊息。但是我們應用程式已經註冊了這個許可權。所以是有這個許可權的。

第三步: 傳送廣播

    @OnClick(R.id.btn_send_broadcast)
    public void sendBroadcastWithPermissions() {
        Intent intent = new Intent();  //Itent就是我們要傳送的內容
        intent.putExtra("data", "this is data from broadcast "+Calendar.getInstance().get(Calendar.SECOND));  
        intent.setAction(BROADCAST_ACTION_DISC);   //設定你這個廣播的action,只有和這個action一樣的接受者才能接受者才能接收廣播
        sendBroadcast(intent,BROADCAST_PERMISSION_DISC);   //傳送廣播
    }

代表接收訊息的廣播需要BROADCAST_PERMISSION_DISC許可權,其實跟上一種方式的定義效果一樣。

至此,安全檢查工具報錯消除。

注意:
1.registerReceiver(receiveBroadCast, filter,BROADCAST_PERMISSION_DISC,null);如果改為registerReceiver(receiveBroadCast, filter); 照樣能夠收到第三步傳送的訊息,因為我們在xml裡面已經申請了BROADCAST_PERMISSION_DISC許可權,所以sendBroadcast(intent,BROADCAST_PERMISSION_DISC);傳送廣播我們依然能收到。
2.sendBroadcast(intent,BROADCAST_PERMISSION_DISC); 改為sendBroadcast(intent);也同樣能收到這個訊息。因為第一個的意思是收到這個訊息的廣播監聽器必須有BROADCAST_PERMISSION_DISC許可權,如果第二個引數去掉,則說明廣播監聽器不需要任何許可權就能收到這個訊息。