尝试 UNINSTALL_SHORTCUT 但快捷方式不会消失

发布于 2024-09-14 10:26:07 字数 3519 浏览 6 评论 0原文

我创建了一个测试活动,它在 Android 主屏幕上安装了它自己的快捷方式。当您单击按钮时,活动应该删除它刚刚创建的相同快捷方式。但是,我似乎没有做任何事情来删除快捷方式。

这是 Java 代码 (ShortcutTest.java):

import java.net.URISyntaxException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ShortcutTest extends Activity {
    String shortcutUri;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        addShortcut(getBaseContext());

        Button button = (Button)findViewById(R.id.Button01);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                removeShortcut(getBaseContext());
                finish();
            }
        });
    }

    public void addShortcut(Context context) {
        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();
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutTest");
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.drawable.icon));
        intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
        shortcutUri = intent.toUri(MODE_WORLD_WRITEABLE);
        context.sendBroadcast(intent);
    }

    public void removeShortcut(Context context) {
        Intent intent = null;
        try {
            intent = Intent.parseUri(shortcutUri, 0);
        } catch (URISyntaxException e) {
        }
        intent.setAction("com.android.launcher.permission.UNINSTALL_SHORTCUT");
        context.sendBroadcast(intent);
    }
}

这是清单:

<?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> 

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

非常感谢任何建议。

谢谢。

I created a test Activity that installs a shortcut of itself on the Android Home screen. When you click a button, the Activity is supposed to remove the same shortcut it just created. However, nothing I do seems to delete the shortcut.

Here is the Java code (ShortcutTest.java):

import java.net.URISyntaxException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ShortcutTest extends Activity {
    String shortcutUri;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        addShortcut(getBaseContext());

        Button button = (Button)findViewById(R.id.Button01);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                removeShortcut(getBaseContext());
                finish();
            }
        });
    }

    public void addShortcut(Context context) {
        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();
        intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
        intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutTest");
        intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.drawable.icon));
        intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
        shortcutUri = intent.toUri(MODE_WORLD_WRITEABLE);
        context.sendBroadcast(intent);
    }

    public void removeShortcut(Context context) {
        Intent intent = null;
        try {
            intent = Intent.parseUri(shortcutUri, 0);
        } catch (URISyntaxException e) {
        }
        intent.setAction("com.android.launcher.permission.UNINSTALL_SHORTCUT");
        context.sendBroadcast(intent);
    }
}

Here is the Manifest:

<?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> 

I'm almost positive there is some kind of permissions problem, though I've seen other posts on the Internet that indicates this should be possible.

Any advice is greatly appreciated.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

请你别敷衍 2024-09-21 10:26:07

已弃用;仅出于历史目的保留

此答案于 2014 年发布,当时所描述的方法依赖于大多数 Android 设备中存在的功能。但是,正如 Adrian-Costin şundrea 提到的,此功能几年前已从 Launcher3 中删除,Launcher3 是 Google 所依赖的 AOSP 启动器现在启动器基于1。提交消息说:

由于其脆弱的设计而取消了支持。删除快捷方式
导致完全重新加载。而且我们没有任何所有者的概念,所以
任何应用程序都可以删除任何快捷方式。

自 2017 年 3 月起,此启动器也将正在逐步淘汰,取而代之的是“Google 搜索启动器服务”,这意味着制造商可以将某个 Google 库集成到他们自己的自定义启动器中,而不是依赖 Google 提供的标准化启动器。

考虑到每个制造商都可以自由地以他们想要的方式实现他们的启动器,并且假设其中一些基于 Launcher3,很难判断下面的方法适用于哪些设备,因为 Launcher3 甚至可以在某些设备上运行="https://f-droid.org/wiki/page/com.android.launcher3" rel="nofollow noreferrer">Android 4.1 设备,属于 仍在使用的最旧设备


问候!

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

一些背景:

在开发应用程序的“下一个版本”时,需要更改默认入口点(即重命名“Main活动”)。这是令人不悦的,因为从旧版本升级的用户仍然会使用旧的快捷方式,指向错误的位置。为了尽可能避免出现问题,在第一次启动时,在他们不知情的情况下,旧的快捷方式被替换为新的快捷方式。

第 1 步:设置新的入口点

这是最简单的部分。要声明入口点,唯一要做的事情就是将以下 标记放入清单内相应的活动声明中

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

:从某种意义上说,入口点默认是启动器快捷方式指向它。这就是为什么开发人员通常也会将其包含在 中:

<category android:name="android.intent.category.LAUNCHER"/>

应该注意的是,每个在其 中包含此内容的活动 <将会在您的应用程序抽屉中创建一个项目 - 这就是为什么在大多数情况下您只需要 1 个实例。

