Android 尝试卸载快捷方式,但快捷方式失败';别走开

Android 尝试卸载快捷方式,但快捷方式失败';别走开,android,android-activity,android-intent,manifest,shortcut,Android,Android Activity,Android Intent,Manifest,Shortcut,我创建了一个在Android主屏幕上安装自身快捷方式的测试活动。当您单击某个按钮时,活动应该删除它刚才创建的同一快捷方式。然而,我所做的一切似乎都没有删除快捷方式 以下是Java代码(ShortcutTest.Java): 这是舱单: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="

我创建了一个在Android主屏幕上安装自身快捷方式的测试活动。当您单击某个按钮时,活动应该删除它刚才创建的同一快捷方式。然而,我所做的一切似乎都没有删除快捷方式

以下是Java代码(ShortcutTest.Java):

这是舱单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.telespree.android.client"
      android:versionCode="1"
      android:versionName="1.0">

      <permission
        android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
        android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
        android:protectionLevel="normal"
        />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".ShortcutTest"
                  android:label="@string/app_name" android:theme="@android:style/Theme.Translucent">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

    <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
    <!-- 
    <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
     -->

    <uses-sdk android:minSdkVersion="7" />

</manifest> 
<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>

我几乎肯定存在某种权限问题,尽管我在互联网上看到其他帖子表明这应该是可能的

非常感谢您的建议


谢谢。

您需要
shortcutient
设置操作,例如:

shortcutIntent.setAction(Intent.ACTION_MAIN);
尝试使用

public void removeShortcut(Context context) {
        Intent intent = new Intent();

        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutTest");

        try {
            Intent shortcutIntent = Intent.parseUri(shortcutUri, 0);
            intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        } catch (URISyntaxException e) {
        }
        intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
        context.sendBroadcast(intent);
    }
注意:不必保存
shortcutUri
即可删除快捷方式。相反,你可以使用

Intent shortcutIntent = new Intent();
shortcutIntent.setClassName("com.telespree.android.client",
        "com.telespree.android.client.ShortcutTest");
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

Intent intent = new Intent();
try {
    intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
            Intent.parseUri(shortcutIntent.toUri(0), 0));
} catch (URISyntaxException e) {
    e.printStackTrace();
}
...
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
context.sendBroadcast(intent);
如果要使用
intent.putExtra(intent.EXTRA\u SHORTCUT\u intent,shortcuttent)而不是

intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
                Intent.parseUri(shortcutIntent.toUri(0), 0));
然后每次都需要为
shortcutient
设置操作,即在安装和卸载时,例如
Intent shortcutient=newintent(Intent.action\u MAIN)

已弃用;仅为历史目的而保存 这个答案发表在2014年,当时描述的方法依赖于大多数Android设备中存在的功能。然而,正如所提到的,这项功能在几年前来自Launcher3,它是Google Now launcher所基于的AOSP launcher。提交消息说:

由于其轻薄的设计,拆卸支架。删除快捷方式 导致完全重新加载。而且我们没有任何所有者的概念,所以 任何应用程序都可以删除任何快捷方式

截至2017年3月,该启动器也支持“谷歌搜索启动器服务”,这意味着制造商可以将某个谷歌库集成到自己的定制启动器中,而不是依赖谷歌提供的标准化启动器

考虑到每个制造商都可以自由地以他们想要的方式实现他们的发射器,并且假设其中一些基于Launcher3,很难判断下面的方法将在哪些设备上工作,因为Launcher3甚至可以在一些设备上运行,这些设备是最受欢迎的


问候语! 我刚刚处理了同样的问题,并想分享我成功解决后的经验tl;dr-跳到下面的“总结”部分。

一些背景: 在处理应用程序的“下一个版本”时,需要更改默认入口点(即重命名“主要活动”)。这是不赞成的,因为从旧版本升级的用户仍然会有旧的快捷方式,指向错误的位置。为了尽可能避免出现问题,在他们不知道的情况下,在第一次发射时,旧的快捷方式将被替换为新的快捷方式

步骤1:设置新的入口点 这是最简单的部分。要声明一个入口点,唯一需要做的事情就是放入以下

尝试2:使用来自viralpatel的原样代码 结果:图标未删除

尝试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);
结果:图标已删除

总之
  • 通过存储用于创建图标的URI或从
    launcher.db
    获取该URI,确保您的“图标卸载程序”意图使用与创建要删除的图标时使用的URI完全相同的URI
  • 等待约2-3秒,以显示“图标已移除”烤面包片
  • 来源 (一)

    (二)

    (三)

    附笔。 为了模拟和调试Google Play更新(保留旧的快捷方式),我执行了以下操作:

  • 从应用商店安装了应用程序的旧版本-带有“旧快捷方式”的图标自动放置在我的屏幕上
  • 使用Total Commander备份了我的launcher.db
  • 通过我的IDE安装了新版本(你也可以使用.apk来安装)-“旧的快捷方式”现在不见了
  • 打开Total Commander并将其最小化(以便在“ALT-TAB”菜单中提供快捷方式)
  • 转到设备设置>>应用>>全部,找到我的启动器(对我来说,它是“投石机”,因为我在CM11上),并强制停止它
  • ALT-TAB转换为Total Commander并恢复数据库
  • 单击硬件“主页”按钮重新启动启动器
  • 中提琴!原来的捷径现在恢复了
  • 注1:在回顾中,使用从数据库获取的URI手动创建旧的快捷方式可能更容易,而不是通过所有备份和强制停止操作


    注2:我没有尝试过使用此方法删除属于其他应用程序的图标,但这可能已经足够疯狂了。

    我花了大约一个小时的时间调试和尝试stackoverflow上的每个示例,但解决方案非常简单。您的代码中有一个输入错误:您需要使用com.android.launcher。操作。卸载快捷方式(与清单中的权限相反)


    编辑:答案已修改

    ,但建议Dev iL和Funt的两种解决方案在棉花糖上市前均有效。Android 6.0(有Launcher v3)中,谷歌删除了卸载ShortcutReceiver,因为它存在安全问题(可能是因为它变得明显)。所以不要指望它能与安卓6.0一起工作。希望在将来的某个版本中,它将以某种形式重新阅读


    PS:通常这应该是一个评论,但我不允许评论,因为我的声誉…

    谢谢!你在这里救了我的命:)尝试3:“暴力”用于删除另一个应用程序的快捷方式。太棒了,我真是太感谢你了。第三次尝试成功了。但只在模拟器或根手机上。如何在无根pho中获取
    launchFlags
    <category android:name="android.intent.category.LAUNCHER"/>
    
    /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
    
    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) { ... }
    
    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);
    
    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);
    
    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);
    
    intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");