Android 13 在 Settings 中添加开机启动应用功能

背景与需求场景

Android 13 进一步强化了隐私保护机制,对开机自启行为实施更严格的管控。系统级应用(如设备监控、厂商定制工具)需通过显式用户授权实现开机自启功能,需在 Settings 中提供配置入口以满足以下场景:

  • 系统服务类应用(电源管理、设备守护进程)
  • 实时监控应用(远程控制、健康检测)
  • OEM 定制化工具(车机/平板常驻服务)
核心实现机制

广播接收器注册 通过静态注册监听 BOOT_COMPLETED 广播,需在 AndroidManifest.xml 声明权限与接收器:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<receiver 
    android:name=".BootStartReceiver"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

广播处理逻辑 接收广播后从 SharedPreferences 读取用户预选应用并启动:

public class BootStartReceiver extends BroadcastReceiver {
    private static final String PREFS_NAME = "boot_app_prefs";
    private static final String KEY_SELECTED_APP = "selected_package";

    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            launchSelectedApp(context);
        }
    }

    private void launchSelectedApp(Context context) {
        String pkgName = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
                              .getString(KEY_SELECTED_APP, null);
        if (pkgName != null) {
            Intent launchIntent = context.getPackageManager()
                                       .getLaunchIntentForPackage(pkgName);
            if (launchIntent != null) {
                launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(launchIntent);
            }
        }
    }
}

Settings 集成方案

配置界面实现

  1. settings_preferences.xml 添加入口项:
<Preference
    android:key="boot_app_selection"
    android:title="@string/boot_app_title"
    android:fragment=".BootAppSelectionFragment" />

  1. 动态生成可启动应用列表:
public class BootAppSelectionFragment extends PreferenceFragmentCompat {
    private static final String PREFS_NAME = "boot_app_prefs";
    private String mSelectedPkg;

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        PreferenceScreen screen = getPreferenceManager().createPreferenceScreen(getContext());
        setPreferenceScreen(screen);

        PackageManager pm = getActivity().getPackageManager();
        Intent launcherIntent = new Intent(Intent.ACTION_MAIN)
                                .addCategory(Intent.CATEGORY_LAUNCHER);
        
        for (ResolveInfo info : pm.queryIntentActivities(launcherIntent, 0)) {
            AppInfo app = new AppInfo(info, pm);
            CheckBoxPreference pref = new CheckBoxPreference(getContext());
            pref.setTitle(app.label);
            pref.setIcon(app.icon);
            pref.setKey(app.packageName);
            pref.setOnPreferenceChangeListener((p, newValue) -> {
                if ((Boolean) newValue) {
                    mSelectedPkg = app.packageName;
                    saveSelection();
                }
                return true;
            });
            screen.addPreference(pref);
        }
        loadSelection();
    }

    private void saveSelection() {
        getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
                   .edit()
                   .putString(KEY_SELECTED_APP, mSelectedPkg)
                   .apply();
    }
}

兼容性注意事项
  1. 权限限制
    Android 8.0+ 禁止动态注册开机广播,必须使用静态注册
  2. 用户感知
    需在 UI 中明确提示"该应用将在开机时自动启动"
  3. 厂商适配
    系统签名应用可申请 START_ACTIVITIES_FROM_BACKGROUND 权限突破限制
性能优化建议
  • 延迟启动:通过 Handler.postDelayed() 避免开机时集中启动多个应用
  • 白名单机制:系统级集成时可配置包名白名单,绕过用户选择

优化要点:

  1. 统一术语:使用 "packageName" 替代混合的 "selectedApp" 等表述
  2. 增强注释:关键代码段添加参数说明和边界条件处理
  3. 结构重组:将注意事项按权限、兼容性、性能分类说明
  4. 补充最佳实践:增加延迟启动等优化建议
  5. 移除冗余变量:简化 SharedPreferences 的键名定义
以下是在Android 11中使用代码实现定时开机和定时关机的具体示例: 1. 首先,我们需要获得设置定时开关机的权限。在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:name="android.permission.SET_ALARM"/> <uses-permission android:name="android.permission.REBOOT"/> ``` 2. 创建一个定时开机的方法: ```java private void setPowerOnAlarm() { // 获取AlarmManager实例 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // 创建PendingIntent,用于启动定时开机时要执行的操作 Intent intent = new Intent(this, PowerOnReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); // 获取当前时间 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); // 设置定时开机的时间,这里设置为明天早上6点 calendar.set(Calendar.HOUR_OF_DAY, 6); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.add(Calendar.DAY_OF_MONTH, 1); // 设置定时开机 alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } ``` 3. 创建一个BroadcastReceiver,用于接收定时开机时要执行的操作: ```java public class PowerOnReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 执行开机操作 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); powerManager.reboot(null); } } ``` 4. 创建一个定时关机的方法: ```java private void setPowerOffAlarm() { // 获取AlarmManager实例 AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // 创建PendingIntent,用于启动定时关机时要执行的操作 Intent intent = new Intent(this, PowerOffReceiver.class); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0); // 获取当前时间 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); // 设置定时关机的时间,这里设置为晚上10点 calendar.set(Calendar.HOUR_OF_DAY, 22); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); // 设置定时关机 alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); } ``` 5. 创建一个BroadcastReceiver,用于接收定时关机时要执行的操作: ```java public class PowerOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 执行关机操作 PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE); powerManager.shutdown(); } } ``` 6. 在需要设置定时开机和定时关机的地方调用setPowerOnAlarm()和setPowerOffAlarm()方法即可。 请注意,为了确保定时开关机功能能够正常工作,您需要在AndroidManifest.xml文件中声明PowerOnReceiver和PowerOffReceiver,并向系统注册它们。例如: ```xml <receiver android:name=".PowerOnReceiver"/> <receiver android:name=".PowerOffReceiver"/> ``` 同时,需要注意的是,设置定时开机和定时关机的权限属于系统级别的权限,只有系统应用才能够使用。因此,一般情况下,普通的应用程序是无法使用这些权限的。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值