今天要讨论的是:在Android手机上如何根据用户的设置来决定是否在开机时启动应用程序。这句话不知道怎么说才能通顺,就先详细说一下要解决的问题吧。
我们都知道要让应用程序在开机时启动,首先是在manifest中添加权限,注册receiver,给receiver添加action,然后在receiver的onReceive方法中启动一个service或者activity。
如果某个应用程序想让用户决定是不是在开机时启动,用户选择是,这个应用程序就接收boot completed 广播,用户选择否,这个程序就不接收boot completed广播。可是由于receiver是注册在manifest文件中,怎样让它在手机启动时不响应boot completed广播了。
有人说在onReceive方法中检查SharedPreferences,这是不对的,即使它执行完onReceive后就结束了,但它毕竟是启动了。
解决的方法是使用PackageManager,然后调用它的setComponentEnabledSetting方法,这个方法可以让一个组件失效或者生效,如果让这个receiver失效了,他就接收不到广播了,当然让它生效了,就能接收到广播了。
先贴代码片段
首先是权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
接着注册receiver
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
然后是onReceiver方法,我选择启动一个Activity测试
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Toast.makeText(context, "receive boot completed", Toast.LENGTH_LONG).show();
Intent start = new Intent(context, DisableReceiverInCodeActivity.class);
start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(start);
}
}
主界面是DisableReceiverInCodeActivity,布局文件中有个checkbox,当checkbox选中,就在开机时启动这个程序,否则不启动。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start on boot complete">
</TextView>
<CheckBox android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/boot_complete_checkbox"/>
</LinearLayout>
</LinearLayout>
然后是checkbox的事件和处理
public class DisableReceiverInCodeActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final CheckBox bootCheck = (CheckBox) findViewById(R.id.boot_complete_checkbox);
final ComponentName cm = new ComponentName("com.rsft.test.demo1", "com.rsft.test.demo1.MyReceiver");
final PackageManager pm = getPackageManager();
int state = pm.getComponentEnabledSetting(cm);
if (state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
&& state != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
bootCheck.setChecked(true);
}
bootCheck
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
int newState = bootCheck.isChecked() ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
pm.setComponentEnabledSetting(cm, newState,
PackageManager.DONT_KILL_APP);
}
});
}
}
然后就结束了,简单说一下ComponentName cm = new ComponentName("com.rsft.test.demo1", "com.rsft.test.demo1.MyReceiver") 这个东西前面是程序的包名,后面是组件的类名,我的是一个receiver,注意类名一定得是全名,就是包名+类名的方式。
再说一下pm.setComponentEnabledSetting(cm, newState,
PackageManager.DONT_KILL_APP); 这个就是让一个组件失效或者生效的方法,第一个参数是组件,第二个是你要设置的状态,查查文档就知道有哪些状态,第三个参数可设置的值只有两个,具体看看文档。
工程文件的下载地址我会写在评论里面,欢迎下载。
谢谢阅读
若水飞天
还有代码下载
http://download.csdn.net/detail/huihuangui/4323364