一.第一种方案
1.1.将客户应用 内置到system/app 也就是将应用提升至系统级别 需要注意的是要将依赖lib库 拷贝到system/lib 下面
静默升级 也需要 更新 或者添加的库以前没有的库 建议:使用到不需要更新的apk 或者手动更新
二.第二种方案
2.1.预装应有 到system/preinstall 但不允许卸载 静默升级 推荐使用
仨.第二种方案 两种改法 OS Android5.1
3.1.Fist 改法
拖动到删除按钮 直接识别到可不包名不让卸载
diff --git a/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java index 449bfad..5d12be9 100755 --- a/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java +++ b/packages/apps/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java @@ -216,8 +216,13 @@ public class UninstallerActivity extends Activity implements OnCancelListener{ // Continue as the ActivityInfo isn't critical. } } - - showConfirmationDialog(); + + if((packageName != null)&& packageName.contains("com.gatsbt.life")){ + Log.d("gatsby","UninstallerActivity uninstall com.gatsby.fucklife"); + System.exit(0); + }else { + showConfirmationDialog(); + } } public void OnCreateDialog(){
3.2.Second 改法 识别包名不显示 卸载按钮
a.packages\apps\Launcher3\src\com\android\launcher3\DeleteDropTarget.java
boolean useDeleteLabel = !useUninstallLabel && source.supportsDeleteDropTarget();
if(info instanceof AppInfo){ AppInfo appInfo = (AppInfo) info; if(appInfo.componentName.getPackageName().equals("fuck.your.gatsby")){ useUninstallLabel = false; } }控制是否显示长按 “卸载” 的选项
@Override public void onDragStart(DragSource source, Object info, int dragAction) { boolean isVisible = true; boolean useUninstallLabel = !LauncherAppState.isDisableAllApps() && isAllAppsApplication(source, info); 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); } }
b. packages\apps\Settings\src\com\android\settings\applications\InstalledAppDetails.java
设置应用信息 卸载项目
mUninstallButton.setOnClickListener(this); 让点击无效
private void initUninstallButtons() { mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0; final boolean isBundled = (mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; boolean enabled = true; if (mUpdatedSysApp) { mUninstallButton.setText(R.string.app_factory_reset); boolean showSpecialDisable = false; if (isBundled) { showSpecialDisable = handleDisableable(mSpecialDisableButton); mSpecialDisableButton.setOnClickListener(this); } if (mAppControlRestricted) { showSpecialDisable = false; } mMoreControlButtons.setVisibility(showSpecialDisable ? View.VISIBLE : View.GONE); } else { mMoreControlButtons.setVisibility(View.GONE); if (isBundled) { enabled = handleDisableable(mUninstallButton); } else if ((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) == 0 && mUserManager.getUsers().size() >= 2) { // When we have multiple users, there is a separate menu // to uninstall for all users. mUninstallButton.setText(R.string.uninstall_text); enabled = false; } else { mUninstallButton.setText(R.string.uninstall_text); } } // If this is a device admin, it can't be uninstalled or disabled. // We do this here so the text of the button is still set correctly. if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) { enabled = false; } // Home apps need special handling. Bundled ones we don't risk downgrading // because that can interfere with home-key resolution. Furthermore, we // can't allow uninstallation of the only home app, and we don't want to // allow uninstallation of an explicitly preferred one -- the user can go // to Home settings and pick a different one, after which we'll permit // uninstallation of the now-not-default one. if (enabled && mHomePackages.contains(mPackageInfo.packageName)) { if (isBundled) { enabled = false; } else { ArrayList<ResolveInfo> homeActivities = new ArrayList<ResolveInfo>(); ComponentName currentDefaultHome = mPm.getHomeActivities(homeActivities); if (currentDefaultHome == null) { // No preferred default, so permit uninstall only when // there is more than one candidate enabled = (mHomePackages.size() > 1); } else { // There is an explicit default home app -- forbid uninstall of // that one, but permit it for installed-but-inactive ones. enabled = !mPackageInfo.packageName.equals(currentDefaultHome.getPackageName()); } } } if (mAppControlRestricted) { enabled = false; } mUninstallButton.setEnabled(enabled); if (enabled) { // Register listener mUninstallButton.setOnClickListener(this); } }