最近做一个电视盒子上的需求,要求
1、显示当前盒子中:所有APK、已下载的三方APK、正在运行中的APK
2、点击APK选项,弹出该APK的详情页面;
3、详情页面包含:应用大小、缓存大小、数据大小、图标、版本号;
4、功能上包含:打开apk、停止apk、清理缓存、清理数据、卸载apk;
最终实现效果如下:
all_app.png app_dialog.png
实现过程中,主要用到PackageManager和ActivityManager,函数多是hide函数,需要用反射调用;
具体函数封装如下:
/**
* 获取系统全部应用
*
* @return
*/
private ArrayList<AppInfo> getAllApps() {
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
ArrayList<AppInfo> arrayList = new ArrayList<AppInfo>();
for (PackageInfo packageInfo : packs) {
AppInfo appInfo = new AppInfo(context);
appInfo.appname = packageInfo.applicationInfo.loadLabel(packageManager).toString();
appInfo.pname = packageInfo.packageName;
appInfo.version = new StringBuilder(String.valueOf(packageInfo.versionName)).toString();
appInfo.icon = packageInfo.applicationInfo.loadIcon(packageManager);
getPackageSize(context, appInfo);
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
//三方应用
if (debug) Log.d(TAG, appInfo.appname + "是 :三方应用");
appInfo.iscore = false;
if (appInfo.pname.contains("com.amlogic.miracast")
|| appInfo.pname.contains("com.amlogic.mediacenter")
|| appInfo.pname.contains("com.droidapp.mediaserver")) {
appInfo.iscore = true;
continue;
}
arrayList.add(appInfo);
} else {
//系统应用
if (debug) Log.d(TAG, appInfo.appname + "是 :系统应用");
appInfo.iscore = true;
if (appInfo.pname.contains("smart")
|| appInfo.pname.contains("com.android.settings")
|| appInfo.pname.contains("icntv.ott")
|| appInfo.pname.contains("BrandTestJT")) {
arrayList.add(appInfo);
}
}
}
return arrayList;
}
/**
* 获取第三方应用
*
* @return
*/
private ArrayList<AppInfo> getInstalledApps() {
List<PackageInfo> packs = packageManager.getInstalledPackages(0);
ArrayList<AppInfo> arrayList = new ArrayList<AppInfo>();
for (PackageInfo packageInfo : packs) {
AppInfo appInfo = new AppInfo(context);
appInfo.appname = packageInfo.applicationInfo.loadLabel(packageManager).toString();
appInfo.pname = packageInfo.packageName;
appInfo.version = new StringBuilder(String.valueOf(packageInfo.versionName)).toString();
appInfo.icon = packageInfo.applicationInfo.loadIcon(packageManager);
getPackageSize(context, appInfo);
if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
//三方应用
if (appInfo.pname.contains("com.amlogic.miracast")
|| appInfo.pname.contains("com.amlogic.mediacenter")
|| appInfo.pname.contains("com.droidapp.mediaserver")) {
appInfo.iscore = true;
continue;
}
if (debug) Log.d(TAG, appInfo.appname + "是 :三方应用");
appInfo.iscore = false;
arrayList.add(appInfo);
} else {
//系统应用
if (debug) Log.d(TAG, appInfo.appname + "是 :系统应用");
appInfo.iscore = true;
}
}
return arrayList;
}
/**
* 获取正在运行的app
*
* @return
*/
private ArrayList<AppInfo> getRunningApps() {
ArrayList<AppInfo> arrayList = new ArrayList<AppInfo>();
List<RunningAppProcessInfo> run = activityManager.getRunningAppProcesses();
list_all = getAllApps();//获取全部app
for (AppInfo appInfo : list_all) {
for (RunningAppProcessInfo runInfo : run) {
if (appInfo.pname.equals(runInfo.processName)) {
if (debug) Log.d(TAG, "正在运行的app = " + appInfo.appname);
arrayList.add(appInfo);
}
}
}
return arrayList;
}
/**
* 获取APK的缓存大小、数据大小、应用大小、总大小
*
* @param context
* @param appInfo
*/
public static void getPackageSize(final Context context, final AppInfo appInfo) {
Method method;
String pkgName = appInfo.pname;
try {
method = PackageManager.class.getMethod("getPackageSizeInfo", new Class[]{String.class, IPackageStatsObserver.class});
// 调用 getPackageSizeInfo 方法,需要两个参数:1、需要检测的应用包名;2、回调
method.invoke(context.getPackageManager(), pkgName,
new IPackageStatsObserver.Stub() {
@Override
public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {
if (succeeded && pStats != null) {
synchronized (AppInfo.class) {
appInfo.setCatchSize(pStats.cacheSize);//缓存大小
appInfo.setDataSize(pStats.dataSize); //数据大小
appInfo.setCodeSize(pStats.codeSize); //应用大小
appInfo.setAppSize(pStats.cacheSize + pStats.codeSize + pStats.dataSize);//应用的总大小
if (debug)
Log.d(TAG, "CatchSize = " + appInfo.cacheSize + " ,DataSize = "
+ appInfo.dataSize + " ,CodeSize = " + appInfo.codeSize
+ " ,AppSize = " + appInfo.appSize);
}
}
}
});
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 卸载App
*/
private void unInstallApp() {
Uri uri = Uri.fromParts("package", appInfo.pname, null);
Intent intent = new Intent(Intent.ACTION_DELETE, uri);
mContext.startActivity(intent);
}
/**
* 打开app
*/
private void openApp() {
PackageManager packageManager = mContext.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(appInfo.pname);
mContext.startActivity(intent);
}
/**
* 强制停止app
*/
private void stopApp() {
Method method;
try {
Log.d(TAG, "stopApp() --- " + appInfo.pname);
method = ActivityManager.class.getMethod("forceStopPackage", String.class);
method.invoke(activityManager, appInfo.pname);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
Toast.makeText(mContext, R.string.cant_foce_close_app, Toast.LENGTH_SHORT).show();
}
}
/**
* 清理缓存和数据
* @return
*/
private boolean clearCache() {
Method method;
try {
method = ActivityManager.class.getMethod("clearApplicationUserData", new Class[]{String.class, IPackageDataObserver.class});
method.invoke(activityManager, appInfo.pname, new IPackageDataObserver() {
@Override
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
Log.e(TAG, packageName + ",clearCache() ---------- " + succeeded);
}
@Override
public IBinder asBinder() {
return null;
}
});
appInfo.setCatchSize(0);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
return false;
}
return true;
}
网友评论