步骤 2:弄清楚旧快捷方式是如何工作的

有了 root 设备,我可以访问存储启动器/主屏幕/桌面项目的数据库表 (查看 SQLite 条目的图像) 位于:

/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 中进行了解释。

第 3 步:弄清楚快捷方式卸载程序期望什么

UninstallShortcutReceiver.java 中的第 38-42 行告诉我们:

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.EXTRA_SHORTCUT_INTENTIntent.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);

结果: 图标未删除。
0x10200000 实际上是两个参数的总和,如所解释的

尝试 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);

结果: 图标未删除。

尝试 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);

结果:图标已删除!

结论

  1. 确保您的“图标卸载程序”意图使用与创建您要删除的图标完全相同的 URI,方法是存储用于创建图标的 URI,或从 launcher.db 获取它/代码>。
  2. 等待大约 2-3 秒,“图标已删除”吐司就会出现。

来源

1) 本指南位于 Viralpatel.net< /a>

2) Google 的 UninstallShortcutReceiver.java 实现

3) xdadevelopers 上的此线程

PS

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

  1. 从商店安装了旧版本的应用程序- 带有“旧快捷方式”的图标自动放置在我的屏幕上。
  2. 使用 Total Commander 备份我的 launcher.db。
  3. 通过我的 IDE 安装新版本(您也可以使用 .apk)-“旧快捷方式”现在消失了。
  4. 打开 Total Commander 并将其最小化(以便在“ALT-TAB”菜单中提供快捷方式)。
  5. 进入设备设置>>应用>>全部,找到了我的发射器(对我来说,它是“Trebuchet”,因为我在 CM11)并且强制停止它。
  6. ALT-TAB 进入 Total Commander 并恢复数据库。
  7. 单击硬件“主页”按钮重新启动启动器。
  8. 中提琴!旧的快捷方式现已恢复。

注 1:回想起来,使用从数据库获取的 URI 手动创建旧快捷方式可能更容易,而不是经历所有备份和强制停止的考验。

注意2:我还没有尝试使用此方法删除属于其他应用程序的图标,但它可能足够疯狂,可以工作。

DEPRECATED; KEPT SOLELY FOR HISTORICAL PURPOSES

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, this functionality was removed a couple of years ago from Launcher3, which is the AOSP launcher upon which the Google Now Launcher is based1. The commit message said:

Removing support due to its flacky design. Removing a shortcut
causes a full reload. Also we do not have any concept of owner, so
any app can remove any shortcut.

As of March 2017, this launcher, too, is being phased out in favor of "Google Search Launcher Services", which means that manufacturers could integrate a certain Google library into their own custom launchers, instead of relying on a standardized launcher provided by Google.

Considering that each manufacturer is free to implement their launcher whichever way they want, and assuming some of them are based off Launcher3, it's difficult to tell which devices the method below will work on, as Launcher3 was made to run even on some Android 4.1 devices, which are among the oldest devices still in use.


Greetings!

I have just dealt with the same exact problem, and would like to share my experience after successfully resolving it. tl;dr - skip to "In Conclusion" below.

Some background:

While working on the "next version" of an app, a need arose to change the default entry point (i.e. to rename the "Main Activity"). This is frowned upon because users who would be upgrading from an old version will still have the old shortcut, pointing to the wrong place. In order to avoid problems as much as possible, on the first launch, unbeknownst to them, the old shortcut was to be replaced with a new one.

Step 1: Setting up a new entry point

This is the easiest part. To declare an entry point the only essential thing to do is to put the following <action ...> tag in the appropriate activity declaration inside your 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>

What makes an entry point default in some sense, is that the launcher shortcut points to it. This is why developers usually also include this in the <intent-filter>:

<category android:name="android.intent.category.LAUNCHER"/>

It should be noted that every activity that has this in its <intent-filter> will create an item in your app drawer - this is why for most cases 1 instance is all you need.

Step 2: Figuring out how the old shortcut is working

Having a rooted device, I could access the database table where the launcher/homescreen/desktop items are stored (see image of what the SQLite entries looks like) that's located in:

