最近测试发现一个bug,在应用程序信息页面,点击清除数据后,然后打开该应用,发现桌面又创建了一个shortcut,很显然shortcut重复了。于是赶紧去分析bug产生的原因:我们的应用程序主页会有一个判断ShortCutFlag的过程,如果返回false,则会创建。而ShortCutFlag是记录在SharedPreferences中,清除应用数据时,也会把SharedPreferences清除,导致会重复创建shortcut,而此时系统应该能够判断是否已创建,我们是否有参数来设置不允许重复创建shortcut呢,创建shortcut的代码如下
public static void addShortcut(Context cx) {
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
Intent shortcutIntent = cx.getPackageManager().getLaunchIntentForPackage(cx.getPackageName());
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
String title = null;
try {
final PackageManager pm = cx.getPackageManager();
title = pm.getApplicationLabel(pm.getApplicationInfo(cx.getPackageName(),PackageManager.GET_META_DATA)).toString();
} catch (Exception e) {
}
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
shortcut.putExtra("duplicate", false);
Parcelable iconResource = Intent.ShortcutIconResource.fromContext(cx,R.drawable.ic_launcher);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
cx.sendBroadcast(shortcut);
}
其中shortcut.putExtra("duplicate", false) 就设置不允许重复,似乎没起作用。多调用cx.sendBroadcast(shortcut)几次就会出现多生成几个shortcut。
于是只能寻找其他办法来判断是否已生成shortcut,经过测试以下方法有效
1.修改addShortCut
public static void addShortcut(Context cx) {
String title = null;
try {
final PackageManager pm = cx.getPackageManager();
title = pm.getApplicationLabel(pm.getApplicationInfo(cx.getPackageName(),PackageManager.GET_META_DATA)).toString();
} catch (Exception e) {
}
if(hasShortcut(cx ,title)){
return;
}else {
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
Intent shortcutIntent = cx.getPackageManager().getLaunchIntentForPackage(cx.getPackageName());
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
shortcut.putExtra("duplicate", false);
Parcelable iconResource = Intent.ShortcutIconResource.fromContext(cx, R.drawable.ic_launcher);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
cx.sendBroadcast(shortcut);
}
}
2.增加hasShortCut来判断是否创建已创建shortcut
private static boolean hasShortcut(Context context,String shortcutName){
String url = "";
int systemversion = Build.VERSION.SDK_INT;
/*大于8的时候在com.android.launcher2.settings 里查询*/
if(systemversion < 8){
url = "content://com.android.launcher.settings/favorites?notify=true";
}else{
url = "content://com.android.launcher2.settings/favorites?notify=true";
}
try {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(url), null, "title=?", new String[]{shortcutName}, null);
if (cursor != null && cursor.moveToFirst()) {
cursor.close();
return true;
}
}catch (Exception e) {
}
return false;
}
注: 需要增加<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
否则“Cursor cursor = resolver.query(Uri.parse(url), null, "title=?",new String[] {shortcutName}, null)”
会卡住。。。
注: 可以让addShortCut在单独的线程中执行。