android - 启动器应用程序如何在后台卸载应用程序?
问题描述
背景
我有一个业余时间应用程序,它的主要功能之一是轻松卸载应用程序。
问题
我正在使用一个非常基本的 API 来卸载应用程序,对于用户来说这似乎是 2 个步骤:确认卸载,并看到一些显示卸载过程的对话框。
我注意到在某些启动器应用程序(例如 Nova 启动器和 Pixel Launcher)上,在卸载时,它们只显示一个步骤,即确认卸载所选应用程序。
这是通过我的应用程序和应用程序信息的正常内置屏幕的外观。首先你会看到:
然后这个:
但是,在启动器上,您只会看到以下内容:
不久之后,该应用程序消失了,而您之间没有看到任何东西。
我发现了什么
我知道在后台卸载应用程序的唯一方法是使用 root,但这不是这些应用程序所做的。
这是我用于正常卸载过程的内容:
public static Intent prepareUninstallAppIntent(@NonNull final Context context, @NonNull final String packageName) {
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", packageName, null));
intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
intent.putExtra("android.intent.extra.UNINSTALL_ALL_USERS", true);
return null;
}
问题
启动器应用程序如何仅显示确认对话框,并在后台执行卸载?
它是一个新的 API 吗?如果是这样,来自哪个版本?我在哪里可以读到它?
编辑:这不再重要了。得看看它是如何工作的。
通过查看Lawnchair启动器应用程序代码,我现在发现它与我所做的有点相似:
public static boolean startUninstallActivity(
final Launcher launcher, ItemInfo info, DropTargetResultCallback callback) {
Pair<ComponentName, Integer> componentInfo = getAppInfoFlags(info);
ComponentName cn = componentInfo.first;
final boolean isUninstallable;
if ((componentInfo.second & AppInfo.DOWNLOADED_FLAG) == 0) {
// System applications cannot be installed. For now, show a toast explaining that.
// We may give them the option of disabling apps this way.
Toast.makeText(launcher, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
isUninstallable = false;
} else {
Intent intent = new Intent(Intent.ACTION_DELETE,
Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.putExtra(Intent.EXTRA_USER, info.user);
launcher.startActivity(intent);
isUninstallable = true;
}
if (callback != null) {
sendUninstallResult(
launcher, isUninstallable, componentInfo.first, info.user, callback);
}
return isUninstallable;
}
它在那里的工作方式与其他启动器相同,因此,对我来说,他们似乎为当前用户添加了卸载部分(使用android.os.Process.myUserHandle();
)。
但我还是试过了。似乎有效,所以我当时尝试的是删除越来越多的代码,直到我得到一些没有奇怪东西的东西。
这是最小的代码:
final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE, Uri.fromParts("package", packageName, null));
你只需使用 startActivity,而不是 startActivityForResult。
是的。这么短,我想知道我错过了多久...
但现在我有其他问题:
cn.getClassName()
和Intent.EXTRA_USER
用途是什么?此代码将从哪个版本的 Android 后台卸载应用程序?
ACTION_UNINSTALL_PACKAGE 和 ACTION_DELETE 这里有什么区别吗?
我删除了所有标志,它似乎仍然在做同样的工作,没有历史上的任务。他们真的需要吗?
还有更多卸载应用程序的方法吗?也许是一批?
解决方案
推荐阅读
- json - 将 json.parse 与 src 手动路由合并
- antlr - 有没有办法使用 antlr4 语法生成构建器?
- c# - 当 dotPeek 和 stackoverflow 问题反编译器清楚地显示它时,无法通过反射找到/编辑字段
- linux - 是否可以在 raspbian 上安装 linux 程序?
- database-design - SQL 事件存储 - 每个聚合一个流
- icecast - icecast 介绍文件 - 它可以是远程脚本吗?
- numpy - MLP 输出任何输入的所有训练输出的平均值
- powershell - 从 Excel 表中读取数据并与现有用户进行比较
- python - 基于条件的带有字典的嵌套列表
- ms-word - 如何将 Xml 更改保存回原始文档