Launcher workspace 应用快捷方式重复的问题
前段时间改过一个BUG,就是Launcher桌面上的应用快捷方式重复,纠结了好久,后来改好了,总结了下出现这个问题的原因:首先声明下我们的Launcher要求是没有allapp按钮的,图标全部显示在桌面上,所以才会出现这个问题,总结的也是我碰到过的几种情况,遇到具体问题具体分析,应该会有帮助的。
1.只有单独一两个应用快捷方式重复
这个可能就是你在default_workspace.xml配置时,将应用的类名写错了,你写的那个类名并不是它的入口函数,这样就会出现重复的,并且其中一个应该是点不进去的,
下面提供3个获取入口函数的方法:
1)用eclipse的DDMS工具或者是sdk工具(/adt-bundle-linux-x86_64-20131030/sdk/tools/hierarchyviewer)
2)用获取第三方应用的包名和类名的apk,安装后会将系统里面所有的apk的包名和类名都列出来,少数的看不到
3)在ubuntu下使用命令: aapt d bading xxx.apk
4)反编译apk,看AndroidManifest.xml ,当然这个方法对于加密的apk是不适用的
2.系统所有的应用快捷方式都重复
我碰到这种情况是因为项目默认是英语,插入了中文SIM,这样重启之后就出现了,而Launcher原来的判断快捷方式重复是根据title来的,下面提供一种判断快捷方式重复的方法,是根据包名来判断的
static boolean hctShortcutExists(Context context, String title, Intent intent) {
final ContentResolver cr = context.getContentResolver();
Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { "title", "intent" }, "title=? and intent=?",
new String[] { title, intent.toUri(0) }, null);
c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
new String[] { LauncherSettings.Favorites.INTENT }, "title=? and (itemType=? or itemType=?)",
new String[] { title, String.valueOf(LauncherSettings.Favorites.ITEM_TYPE_APPLICATION)}, null);
boolean result = false;
final int intentIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.INTENT);
try {
while (c.moveToNext()) {
try {
Intent exitIntent = Intent.parseUri(c.getString(intentIndex), 0);
if(exitIntent.getComponent().getPackageName().equals(intent.getComponent().getPackageName())){
result = true;
}
} catch (Exception e) {
// Ignore
e.printStackTrace();
}
}
} finally {
c.close();
}
return result;
}
3.安装的第三方应用快捷方式重复
这是因为有的第三方应用会发送一个安装快捷方式的广播,接收到广播后就会在Launcher 的workspace上创建快捷方式
解决方法:
android中后台自动创建快捷方式主要是通过发送Action为”android.intent.action.CREATE_SHORTCUT“的broadcast,当然还会带有一些包含icon,name等data。之后ActivityManagerService会将这个Broadcast放到BroadcastQueue中开始异步处理。
BroadcastQueue.java的对应处理位置是:
processNextBroadcast函数,正常允许后台创建快捷方式会打印像如下行的log:
"Processing ordered broadcast [" background + "] " + {42615a08 u0 com.android.launcher.action.INSTALL_SHORTCUT}
对应代码就是:
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["+ mQueueName + "] " + r);
所以我们只需要在后面加上:
if (mQueueName.equals("background")
&& r.intent.getAction().equals("com.android.launcher.action.INSTALL_SHORTCUT"))
return;
这样就可以禁止后台自动创建快捷方式