Android 取消靜態註冊的BroadcastReceiver
阿新 • • 發佈:2019-02-20
大家都知道,關於Android廣播事件的註冊有兩種方式。1:在程式碼中動態註冊;2:在Manifest中的靜態註冊。
本文主要討論怎麼取消 靜態註冊的廣播
經過查詢資料發現,可以利用PackageManager中的setComponentEnableSetting()這個函式來解決這個問題,對於setComponetEnableSetting()這個函式的描述在官方文件中如是說:
-
/** * Set the enabled setting for a package component (activity, receiver, service, provider). * This setting will override any enabled state which may have been set by the component in its
意思簡單來說就是,能夠使四大元件從enable轉化為disabled;
第一個引數是一個ComponentName()物件,指定你要設定的元件的名字和所在的報名;
第二個引數newState這個引數來決定如何轉換;
第三個引數flags表示行為,有兩種不同的行為,如果設定為DONT_KILL_APP那麼在呼叫PackageManager.setComponentEnableSetting()設定Manifest.xml的時候就不至於殺死APP,反之就是0,這個時候你在設定就會出現閃退,因為這個時候已經把APP殺死了。
下面用一個例子來說明:
MainActivity.Java:
-
package com.example.testbroadcastreceiver; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import java.util.Timer; import java.util.TimerTask; public class MainActivity extends AppCompatActivity { private Button sendButton; private Button cancelButton; private Button resumeButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendButton = (Button) findViewById(R.id.sendButton); cancelButton = (Button) findViewById(R.id.cancelButton); resumeButton = (Button) findViewById(R.id.resumeButton); } TimerTask task = new TimerTask() { @Override public void run() { //建立Intent物件,action為ELITOR_CLOCK,” Intent intent = new Intent("ELITOR_CLOCK"); intent.putExtra("msg", "time over!"); sendBroadcast(intent); } }; public void myOnclick(View view){ switch (view.getId()){ case R.id.sendButton: Timer timer = new Timer(); timer.schedule( task , 1000, 9000); break; case R.id.cancelButton: //取消靜態註冊的廣播 getPackageManager().setComponentEnabledSetting( new ComponentName("com.example.testbroadcastreceiver", MyBroadcastReceiver.class.getName()), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); break; case R.id.resumeButton: //這個地方因為當你點選 cancelButton 按鈕使靜態註冊的廣播disabled之後,下次進來的時候廣播就不能用了,相當於修改了Manifest中 靜態廣播註冊中的 android:enabled="false", //這個地方還原成default,也就是在Manifest中設定的預設值(android:enable="true") getPackageManager().setComponentEnabledSetting( new ComponentName("com.example.testbroadcastreceiver" , MyBroadcastReceiver.class.getName()), PackageManager.COMPONENT_ENABLED_STATE_DEFAULT, PackageManager.DONT_KILL_APP); break; } } @Override protected void onDestroy() { super.onDestroy(); if( null != task){ task.cancel(); task = null; } } }
MyReceiver.java:
-
package com.example.testbroadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import android.widget.Toast; public class MyReceiver extends BroadcastReceiver { public MyReceiver(){ } @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String action = intent.getAction(); Log.e("TAG","action= " + action); if( action == "ELITOR_CLOCK"){ String msg = intent.getStringExtra("msg"); Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); } } }
mStaBroadcastReceiver.java
- package com.example.broadcasttest;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- publicclass mStaBroadcastReceiver extends BroadcastReceiver {
- @Override
- publicvoid onReceive(Context context, Intent intent) {
- MainActivity.tv.append("\n" + "mStaBroadcastReceiver=>"
- + intent.getAction().toString());
- }
- }
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" android:orientation="vertical" tools:context="com.example.testbroadcastreceiver.MainActivity"> <Button android:id="@+id/sendButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="myOnclick" android:text="Send BroadcastReceiver"/> <Button android:id="@+id/cancelButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:onClick="myOnclick" android:text="Cancel BroadcastReceiver"/> <Button android:id="@+id/resumeButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:onClick="myOnclick" android:text="恢復 BroadcastReceiver"/> </LinearLayout>
在AndroidManifest.xml中註冊一下要靜態註冊的廣播
-
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.testbroadcastreceiver" > <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> <!-- 靜態註冊 --> <receiver android:name="com.example.testbroadcastreceiver.MyBroadcastReceiver" android:enabled="true"> <intent-filter > <action android:name="ELITOR_CLOCK" /> </intent-filter> </receiver> </application> </manifest>