Android8.1 Launcher3 去掉抽屉(三)
上篇博客遗留了两个问题:
a.workspace中的app和HotSeat中有重复的
b.HotSeat中可以创建文件夹
其实问题b可以归类为整体布局逻辑,而且文件夹的样式也不是国内的主流形式。所以问题b先放着,后续和修改文件夹的样式一起修改,这篇博客主要解决问题a。
在src/com/android/launcher3/model/LoaderTask.java中的loadWorkspace(),可以看到是从数据库中加载数据的
private void loadWorkspace() {
......
synchronized (mBgDataModel) {
mBgDataModel.clear();
final HashMap<String, Integer> installingPkgs =
mPackageInstaller.updateAndGetActiveSessionCache();
mBgDataModel.workspaceScreens.addAll(LauncherModel.loadWorkspaceScreensDb(context));
Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>();
final LoaderCursor c = new LoaderCursor(contentResolver.query(
LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp);
HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
......
}
......
}
可以看到这里是查询了数据库,所以我就去数据库查看,在data/data/com.android.launcher3/中可以看到三个数据库:app_icons.db launcher.db widgetpreviews.db,我用的Ubuntu,所以安装了一个sqliteBrower(sudo apt-get install sqliteBrower)。
导入这三个db,发现在launcher.db中有一张表favorites,里面是我们需要的数据,在Launcher上应该显示22个APP,但是在表中有28条数据,其中有6条是重复的。
那么接下里的思路就很清晰了,就是要把这多余的6条数据剔除,为了快速完成,刚开始我是想在查询的时候过滤,试了一下,发现涉及的逻辑太多,我对Launcher的代码又不够熟悉;于是转变思路,在插入的时候过滤,最终还是回到我的Launcher第一篇博客中的
src/com/android/launcher3/model/LoaderTask.java -> verifyApplications():
private void verifyApplications() {
final Context context = mApp.getContext();
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> items = new ArrayList<>();
synchronized (this) {
for (AppInfo app : mBgAllAppsList.data) {
Intent data = app.getIntent();
data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, data);
data.putExtra(Intent.EXTRA_SHORTCUT_ICON, app.iconBitmap);
data.putExtra(Intent.EXTRA_SHORTCUT_NAME, app.title);
InstallShortcutReceiver.PendingInstallShortcutInfo info = new InstallShortcutReceiver.PendingInstallShortcutInfo(
data, app.user, context);
items.add(info);
}
}
//过滤重复APP begin
final ContentResolver cr = context.getContentResolver();
Cursor cursor = cr.query(LauncherSettings.Favorites.CONTENT_URI,
null, null, null, null);
ArrayList<String> intents = new ArrayList<>();
try {
if (cursor.moveToFirst()) {
do {
String intent = cursor.getString(cursor.getColumnIndex(LauncherSettings.Favorites.INTENT));
LogUtil.d(TAG, "intent = " + intent);
intents.add(intent);
} while (cursor.moveToNext());
}
} finally {
cursor.close();
}
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> itemsRm = new ArrayList<>();
for (InstallShortcutReceiver.PendingInstallShortcutInfo info : items) {
if (info == null || info.getItemInfo() == null || info.getItemInfo().first == null || info.getItemInfo().first.getTargetComponent() == null
|| info.getItemInfo().first.getTargetComponent().getPackageName() == null) {
continue;
}
String packageName = info.getItemInfo().first.getTargetComponent().getPackageName();
for (String intent : intents) {
if (intent != null && intent.contains(packageName)) {
itemsRm.add(info);
}
}
}
for (InstallShortcutReceiver.PendingInstallShortcutInfo info : itemsRm) {
if (items.contains(info)) {
items.remove(info);
}
}
itemsRm.clear();
itemsRm = null;
//过滤重复APP end
if (!items.isEmpty()) {
mApp.getModel().addAndBindAddedWorkspaceItems(
new InstallShortcutReceiver.LazyShortcutsProvider(context.getApplicationContext(), items));
}
}
运行一下,很开心,发现搞定了!!!
总结:因为这次的需求,时间要求比较着急,而且我对Launcher也不熟悉,所以很多地方没有考虑太多,基本都是能实现功能就OK,如果以后有时间,代码还需要再重新整理一下。