已弃用;仅为历史目的保留
This answer was posted in 2014, when the described method relied on functionality that existed in most Android devices. However, as mentioned by Adrian-Costin Țundrea https://stackoverflow.com/a/33731620/3372061, this functionality was removed https://android.googlesource.com/platform/packages/apps/Launcher3/+/e9909f58c2b235f8066295c4faa6a00415968ae7 a couple of years ago from Launcher3, which is the AOSP launcher upon which the Google Now Launcher is based1 https://www.reddit.com/r/AndroidQuestions/comments/3wcfuj/google_now_app_called_launcher3_is_this_normal/cxv9va6/. The commit message said:
由于其脆弱的设计而取消了支撑。删除快捷方式
导致完全重新加载。而且我们没有任何所有者的概念,所以
任何应用程序都可以删除任何快捷方式。
截至 2017 年 3 月,该启动器也正在逐步淘汰 http://www.androidpolice.com/2017/02/03/google-will-discontinue-google-now-launcher-coming-weeks/支持“Google搜索启动器服务”,这意味着制造商可以将某个Google库集成到自己的自定义启动器中,而不是依赖于Google提供的标准化启动器。
考虑到每个制造商都可以自由地以他们想要的方式实现他们的启动器,并且假设其中一些基于 Launcher3,则很难判断下面的方法适用于哪些设备,因为 Launcher3 甚至可以在某些设备上运行安卓4.1 https://f-droid.org/wiki/page/com.android.launcher3设备,其中包括仍在使用的最旧设备 https://developer.android.com/about/dashboards/index.html#Platform.
问候!
我刚刚处理了同样的问题,并想在成功解决后分享我的经验。tl;dr - 跳到下面的“结论”。
一些背景:
在开发应用程序的“下一个版本”时,需要更改默认入口点(即重命名“主要活动”)。这是皱起眉头因为从旧版本升级的用户仍然会使用旧的快捷方式,指向错误的位置。为了尽可能避免出现问题,在第一次启动时,在他们不知情的情况下,旧的快捷方式被替换为新的快捷方式。
第 1 步:设置新的入口点
这是最简单的部分。声明入口点唯一重要的事情要做就是把下面的<action ...>
在清单内适当的活动声明中标记:
<activity
android:name="YOUR_PACKAGE_NAME.YOUR_ACTIVITY_NAME"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
什么是切入点default从某种意义上说,是启动器快捷方式指向它。这就是为什么开发人员通常也会将其包含在<intent-filter>
:
<category android:name="android.intent.category.LAUNCHER"/>
应该指出的是,每项活动都包含此内容<intent-filter>
will在您的应用程序抽屉中创建一个项目 - 这就是为什么在大多数情况下您只需要 1 个实例。
第 2 步:弄清楚旧快捷方式是如何工作的
拥有 root 设备后,我可以访问存储启动器/主屏幕/桌面项目的数据库表(参见 SQLite 条目的图片) http://imageshack.com/a/img713/3677/o2u4.png它位于:
/data/data/com.android.launcher/databases/launcher.db -> SELECT * FROM favorites`
这是图像中突出显示的条目的更易读的版本:
#Intent;
action=android.intent.action.MAIN;
category=android.intent.category.LAUNCHER;
launchFlags=0x10200000;
package=gidutz.soft.bluecard;
component=gidutz.soft.bluecard/.LoadingScreen;
end
请注意0x10200000
- 这在中进行了解释第 4 步 - 尝试 1 below.
第 3 步:找出快捷方式卸载程序的期望
第 38-42 行UninstallShortcutReceiver.java
告诉我们:
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
if (intent != null && name != null) { ... }
这意味着“卸载意图”必须具有both Intent.EXTRA_SHORTCUT_INTENT
and Intent.EXTRA_SHORTCUT_NAME
否则根本不会考虑执行。
第四步:找到正确的语法
这是一个试错但结局皆大欢喜的案例。
尝试 1:重构意图
Intent oldShortcutIntent = new Intent();
oldShortcutIntent.setAction(Intent.ACTION_MAIN);
oldShortcutIntent.addCategory(Intent.CATEGORY_LAUNCHER);
oldShortcutIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED +
Intent.FLAG_ACTIVITY_NEW_TASK);
oldShortcutIntent.setPackage("gidutz.soft.bluecard");
oldShortcutIntent.setComponent(new ComponentName("gidutz.soft.bluecard",
".LoadingScreen"));
// The above line is equivalent to:
Intent oldShortcutIntent = new Intent(getApplicationContext(),LoadingScreen.class);
Intent uninstaller = new Intent();
uninstaller.putExtra(Intent.EXTRA_SHORTCUT_INTENT, oldShortcutIntent);
uninstaller.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
uninstaller.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(uninstaller);
Result:图标未删除。
这0x10200000
实际上是两个参数的总和,如所解释的here http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK.
尝试 2:使用 Viralpatel 中的原样代码
Intent shortcutIntent = new Intent(getApplicationContext(),LoadingScreen.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
addIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(addIntent);
Result:图标未删除。
尝试3:“暴力”
尝试完全按照 launcher.db 中显示的方式复制粘贴意图:
Intent intent = new Intent();
String oldShortcutUri = "#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;package=gidutz.soft.bluecard;component=gidutz.soft.bluecard/.LoadingScreen;end";
try {
Intent altShortcutIntent = Intent.parseUri(oldShortcutUri,0);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, altShortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
} catch (URISyntaxException e) {
}
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(intent);
Result:图标已删除!!
综上所述
- 确保您的“图标卸载程序”意图使用与创建您要删除的图标完全相同的 URI,方法是存储用于创建图标的 URI,或者从
launcher.db
.
- 等待大约 2-3 秒,“图标已删除”吐司就会出现。
Sources
1) 本指南位于 Viralpatel.net http://viralpatel.net/blogs/android-install-uninstall-shortcut-example/
2) Google 的 UninstallShortcutReceiver.java 实现 https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/UninstallShortcutReceiver.java
3) xda 开发者的这个帖子 http://forum.xda-developers.com/showthread.php?t=543882
P.S.
为了模拟和调试 Google Play 更新(保留旧的快捷方式),我执行了以下操作:
- 从商店安装了旧版本的应用程序 - 带有“旧快捷方式”的图标自动放置在我的屏幕上。
- 使用 Total Commander 备份我的 launcher.db。
- 通过我的 IDE 安装新版本(您也可以使用 .apk)-“旧快捷方式”现在消失了。
- 打开 Total Commander 并将其最小化(以便在“ALT-TAB”菜单中提供快捷方式)。
- 转到“设备设置”>>“应用程序”>>“全部”,找到我的启动器(对我来说,它是“Trebuchet”,因为我使用的是 CM11)并且力停止 it.
- ALT-TAB 进入 Total Commander 并恢复数据库。
- 单击硬件“主页”按钮重新启动启动器。
- 中提琴!旧的快捷方式现已恢复。
注 1:回想起来,使用从数据库获取的 URI 手动创建旧快捷方式可能更容易,而不是经历所有备份和强制停止的考验。
注意2:我还没有尝试使用此方法删除属于其他应用程序的图标,但它可能足够疯狂,可以工作。