Android关于如何取消静态注册的广播事件,你知道吗?

本文探讨如何在用户不需要监听广播时取消Android静态注册的广播事件。除了不执行广播接收器的动作,还可以使用PackageManager的setComponentEnableSetting()函数来实现。通过设置ComponentName和enableState,可以达到类似修改Manifest的效果,使静态注册广播失效。动态注册时,可通过unregisterReceiver()取消监听。此外,文章还提示PackageManager类包含更多有趣的功能可供探索。

大家都知道,关于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这个类中还有很多好玩的函数,有兴趣的可以看一下。

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值