/data/data/com.android.launcher/databases/launcher.db -> SELECT * FROM favorites`

Here's a more readable version of the highlighted entry from the image:

#Intent;
    action=android.intent.action.MAIN;
    category=android.intent.category.LAUNCHER;
    launchFlags=0x10200000;
    package=gidutz.soft.bluecard;
    component=gidutz.soft.bluecard/.LoadingScreen;
 end

Note the 0x10200000 - this is explained in Step 4 - Attempt 1 below.

Step 3: Figuring out what the Shortcut Uninstaller is expecting

Lines 38-42 in UninstallShortcutReceiver.java tell us that:

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) { ... }

Meaning that the "uninstallation intent" has to have both Intent.EXTRA_SHORTCUT_INTENT and Intent.EXTRA_SHORTCUT_NAME or else it will not even consider executing.

Step 4: Finding the Right Syntax

This is a case of trial an error with a happy ending.

Attempt 1: Reconstructing the intent

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: Icon not removed.
The 0x10200000 is actually a sum of two arguments as explained here.

Attempt 2: Using as-is code from 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: Icon not removed.

Attempt 3: "Brute Force"

Trying to copy-paste the intent exactly as it appears in the 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: Icon removed!!

In Conclusion

  1. Make sure that your "Icon Uninstaller" intent uses the exact same URI used to create the icon you're trying to delete, by either storing the URI used to create it, or by obtaining it from launcher.db.
  2. Wait about 2-3 seconds for the "icon removed" toast to appear.

Sources

1) This guide at viralpatel.net

2) Google's implementation of UninstallShortcutReceiver.java

3) This thread at xdadevelopers

P.S.

In order to simulate and debug a Google Play update (which keeps the old shortcut) I did the following:

  1. Installed the old version of the app from the store - an icon with the "old shortcut" was automatically placed on my screen.
  2. Backed-up my launcher.db using Total Commander.
  3. Installed the new version through my IDE (you can also use an .apk for that) - the "old shortcut" was now gone.
  4. Opened Total Commander and minimized it (so that a shortcut is available in the "ALT-TAB" menu).
  5. Went to the Device Settings >> Apps >> ALL, found my launcher (for me it was "Trebuchet" since I'm on CM11) and Force stopped it.
  6. ALT-TAB into Total Commander and restored the DB.
  7. Clicked the hardware "home" button to re-launch the launcher.
  8. Viola! The old shortcut was now restored.

Note1: In retrospective, it might have been easier to create the old shortcut manually using the URI obtained from the database instead of going through all backing-up and force-stopping ordeal.

Note2: I haven't tried removing icons belonging to other apps using this method, but it might just be crazy enough to work.

寂寞花火° 2024-09-21 10:26:07

虽然 Dev-iL 和 Funt 的两种解决方案都有效,但请注意,它们在 Marshmallow 之前都是如此。在 Android 6.0(具有 Launcher v3)中,Google 由于其安全问题而删除了 UninstallShortcutReceiver(可能是因为它变得明显这里)。所以不要指望它能与 Android 6.0 兼容。希望在未来的版本中,它将以某种形式或另一种形式被阅读。

PS:通常这应该是一个评论,但由于声誉,我不允许发表评论......

While both solutions from Dev-iL and Funt work be advised they do so until Marshmallow. With Android 6.0 (which has Launcher v3) Google has removed the UninstallShortcutReceiver because of its security problems (probably because it became apparent here). So do not expect it to work with Android 6.0. Hopefully in some future release it will be readded in a form or another.

PS: Normally this should be a comment, but I am not allowed to comment because of the reputation...

谁对谁错谁最难过 2024-09-21 10:26:07

您需要为 shortcutIntent 设置操作,例如:

shortcutIntent.setAction(Intent.ACTION_MAIN);

You need to setAction for shortcutIntent like:

shortcutIntent.setAction(Intent.ACTION_MAIN);
若有似无的小暗淡 2024-09-21 10:26:07

尝试使用

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_SHORTCUT_INTENT,shortcutIntent);而不是

intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
                Intent.parseUri(shortcutIntent.toUri(0), 0));

那么您需要每次为shortcutIntent设置操作,即在安装时以及卸载时,例如Intent捷径Intent = new Intent(Intent.ACTION_MAIN);

Try to use

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);
    }

Note: You do not have to save shortcutUri to remove the shortcut. Instead you can use

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);

If you want to use intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); instead of

intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
                Intent.parseUri(shortcutIntent.toUri(0), 0));

then you need to set action for shortcutIntent each time , i.e. while installing as well as while uninstalling e.g. Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);

↙厌世 2024-09-21 10:26:07

我花了大约一个小时的时间调试并尝试了 stackoverflow 上的每个示例,但解决方案非常简单。您的代码中有一个拼写错误:您需要使用 com.android.launcher.action.UNINSTALL_SHORTCUT (与清单中的权限相反)

intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");

It took me about an hour of debugging and trying out every example on stackoverflow, but the solution was very easy. There's a typo in your code: You need to use com.android.launcher.action.UNINSTALL_SHORTCUT (as opposed to permission, as it is in the Manifest)

intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文