大家都知道,关于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
* manifest.
*
* @param componentName The component to enable
* @param newState The new enabled state for the component. The legal values for this state
* are:
* { @link #COMPONENT_ENABLED_STATE_ENABLED},
* { @link #COMPONENT_ENABLED_STATE_DISABLED}
* and
* { @link #COMPONENT_ENABLED_STATE_DEFAULT}
* The last one removes the setting, thereby restoring the component's state to
* whatever was set in it's manifest (or enabled, by default).
* @param flags Optional behavior flags: { @link #DONT_KILL_APP} or 0.
意思简单来说就是,能够使四大组件从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; public class mStaBroadcastReceiver extends BroadcastReceiver { @Override public void 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 >