首页 > 代码库 > 4、应用设置之应用详情页

4、应用设置之应用详情页

转载请注明出处:http://blog.csdn.net/droyon/article/details/39892619


一、应用标题描述。

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。第一行“强制停止”,“停用/启用”
如果是用户更新的系统程序,则:

否则:


显示停用、启用还是卸载?
如果是系统应用,则
    在【mAppEntry.info.enabled  || mHomePackages.contains(mAppEntry.info.packageName) || isThisASystemPackage()】时显示“停用”
    否则显示“启用”
如果是非系统应用
显示卸载。
按钮是否可点击?
不可可点击的情况:应用含有系统签名 或者 应用中含有设备文件。
点击逻辑
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 = http://www.mamicode.com/false;>

四、缓存。

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);

4、应用设置之应用详情页