试图UNINSTALL_SHORTCUT但快捷方式不会消失 [英] Trying to UNINSTALL_SHORTCUT but shortcut won't go away

查看:162
本文介绍了试图UNINSTALL_SHORTCUT但快捷方式不会消失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个测试活动,它安装自身的Andr​​oid主屏幕上的快捷方式。当你点击一个按钮,该活动是应该将其删除刚刚创建的快捷。不过,我似乎没有任何要删除的快捷方式。

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.

下面是Java code(ShortcutTest.java):

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

下面的清单:

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

任何意见是很大的AP preciated。

Any advice is greatly appreciated.

感谢。

推荐答案

我刚刚处理了完全相同的问题,并希望顺利解决之后分享我的经验。 TL;博士 - 跳到总结的

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.

当处理一个应用程序的下一个版本,一个需要时更改默认入口点(即重命名主要活动)。这是的皱眉的,因为用户谁将会从旧版本的升级仍然有旧的快捷方式,指向了错误的地方。为了避免出现问题,尽可能地,在第一次发射,瞒着他们,老快捷方式是更换一个新的。

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.

这是最容易的部分。要声明一个切入点的唯一重要的事情是把下面的&lt;作用...&gt;在适当的活动宣言标签你的清单里:

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>

是什么让在某种意义上是一个入口点的默认的,就是启动快捷方式指向它。这就是为什么开发人员通常都会包含这些在&LT;意向滤光器&gt;

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

应该注意的是,每次有这样的活动了&LT;意向滤光器&gt; 在你的应用程序抽屉里创建一个项目 - 这就是为什么在大多数情况下1个实例是你所需要的。

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.

有一个根深蒂固的设备,我可以访问那里的发射/主屏幕/桌面项目存储数据库表(见什么样的SQLite的作品图像的样子)多数民众赞成位于:

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

注意 0x10200000 - 这是第四步解释 - 尝试1 下面

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_INTENT Intent.EXTRA_SHORTCUT_NAME 要不然也不会考虑执行。

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.

这是审判的情况下,大团圆结局的错误。

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

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 实际上是两个参数的总和解释<一个href="http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK">here.

Result: Icon not removed. The 0x10200000 is actually a sum of two arguments as explained here.

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

结果:图标不会被删除

试图复制粘贴的意图,正是因为它出现在launcher.db:

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

结果:图标删除!

  1. 确保你的图标卸载程序意图使用完全相同的URI用来创建你想删除的图标,方法是存储URI使用,或从获得它来创建它launcher.db
  2. 在等待约2-3秒,为图标删除出现敬酒。

1) 本指南在viralpatel.net

2)<一href="https://android.googlesource.com/platform/packages/apps/Launcher/+/master/src/com/android/launcher/UninstallShortcutReceiver.java">Google's实施UninstallShortcutReceiver.java的

3) 此线程xdadevelopers

为了模拟和我做了以下调试一个谷歌播放的更新(这使旧的快捷方式):

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

  1. 在安装了旧版本从商店应用程序的 - 与老快捷方式的图标被自动放置在我的屏幕上
  2. 备份使用Total Commander的我launcher.db。
  3. 通过我的IDE安装了新版本(你也可以使用一个.apk文件为) - 旧捷径现在不见了
  4. 在打开的总指挥官,并最小化它(这样的快捷方式是在ALT-TAB菜单)。
  5. 又到了设备设置>>应用>>所有,发现我的启动器(对我来说,这是投石机,因为我在CM11)和强制停止的吧。
  6. ALT-TAB为总指挥官和恢复数据库。
  7. 点击硬件回家按钮重新启动发射器。
  8. 中提琴!旧的快捷方式,现在恢复了。
  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.

注1:在回顾性的,它可能是更容易地创建旧的快捷键手动使用URI从数据库中,而不是通过所有后备式和强制停止折磨得

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.

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

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

这篇关于试图UNINSTALL_SHORTCUT但快捷方式不会消失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