大家都知道,关于Android广播事件的注册有两种方式,一种是在代码中静态注册,一种呢是写在Manifest中的静态注册,在这我就不跟大家罗嗦,如何
静态注册,如何动态注册了,相信大家也知道。
大家有没有考虑过这个问题,但用户设置不要监听这个广播了,该如何是好的。
最简单的方法就是还是照样监听,只不过收到广播之后不再执行对应的动作了,对用户来说,就跟没监听到广播一样,那么还有其他的方法吗?
对于动态注册来说,如果要取消注册事件,不想再监听这个事件了,只需要动态的unregister掉就ok了,那么静态注册呢?
今天经过我的研究,可以利用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.Parameters
<span style="font-size:14px;color:#CC0000;">componentName </span> The component to enable
<span style="color:#CC0000;"><span style="font-size:14px;">newState</span> </span> The new enabled state for the component. The legal values for this state are: COMPONENT_ENABLED_STATE_ENABLED,
COMPONENT_ENABLED_STATE_DISABLED and
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).
<span style="font-size:14px;color:#CC0000;">flags </span> Optional behavior flags: 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.broadcasttest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
public static TextView tv;
public static final String Dyn_Action = "dyn_action";
public static final String Sta_Action = "sta_action";
public static final String Sys_Action = Intent.ACTION_POWER_CONNECTED;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
<span style="color:#CC0000;"> getPackageManager().setComponentEnabledSetting(
new ComponentName("com.example.broadcasttest",
mStaBroadcastReceiver.class.getName()),
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
PackageManager.DONT_KILL_APP)</span>;//这个地方因为当你点击按钮使静态注册的广播disabled之后,下次进来的时候广播就不能用了,相当于已经
} //修改了Manifest了,这个地方还原成default,也就是之前在Manifest中设置的默认值(enable="true")
@Override
protected void onStart() {
super.onStart();
IntentFilter mDynIntentFilter = new IntentFilter();
mDynIntentFilter.addAction(Dyn_Action);
registerReceiver(mDynBroadcast, mDynIntentFilter);
IntentFilter mDyn_Sys_IntentFilter = new IntentFilter();
mDyn_Sys_IntentFilter.addAction(Sys_Action);
registerReceiver(mDyn_Sys_Broadcast, mDyn_Sys_IntentFilter);
}
public void onClick(View view) {
Intent intent = new Intent();
switch (view.getId()) {
case R.id.dynbtn:
intent.setAction(Dyn_Action);
sendBroadcast(intent);
break;
case R.id.stabtn:
intent.setAction(Sta_Action);
sendBroadcast(intent);
break;
case R.id.disenablesta:
getPackageManager().setComponentEnabledSetting(
new ComponentName("com.example.broadcasttest",
mStaBroadcastReceiver.class.getName()),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
break;
}
}
private BroadcastReceiver mDynBroadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
tv.append("\n");
tv.append("mDynBroadcast=>" + intent.getAction().toString());
}
};
private BroadcastReceiver mDyn_Sys_Broadcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
tv.append("\n");
tv.append("mDyn_Sys_Broadcast=>" + intent.getAction().toString());
}
};
}mSta_Sys_BroadcastReceiver.java:
package com.example.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class mSta_Sys_BroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
MainActivity.tv.append("\n" + "mSta_Sys_BroadcastReceiver=>"
+ intent.getAction().toString());
}
}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());
}
}
layout_main.xml:
<RelativeLayout 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"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/dynbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:onClick="onClick"
android:text="SendDynamicBro" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />
<Button
android:id="@+id/stabtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/tv"
android:layout_alignParentLeft="true"
android:layout_marginBottom="38dp"
android:onClick="onClick"
android:text="SendStaticBro" />
<Button
android:id="@+id/disenablesta"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/stabtn"
android:layout_alignParentLeft="true"
android:layout_marginBottom="15dp"
android:onClick="onClick"
android:text="DisabledStaBro" />
</RelativeLayout>
在AndroidManifest.xml中注册一下要静态注册的广播;
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcasttest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".mSta_Sys_BroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
</intent-filter>
</receiver>
<receiver
android:name=".mStaBroadcastReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="sta_action" />
</intent-filter>
</receiver>
</application>
</manifest>
经过测试之后发现,同过PackageManager取消注册之后,能够使静态注册的广播失效,就跟修改了Manifest中的配置一样(我感觉是这样的),下次进来如果不进行重新的注册(MainActivity.java中的红色的部分),广播依旧不会有作用,也就是如果去掉MainActivity.java中的红色的部分只要点击一次取消注册的按钮,那么以后无论App重启还是怎么样,该静态注册的广播一直失效。
好了差不多笔记就写这么多了。
PS:PackageManager这个类中还有很多好玩的函数,有兴趣的可以看一下。
本文探讨如何在用户不需要监听广播时取消Android静态注册的广播事件。除了不执行广播接收器的动作,还可以使用PackageManager的setComponentEnableSetting()函数来实现。通过设置ComponentName和enableState,可以达到类似修改Manifest的效果,使静态注册广播失效。动态注册时,可通过unregisterReceiver()取消监听。此外,文章还提示PackageManager类包含更多有趣的功能可供探索。
623





