问题:
1.shortcut在2.3上创建后,假如应用升级并修改了app名称,shortcut不会自动更新,仍显示原名字。
2.如果此时强制更新,则会创建新的shortcut,而不是覆盖原shortcut。
3.判断shortcut是否存在时,某些机型LauncherProvider的查询路径不是com.android.launcher.setting.
先说前两个问题,前两个问题的解决办法只是写逻辑上的判断了,先判断应用的shortcut存不存在,然后删除添加任你选。所以只要搞定hasShortcut()这个方法就ok。
然后再说第三个问题,判断shortcut是否存在其实就是去LauncherProvider的数据库里面查询这条数据在不在。
现在大多数机型用的都是android的默认launcher,包名为com.android.launcher,这个数据库一般在data/data/com.android.launcher/database据库里 的launcher.db的favorites表。查询的URI=”"content://com.android.launcher.settings/favorites?notify=true“。 但是android 2.2以后的URI则变为了URI=”"content://com.android.launcher2.settings/favorites?notify=true“.
另外像三星,htc,小米,华为等手机却将launcher改成了他们自己的launcher,颇感无语,其对应包名如下:
miui: com.miui.home
huawei: com.huawei.android.launcher
htc: com.htc.launcher
samsung: com.sec.android.app.launcher
所以这里查询的URI="content://" + packageName + ".settings/favorites?notify=true"。
恩,这里另附数据库中的字段清单:
CREATE TABLE favorites
(
_id INTEGER PRIMARY KEY,
title TEXT,
intent TEXT,
container INTEGER,
screen INTEGER,
cellX INTEGER,
cellY INTEGER,
spanX INTEGER,
spanY INTEGER,
itemType INTEGER,
appWidgetId INTEGER NOT NULL DEFAULT -1,
isShortcut INTEGER,
iconType INTEGER,
iconPackage TEXT,
iconResource TEXT,
icon BLOB,
uri TEXT,
displayMode INTEGER
);
下面就讲一下demo的代码:
首先添加,删除,查询shortcut都需要权限,所以要在mainfast配置一下,注意,如果launcher不是android原生的,read和write的权限需要用其相应的包名,所以我下面加了htc和三星两款机型。
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
添加的代码如下:
private static final String INSTALL_SHORTCUT_ACTION = "com.android.launcher.action.INSTALL_SHORTCUT";
/**
* 添加快捷方式
*
* @param name
*/
public void addShortCut(String name) {
Log.d(TAG, "addShortCut:" + name);
Intent shortcut = new Intent(INSTALL_SHORTCUT_ACTION);
// 设置属性
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(
context.getApplicationContext(), R.drawable.ic_launcher);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON, iconRes);
// 是否允许重复创建
shortcut.putExtra("duplicate", false);
// 设置桌面快捷方式的图标
Parcelable icon = Intent.ShortcutIconResource.fromContext(context,
R.drawable.ic_launcher);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
// 设置启动程序
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, getClickIntent(context));
// 广播通知桌面去创建
context.sendBroadcast(shortcut);
}
删除的代码如下:private static final String UNINSTALL_SHORTCUT_ACTION = "com.android.launcher.action.UNINSTALL_SHORTCUT";
/**
* 删除快捷方式
*
* @param name
*/
public void deleteShortcut(String name) {
Log.d(TAG, "deleteShortcut:" + name);
Intent intent = new Intent(UNINSTALL_SHORTCUT_ACTION);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, getClickIntent(context));
context.sendBroadcast(intent);
}
注意这里的shortcut的EXTRA_SHORTCUT_INTENT得intent相应的值添加和删除的时候必须一致,应该是数据库里的intent字段,删除好像要依靠这个值,如果不一样就删不掉了,所以我直接包了一个方法。 /**
* 点击快捷方式的跳转intent(删除快捷方式时,这个的一些参数要和创建的保持一致,否则删不掉)
*
* @param context
* @return
*/
private Intent getClickIntent(Context context) {
// 点击快捷方式的操作
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
return intent.setClass(context, MainActivity.class);
}
最后说一下判断shortcut是否存在这一方法。首先先想办法扒出手机的launcher包名。
/**
* 尝试获取系统的launcher
*
* @param context
* @return
*/
public static String getLauncherPackageName(Context context) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo res = context.getPackageManager()
.resolveActivity(intent, 0);
if (res.activityInfo == null) {
return "";
}
// 如果是不同桌面主题,可能会出现某些问题,这部分暂未处理
if (res.activityInfo.packageName.equals("android")) {
return "";
} else {
return res.activityInfo.packageName;
}
}
然后再根据相应的包名去查询
/**
* 根据 title 判断快捷方式是否存在
*
* @return
*/
public boolean hasShortcut(String name) {
String url;
String packageName = getLauncherPackageName(context);
Log.d(TAG, "packageName:" + packageName);
/*
* 1.判断launcher包名是否是android原生的
* 2.若果是原生的,在2.2以后LauncherProvider的路径是com.android.launcher2.settings
*/
if (packageName == null || packageName.equals("")
|| packageName.equals("com.android.launcher")) {
if (getSystemVersion() < 8) {
packageName = "com.android.launcher";
} else {
packageName = "com.android.launcher2";
}
}
url = "content://" + packageName + ".settings/favorites?notify=true";
Log.d(TAG, "url:" + url);
try {
ContentResolver resolver = context.getContentResolver();
Cursor cursor = resolver.query(Uri.parse(url), new String[] {
"title", "iconResource" }, "title=?",
new String[] { name }, null);
if (cursor != null && cursor.getCount() > 0) {
return true;
}
} catch (Exception e) {
if (e != null) {
e.printStackTrace();
}
}
return false;
}
另外android2.3手机升级并改名,修改shortcut的思路就是按照原名称删除原shortcut,然后按照新的app名称创建新的shortcut。
恩,大体就是这样了,修改其实应该还可以尝试直接操作数据库,修改其名称的那个字段,但这个我没试验,希望哪位大大挑战一下。
经测试,三星2.3中兴2.3没有问题,小米等手机没有shortcut,手头没有三点几的系统的手机,哪位大大有这个系统的手机也可以测一下。
最后附上demo地址http://download.youkuaiyun.com/download/ccfcccfc/8124883