4、应用程序设置应用程序详细信息页面_系统应用

一、应用标题描写叙述。

1、应用程序版本号。

mAppVersion.setText(getActivity().getString(R.string.version_text,//版本号 <xliff:g id="VERSION_NUM">%1$s</xliff:g>
String.valueOf(pkgInfo.versionName))


二、强制停止、停用/启用/卸载。

1、强制停止。

不可点击情况:1、应用含有设备文件、2、当前应用已停止。

点击操作逻辑:

ActivityManager am = (ActivityManager)getActivity().getSystemService(
Context.ACTIVITY_SERVICE);
am.forceStopPackage(pkgName);
mState.invalidatePackage(pkgName);
ApplicationsState.AppEntry newEnt = mState.getEntry(pkgName);
if (newEnt != null) {
mAppEntry = newEnt;
}
checkForceStop();


2、停用/启用/卸载。

private void initUninstallButtons() {
mUpdatedSysApp = (mAppEntry.info.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;

// 有些系统应用是能够更新的,假设用户自己下载了一个系统的应用来更新了原来的,
// 它就不是系统应用啦,这个就是推断这样的情况的
//FLAG_UPDATED_SYSTEM_APP就是一个可升级的系统应用啦,但假设用户把它升级了。那么。就应该把它当成是用户的应用

boolean enabled = true;
if (mUpdatedSysApp) {//表示是系统程序,但用户更新过,也算是用户安装的程序
mUninstallButton.setText(R.string.app_factory_reset);//卸载更新
boolean specialDisable = false;
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
specialDisable = handleDisableable(mSpecialDisableButton);
mSpecialDisableButton.setOnClickListener(this);
}
mMoreControlButtons.setVisibility(specialDisable ? View.VISIBLE : View.GONE);
} else {
mMoreControlButtons.setVisibility(View.GONE);
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
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 uninstall or disabled.
// We do this here so the text of the button is still set correctly.
if (mDpm.packageHasActiveAdmins(mPackageInfo.packageName)) {
enabled = false;
}
mUninstallButton.setEnabled(enabled);
if (enabled) {
// Register listener
mUninstallButton.setOnClickListener(this);
}
}



1、是否是用户更新的系统程序


2、假设是。显示三个button。第一行“强制停止”,“卸载更新”。第二行“null”。“停用/启用”。


     假设否,显示两个button。第一行“强制停止”。“停用/启用”


假设是用户更新的系统程序。则:

4、应用程序设置应用程序详细信息页面_系统程序_02

否则:

4、应用程序设置应用程序详细信息页面_系统应用_03


显示停用、启用还是卸载?




假设是系统应用。则
在【mAppEntry.info.enabled || mHomePackages.contains(mAppEntry.info.packageName) || isThisASystemPackage()】时显示“停用”
否则显示“启用”
假设是非系统应用
显示卸载。



button是否可点击?



不可可点击的情况:应用含有系统签名 或者 应用中含有设备文件。

点击逻辑


return new AlertDialog.Builder(getActivity())
.setTitle(getActivity().getText(R.string.app_factory_reset_dlg_title))//要卸载更新吗?
.setIconAttribute(android.R.attr.alertDialogIcon)
.setMessage(getActivity().getText(R.string.app_factory_reset_dlg_text))//系统将会卸载此 Android 系统应用的全部相关更新。
.setPositiveButton(R.string.dlg_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Clear user data here
getOwner().uninstallPkg(getOwner().mAppEntry.info.packageName,
false, false);
}
})
.setNegativeButton(R.string.dlg_cancel, null)
.create();
点击处理逻辑
if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
if (mAppEntry.info.enabled) {
showDialogInner(DLG_DISABLE, 0);//停用
} else {
new DisableChanger(this, mAppEntry.info,
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)
.execute((Object)null);//启用
}
} else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
uninstallPkg(packageName, true, false);//卸载
} else {
uninstallPkg(packageName, false, false);
}

3、显示通知。


String packageName = mAppEntry.info.packageName;
INotificationManager nm = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
try {
final boolean enable = mNotificationSwitch.isChecked();
nm.setNotificationsEnabledForPackage(packageName, mAppEntry.info.uid, enabled);
} catch (android.os.RemoteException ex) {
mNotificationSwitch.setChecked(!enabled); // revert
}


三、存储。



1、总计:mAppEntry.size
2、应用:
codeSize = mAppEntry.codeSize;
if (Environment.isExternalStorageEmulated()) {
codeSize += mAppEntry.externalCodeSize;
}
3、USB存储(应用) = mAppEntry.externalCodeSize

4、数据 =
long dataSize = mAppEntry.dataSize;
if (Environment.isExternalStorageEmulated()) {
dataSize += mAppEntry.externalDataSize;
}
5、SD卡;
mAppEntry.externalDataSize

