我正在开发一个 KIOSK 应用程序,它包含 2 个应用程序:
- 启动器应用程序:确保业务应用程序始终运行并实现 KIOSK 功能
- 业务应用程序:这是用户与之交互的内容。
在更新之前,我的启动器应用程序已经是默认启动器,因为它是在设备初始化期间在用户收到设备之前手动设置的。问题来自这样一个事实,即这不是通过更新应用程序而持久的。
我正在使用以下方法更新我的 Launcher 应用程序
- 通过 HTTP 下载新应用程序
- 使用 PackageInstaller API,我将下载的数据流式传输到安装新版本应用程序的会话中。
- 更新完成时将通知静态广播接收器,侦听
android.intent.action.PACKAGE_REPLACED
- 在这个接收器中,我想确保当我重新启动设备时,该启动器保持默认启动器,因此,不会提示用户使用应用程序选择器(选择默认启动器)。
到目前为止,我的工作失败了,因为用户确实收到了应用程序选择器的提示:
检查启动器是否为默认启动器:
private boolean isLauncherDefault(Context context) {
final IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
List<IntentFilter> filters = new ArrayList<>();
filters.add(filter);
List<ComponentName> activities = new ArrayList<>();
final PackageManager packageManager = context.getPackageManager();
packageManager.getPreferredActivities(filters, activities, null);
boolean has = false;
for (ComponentName activity : activities) {
Logger.info(TAG, "Package: " + activity.getPackageName());
if (StaticData.LauncherPackageName.equals(activity.getPackageName())) {
has = true;
}
}
return has;
}
一些使用不同方法的日志记录,只是为了确保:
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
launcherIntent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(launcherIntent, PackageManager.MATCH_DEFAULT_ONLY);
String currentHomePackage = resolveInfo.activityInfo.packageName;
Logger.info(TAG, "Current home package: " + currentHomePackage);
即使上面说我的启动器是默认启动器,我也想确定一下,所以无论如何我都会调用以下方法:
public void setLauncherAsDefault() {
Logger.info(TAG, "Setting launcher as default launcher");
StringBuilder launcherActivity = new StringBuilder();
launcherActivity.append(StaticData.LauncherPackageName);
launcherActivity.append(".activities.LauncherActivity");
ComponentName launcher = new ComponentName(StaticData.LauncherPackageName,
launcherActivity.toString());
IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
mDevicePolicyManager.addPersistentPreferredActivity(mAdminComponentName, filter, launcher);
}
上面的所有代码都是从业务应用程序调用的,因为该应用程序是设备所有者。
不向用户显示默认启动器应用程序选择器至关重要,因为这可能会导致他们弄乱设备。
我花了很多时间研究这个问题,但没有任何成功,感谢您的帮助,谢谢!