隐藏掉应用列表后,发现在Launcher的WorkSpace中不管怎样都市无法卸载应用的,只能删除图标。研究发现在DeleteDropTarget这个类中可以控制拖拽应用图标卸载应用。
1、修改代码,使用户每次拖动图标显示卸载选项,而不是显示删除应用图标的选项
@Override
public void onDragStart(DragSource source, Object info, int dragAction) {
boolean isVisible = true;
// 修改判断条件
// boolean useUninstallLabel = LauncherAppState.isDisableAllApps() &&
// isAllAppsApplication(source, info);
boolean useUninstallLabel = LauncherAppState.isDisableAllApps();
boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget();
// If we are dragging an application from AppsCustomize, only show the control if we can
// delete the app (it was downloaded), and rename the string to "uninstall" in such a case.
// Hide the delete target if it is a widget from AppsCustomize.
if (!willAcceptDrop(info) || isAllAppsWidget(source, info)) {
isVisible = false;
}
if (useUninstallLabel) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
UserManager userManager = (UserManager)
getContext().getSystemService(Context.USER_SERVICE);
Bundle restrictions = userManager.getUserRestrictions();
if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
|| restrictions.getBoolean(UserManager.DISALLOW_UNINSTALL_APPS, false)) {
isVisible = false;
}
}
}
if (useUninstallLabel) {
setCompoundDrawablesRelativeWithIntrinsicBounds(mUninstallDrawable, null, null, null);
} else if (useDeleteLabel) {
setCompoundDrawablesRelativeWithIntrinsicBounds(mRemoveDrawable, null, null, null);
} else {
isVisible = false;
}
mCurrentDrawable = (TransitionDrawable) getCurrentDrawable();
mActive = isVisible;
resetHoverColor();
((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
//
if (isVisible && getText().length() > 0) { setText(useUninstallLabel ? R.string.delete_target_uninstall_label : R.string.delete_target_label); } }
2、修改willAcceptDrop方法,让该方法返回true
public static boolean willAcceptDrop(Object info) {
if (info instanceof ItemInfo) {
ItemInfo item = (ItemInfo) info;
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET ||
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
return true;
}
//默认为!LauncherAppState.isDisableAllApps(),把条件改成相反就可以了
if (LauncherAppState.isDisableAllApps() &&
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
return true;
}
//同上
if (LauncherAppState.isDisableAllApps() &&
item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
item instanceof AppInfo) {
AppInfo appInfo = (AppInfo) info;
return (appInfo.flags & AppInfo.DOWNLOADED_FLAG) != 0;
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
item instanceof ShortcutInfo) {
if (!LauncherAppState.isDisableAllApps()) {
ShortcutInfo shortcutInfo = (ShortcutInfo) info;
return (shortcutInfo.flags & AppInfo.DOWNLOADED_FLAG) != 0;
} else {
return true;
}
}
}
return false;
}
3、当用户拖动图标完成后,会执行completeDrop方法。该方法中的isUninstallFromWorkspace是判断是否可以从WorkSpace中卸载应用,所以也要修改这里,让该方法返回true。判断该应用是否是系统应用中,有一个bug没有解 决。所以不引用源码的方法判断,自己写了一个方法判断应用是否是系统应用。
private void completeDrop(DragObject d) {
ItemInfo item = (ItemInfo) d.dragInfo;
int myAppInfoFlags = 0;
boolean wasWaitingForUninstall = mWaitingForUninstall;
mWaitingForUninstall = false;
if (isAllAppsApplication(d.dragSource, item)) {
// Uninstall the application if it is being dragged from AppsCustomize
AppInfo appInfo = (AppInfo) item;
mLauncher.startApplicationUninstallActivity(appInfo.componentName, appInfo.flags,
appInfo.user);
} else if (isUninstallFromWorkspace(d)) {
ShortcutInfo shortcut = (ShortcutInfo) item;
if (shortcut.intent != null && shortcut.intent.getComponent() != null) {
final ComponentName componentName = shortcut.intent.getComponent();
final DragSource dragSource = d.dragSource;
final UserHandleCompat user = shortcut.user;
/**
*获取手机中所有已安装的应用,根据包名,判断当前应用是否系统应用
*/
List<PackageInfo> packages = getContext().getPackageManager().getInstalledPackages(0);
for (int i = 0; i < packages.size(); i++) {
PackageInfo packageInfo = packages.get(i);
if (packageInfo.packageName.equals(componentName.getPackageName())) {
if ((packageInfo.applicationInfo.flags &
ApplicationInfo.FLAG_SYSTEM)==0) {
Log.e(TAG, "This is user app ");
myAppInfoFlags = 1;
}
}
}
mWaitingForUninstall = mLauncher.startApplicationUninstallActivity(
componentName, myAppInfoFlags, user);
//-------------------------------------------
// mWaitingForUninstall = mLauncher.startApplicationUninstallActivity(
// componentName, shortcut.flags, user);
if (mWaitingForUninstall) {
final Runnable checkIfUninstallWasSuccess = new Runnable() {
@Override
public void run() {
mWaitingForUninstall = false;
String packageName = componentName.getPackageName();
boolean uninstallSuccessful = !AllAppsList.packageHasActivities(
getContext(), packageName, user);
if (dragSource instanceof Folder) {
((Folder) dragSource).
onUninstallActivityReturned(uninstallSuccessful);
} else if (dragSource instanceof Workspace) {
((Workspace) dragSource).
onUninstallActivityReturned(uninstallSuccessful);
}
}
};
mLauncher.addOnResumeCallback(checkIfUninstallWasSuccess);
}
}
} else if (isWorkspaceOrFolderApplication(d)) {
LauncherModel.deleteItemFromDatabase(mLauncher, item);
} else if (isWorkspaceFolder(d)) {
// Remove the folder from the workspace and delete the contents from launcher model
FolderInfo folderInfo = (FolderInfo) item;
mLauncher.removeFolder(folderInfo);
LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
} else if (isWorkspaceOrFolderWidget(d)) {
// Remove the widget from the workspace
mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
LauncherModel.deleteItemFromDatabase(mLauncher, item);
final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
if ((appWidgetHost != null) && launcherAppWidgetInfo.isWidgetIdValid()) {
// Deleting an app widget ID is a void call but writes to disk before returning
// to the caller...
new AsyncTask<Void, Void, Void>() {
public Void doInBackground(Void... args) {
appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
}
if (wasWaitingForUninstall && !mWaitingForUninstall) {
if (d.dragSource instanceof Folder) {
((Folder) d.dragSource).onUninstallActivityReturned(false);
} else if (d.dragSource instanceof Workspace) {
((Workspace) d.dragSource).onUninstallActivityReturned(false);
}
}
}
4、修改isUninstallFromWorkspace方法,注释掉的代码是源码的返回方法,我只是把!给去掉了。然后就可以在workspace中卸载应用了。
private boolean isUninstallFromWorkspace(DragObject d) {
if (LauncherAppState.isDisableAllApps() && isWorkspaceOrFolderApplication(d)) {
ShortcutInfo shortcut = (ShortcutInfo) d.dragInfo;
// Only allow manifest shortcuts to initiate an un-install.
// return !InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent);
return InstallShortcutReceiver.isValidShortcutLaunchIntent(shortcut.intent);
}
return false;
}