5.1、移动sd卡。

初始化
private void initMoveButton() {
if (Environment.isExternalStorageEmulated()) {
mMoveAppButton.setVisibility(View.INVISIBLE);
return;
}
boolean dataOnly = false;
dataOnly = (mPackageInfo == null) && (mAppEntry != null);
boolean moveDisable = true;
if (dataOnly) {
mMoveAppButton.setText(R.string.move_app);
} else if ((mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
mMoveAppButton.setText(R.string.move_app_to_internal);
// Always let apps move to internal storage from sdcard.
moveDisable = false;
} else {
mMoveAppButton.setText(R.string.move_app_to_sdcard);
mCanBeOnSdCardChecker.init();
moveDisable = !mCanBeOnSdCardChecker.check(mAppEntry.info);
}
if (moveDisable) {
mMoveAppButton.setEnabled(false);
} else {
mMoveAppButton.setOnClickListener(this);
mMoveAppButton.setEnabled(true);
}
}


点击逻辑
if (mPackageMoveObserver == null) {
mPackageMoveObserver = new PackageMoveObserver();
}
int moveFlags = (mAppEntry.info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0 ?
PackageManager.MOVE_INTERNAL : PackageManager.MOVE_EXTERNAL_MEDIA;
mMoveInProgress = true;
refreshButtons();
mPm.movePackage(mAppEntry.info.packageName, mPackageMoveObserver, moveFlags);


5.2、清楚数据。

初始化:
private void initDataButtons() {
// If the app doesn't have its own space management UI
// And it's a system app that doesn't allow clearing user data or is an active admin
// Then disable the Clear Data button.
if (mAppEntry.info.manageSpaceActivityName == null
&& ((mAppEntry.info.flags&(ApplicationInfo.FLAG_SYSTEM
| ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA))
== ApplicationInfo.FLAG_SYSTEM
|| mDpm.packageHasActiveAdmins(mPackageInfo.packageName))) {
mClearDataButton.setText(R.string.clear_user_data_text);
mClearDataButton.setEnabled(false);
mCanClearData = false;
} else {
if (mAppEntry.info.manageSpaceActivityName != null) {
mClearDataButton.setText(R.string.manage_space_text);
} else {
mClearDataButton.setText(R.string.clear_user_data_text);
}
mClearDataButton.setOnClickListener(this);
}
}

点击逻辑
private void initiateClearUserData() {
mClearDataButton.setEnabled(false);
// Invoke uninstall or clear user data based on sysPackage
String packageName = mAppEntry.info.packageName;
Log.i(TAG, "Clearing user data for package : " + packageName);
if (mClearDataObserver == null) {
mClearDataObserver = new ClearUserDataObserver();
}
ActivityManager am = (ActivityManager)
getActivity().getSystemService(Context.ACTIVITY_SERVICE);
boolean res = am.clearApplicationUserData(packageName, mClearDataObserver);
if (!res) {
// Clearing data failed for some obscure reason. Just log error for now
Log.i(TAG, "Couldnt clear application user data for package:"+packageName);
showDialogInner(DLG_CANNOT_CLEAR_DATA, 0);
} else {
mClearDataButton.setText(R.string.recompute_size);
}
}


四、缓存。



1、缓存:
mAppEntry.cacheSize + mAppEntry.externalCacheSize;


2、点击清楚缓存
if (mClearCacheObserver == null) {
mClearCacheObserver = new ClearCacheObserver();
}
mPm.deleteApplicationCacheFiles(packageName, mClearCacheObserver);


五、默认启动。



1、默认启动
得到优先设置项mPm.getPreferredActivities(intentList, prefActList, packageName);

是否含有usb默认项设置:hasUsbDefaults = mUsbManager.hasDefaults(packageName, UserHandle.myUserId());

是否绑定权限:boolean hasBindAppWidgetPermission =
mAppWidgetManager.hasBindAppWidgetPermission(mAppEntry.info.packageName);

2、清楚默认设置

<span style="white-space:pre"> </span> mPm.clearPackagePreferredActivities(packageName);
try {
mUsbManager.clearDefaults(packageName, UserHandle.myUserId());
} catch (RemoteException e) {
Log.e(TAG, "mUsbManager.clearDefaults", e);
}
mAppWidgetManager.setBindAppWidgetPermission(packageName, false);
TextView autoLaunchTitleView =
(TextView) mRootView.findViewById(R.id.auto_launch_title);//无默认设置。
TextView autoLaunchView = (TextView) mRootView.findViewById(R.id.auto_launch);
resetLaunchDefaultsUi(autoLaunchTitleView, autoLaunchView);