DownOL 软件仓库– 软件下载,字节世界与新知

不用Root就对App进行查看分享的工具

发表于:2024-04-30 作者:创始人
编辑最后更新 2024年04月30日,今天看到一个项目,从图中可以看到,无需root进行app的一些操作,从中我们可以获取一些常规信息1,获取应用最近使用的pkg信息public static List getUsageStatsList

今天看到一个项目,从图中可以看到,无需root进行app的一些操作,从中我们可以获取一些常规信息

1,获取应用最近使用的pkg信息

public static List getUsageStatsList(Context context){UsageStatsManager usm = getUsageStatsManager(context);Calendar calendar = Calendar.getInstance(); long endTime = calendar.getTimeInMillis(); long startTime = calendar.getTimeInMillis()-60*60*1000;List usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime); return usageStatsList;}

2,通过ProcessManage获取正在运行app包信息列表

public static List getRunningAppProcessInfo(Context context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {List runningAppProcesses = AndroidProcesses.getRunningAppProcesses();List appProcessInfos = new ArrayList<>(); for (AndroidAppProcess process : runningAppProcesses) {RunningAppProcessInfo info = new RunningAppProcessInfo(process.name, process.pid, null);info.uid = process.uid;// TODO: Get more information about the process. pkgList, importance, lru, etc.appProcessInfos.add(info);}return appProcessInfos;}ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); return am.getRunningAppProcesses();}

3,对包管理更多工具

/** Copyright (c) 2015 GuDong** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in all* copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE* SOFTWARE.*/package com.gudong.appkit.dao;import android.annotation.TargetApi;import android.app.ActivityManager;import android.app.usage.UsageStats;import android.app.usage.UsageStatsManager;import android.content.Context;import android.content.Intent;import android.content.pm.ActivityInfo;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.content.pm.ResolveInfo;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.os.Build;import com.gudong.appkit.App;import com.gudong.appkit.utils.RxUtil;import com.gudong.appkit.utils.Utils;import com.gudong.appkit.utils.logger.Logger;import com.jaredrummler.android.processes.models.AndroidProcess;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Calendar;import java.util.List;import java.util.concurrent.Callable;import rx.Observable;/*** 获取app信息的引擎* Created by mao on 15/7/8.*/public class AppInfoEngine {private Context mContext; private PackageManager mPackageManager; private static class SingletonHolder{private static final AppInfoEngine INSTANCE = new AppInfoEngine(App.sContext);}public static AppInfoEngine getInstance(){return SingletonHolder.INSTANCE;}private AppInfoEngine(Context context) {this.mContext = context;mPackageManager = mContext.getApplicationContext().getPackageManager();}/** * get all app info list which is installed by user * @return all installed app info list */public Observable> getInstalledAppList() {return RxUtil.makeObservable(new Callable>() {@Overridepublic List call() throws Exception {List list = new ArrayList<>();ListpackageInfos = mPackageManager.getInstalledPackages(PackageManager.GET_META_DATA); for (PackageInfo info:packageInfos){if(!isUserApp(info))continue;AppEntity entity = warpAppEntity(info); if (entity == null)continue;;list.add(entity);}return list;}});}/** * get installed AppEntity by packageName * @param packageName Application's package name * @return installed app if not found package name will return null */public AppEntity getAppByPackageName(String packageName){ListpackageInfos = mPackageManager.getInstalledPackages(PackageManager.GET_META_DATA); for (PackageInfo packageInfo : packageInfos) {if(!isUserApp(packageInfo))continue; if(packageName.equals(packageInfo.packageName)){return warpAppEntity(packageInfo);}}return null;}/** * get recent running app list * @return recent running app list */@Deprecatedpublic List getRecentAppList() {List list = new ArrayList<>();ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);List recentTasks = mActivityManager.getRecentTasks(10, 0); for (ActivityManager.RecentTaskInfo taskInfo : recentTasks) {Intent intent = taskInfo.baseIntent;ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0); if (resolveInfo == null)continue;String packageName = resolveInfo.activityInfo.packageName; if (isSystemApp(packageName)) continue; if (isShowSelf(packageName)) continue;AppEntity appEntity = DataHelper.getAppByPackageName(packageName); if (appEntity == null)continue;list.add (appEntity);}return list;}/** * check running list should show AppPlus or not * @param packagename* @return true if show else false */private boolean isShowSelf(String packagename){return !Utils.isShowSelf() && packagename.equals(mContext.getPackageName());}/** * check package is system app or not * @param packageName* @return if package is system app return true else return false */private boolean isSystemApp(String packageName){try {PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);ApplicationInfo applicationInfo = packageInfo.applicationInfo; if(applicationInfo == null)return false; return ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);} catch (PackageManager.NameNotFoundException e) {e.printStackTrace(); return false;}}boolean isUserApp(PackageInfo packageInfo) {if(packageInfo == null)return false; int mask = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; return (packageInfo.applicationInfo.flags & mask) == 0;}private boolean isSelf(String packageName) {return packageName.equals(mContext.getPackageName());}//////////////////////// Android L ///////////////////////////////////@Deprecated @TargetApi(Build.VERSION_CODES.LOLLIPOP)public List getUsageStatsList(){UsageStatsManager usm = getUsageStatsManager();Calendar calendar = Calendar.getInstance(); long endTime = calendar.getTimeInMillis();calendar.add(Calendar.MONTH, -1); long startTime = calendar.getTimeInMillis();List usageStatsList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY,startTime,endTime); return usageStatsList;}@Deprecated @TargetApi(Build.VERSION_CODES.LOLLIPOP)public List getRecentAppInfo(){List usageStatsList = getUsageStatsList();List list = new ArrayList<>(); for (UsageStats u : usageStatsList){String packageName = u.getPackageName();ApplicationInfo applicationInfo = getAppInfo(packageName);//system app will not appear recent list //if(isSystemApp(packageName))continue;if (isShowSelf(packageName)) continue;AppEntity entity = DataHelper.getAppByPackageName(packageName); if (entity == null)continue;list.add (entity);}return list;}@SuppressWarnings("ResourceType")@Deprecatedprivate UsageStatsManager getUsageStatsManager(){UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService("usagestats"); return usm;}/** * make PackageInfo warp to AppEntity * @param packageInfo PackageInfo * @return AppEntity */private AppEntity warpAppEntity(PackageInfo packageInfo){if (packageInfo == null)return null;AppEntity entity = new AppEntity();entity.setAppName(mPackageManager.getApplicationLabel(packageInfo.applicationInfo).toString());entity.setPackageName(packageInfo.packageName);Bitmap iconBitmap = drawableToBitmap(mPackageManager.getApplicationIcon(packageInfo.applicationInfo));entity.setAppIconData(formatBitmapToBytes(iconBitmap));entity.setSrcPath(packageInfo.applicationInfo.sourceDir);entity.setVersionName(packageInfo.versionName);entity.setVersionCode(packageInfo.versionCode);entity.setUid(packageInfo.applicationInfo.uid); return entity;}//根据包名获取对应的ApplicationInfo 信息private ApplicationInfo getAppInfo(String packageName){ApplicationInfo appInfo = null; try {appInfo = mPackageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA);} catch (PackageManager.NameNotFoundException e) {e.printStackTrace(); return null;}return appInfo;}/** * 将Drawable转化为Bitmap * @param drawable* @return*/private static Bitmap drawableToBitmap (Drawable drawable) {Bitmap bitmap = null; if (drawable instanceof BitmapDrawable) {BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; if(bitmapDrawable.getBitmap() != null) {return bitmapDrawable.getBitmap();}}if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel} else {bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);}Canvas canvas = new Canvas(bitmap);drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());drawable.draw(canvas); return bitmap;}public List getRecentAppListV1() {List list = new ArrayList<>();ActivityManager mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);List recentTasks = mActivityManager.getRecentTasks(10, 0); for (ActivityManager.RecentTaskInfo taskInfo : recentTasks) {Intent intent = taskInfo.baseIntent;ResolveInfo resolveInfo = mPackageManager.resolveActivity(intent, 0); if (resolveInfo == null)continue; if (isSystemApp(resolveInfo.resolvePackageName)) continue;ActivityInfo activityInfo = resolveInfo.activityInfo; if(activityInfo==null)continue; if (isShowSelf(activityInfo.packageName)) continue;AppEntity entity = new AppEntity();Bitmap bitmap = drawableToBitmap(resolveInfo.loadIcon(mPackageManager));entity.setAppIconData(formatBitmapToBytes(bitmap));entity.setAppName(resolveInfo.loadLabel(mPackageManager).toString());entity.setPackageName(activityInfo.packageName);ApplicationInfo applicationInfo = activityInfo.applicationInfo; if (applicationInfo == null)continue; if(applicationInfo.publicSourceDir!= null){entity.setSrcPath(applicationInfo.publicSourceDir);}list.add(entity);}return list;}private byte[] formatBitmapToBytes(Bitmap bitmap){ByteArrayOutputStream bos = new ByteArrayOutputStream();bitmap.compress(Bitmap.CompressFormat.PNG,100,bos); try {bos.close();} catch (IOException e) {e.printStackTrace();}return bos.toByteArray();}public void getRunningProcesses(){Listlist = new ArrayList<>();File[]files = new File("/proc").listFiles(); for (File file:files){if(file.isDirectory()){int pid; try{pid = Integer.parseInt(file.getName());AndroidProcess process = new AndroidProcess(pid);Logger.i("pid is "+file.getName() +" name is "+process.name);list.add(process);}catch (NumberFormatException e){continue;} catch (IOException e) {e.printStackTrace();}}}}}

4,换肤

/** Copyright (c) 2015 GuDong** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in all* copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE* SOFTWARE.*/package com.gudong.appkit.ui.control;import android.content.Context;import com.gudong.appkit.R;import com.gudong.appkit.utils.Utils;/*** 主题控制类* Created by mao on 7/16/15.*/public class ThemeControl {private Context mContext; private int mCurrentTheme; public ThemeControl(Context context){this.mContext = context;isChanged(); // invalidate stored booleans}public int getTheme(Context context){return Utils.getIntPreference(context, "theme", R.style.Theme_AppPlus);}public void setTheme(int theme){Utils.putIntPreference(mContext, "theme", theme);}/** * 记住用户选择的主题颜色对应的position * @param position 用户已选择position */public void setThemePosition(int position){Utils.putIntPreference(mContext, "themePosition", position);}public int getThemePosition(){return Utils.getIntPreference(mContext,"themePosition",4);}public boolean isChanged() {int currentTheme = getTheme(mContext); boolean isChange = mCurrentTheme != currentTheme;mCurrentTheme = currentTheme; return isChange;}/** * 自定义的主题数组,每一种颜色对应了夜间模式和日间模式 * 目前夜间模式已经不做了,所以对应的主题在目前项目中是用不到的 * @return*/public static int[]themeArr(){return new int[]{R.style.LightRed,R.style.LightPink,R.style.LightPurple,R.style.LightDeepPurple,R.style.LightIndigo,R.style.LightBlue,R.style.LightLightBlue,R.style.LightCyan,R.style.LightTeal,R.style.LightGreen,R.style.LightLightGreen,R.style.LightLime,R.style.LightYellow,R.style.LightAmber,R.style.LightOrange,R.style.LightDeepOrange,R.style.LightBrown,R.style.LightGrey,R.style.LightBlueGrey,};}}

5,对apk的一些操作

/** Copyright (c) 2015 GuDong** Permission is hereby granted, free of charge, to any person obtaining a copy* of this software and associated documentation files (the "Software"), to deal* in the Software without restriction, including without limitation the rights* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell* copies of the Software, and to permit persons to whom the Software is* furnished to do so, subject to the following conditions:** The above copyright notice and this permission notice shall be included in all* copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE* SOFTWARE.*/package com.gudong.appkit.utils;import android.app.Activity;import android.content.DialogInterface;import android.content.Intent;import android.net.Uri;import android.os.Build;import android.os.Bundle;import android.support.design.widget.Snackbar;import android.support.v7.app.AlertDialog;import android.view.LayoutInflater;import android.view.View;import android.widget.ProgressBar;import android.widget.TextView;import com.gudong.appkit.R;import com.gudong.appkit.dao.AppEntity;import com.gudong.appkit.event.EEvent;import com.gudong.appkit.event.RxBus;import com.gudong.appkit.event.RxEvent;import com.gudong.appkit.ui.activity.MainActivity;import com.gudong.appkit.ui.control.NavigationManager;import com.gudong.appkit.view.CircularProgressDrawable;import java.io.File;import java.io.IOException;import rx.android.schedulers.AndroidSchedulers;import rx.functions.Action1;import rx.schedulers.Schedulers;/*** 常用操作工具类 如传送APK 导出APK等操作*/public class ActionUtil {/** * 传送安装包 * @param entity*/public static void shareApk(Activity activity, AppEntity entity) {final File srcFile = new File(entity.getSrcPath()); if(!srcFile.exists()){Snackbar.make(activity.getWindow().getDecorView(),String.format(activity.getString(R.string.fail_share_app),entity.getAppName()),Snackbar.LENGTH_LONG).show(); return;}Intent intent = new Intent();intent.setAction(Intent.ACTION_SEND);intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(new File(entity.getSrcPath())));intent.setType("application/vnd.android.package-archive");intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);activity.startActivity(Intent.createChooser(intent, FormatUtil.warpChooserTitle(activity,entity.getAppName())));}/** * 安装APK * @param entity*/public static void installApp(Activity activity, AppEntity entity) {final File srcFile = new File(entity.getSrcPath()); if(!srcFile.exists()){Snackbar.make(activity.getWindow().getDecorView(),String.format(activity.getString(R.string.fail_install_app),entity.getAppName()),Snackbar.LENGTH_LONG).show(); return;}Intent mIntent = new Intent();mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mIntent.setAction(Intent.ACTION_VIEW);mIntent.setDataAndType(Uri.fromFile(srcFile),"application/vnd.android.package-archive");activity.startActivity(mIntent);}/** * export apk file * @param entity*/public static void exportApk(final Activity activity,AppEntity entity) {//判断sd卡是否挂载if (!FileUtil.isSdCardOnMounted()) {DialogUtil.showSinglePointDialog(activity, activity.getString(R.string.dialog_message_no_sdcard)); return;}final File srcFile = new File(entity.getSrcPath()); if(!srcFile.exists()){Snackbar.make(activity.getWindow().getDecorView(),String.format(activity.getString(R.string.fail_export_app),entity.getAppName()),Snackbar.LENGTH_LONG).show(); return;}File exportParentFile = FileUtil.createDir(FileUtil.getSDPath(),FileUtil.KEY_EXPORT_DIR);String exportFileName = entity.getAppName().concat("_").concat(entity.getVersionName()).concat(".apk"); final File exportFile = new File(exportParentFile, exportFileName);String contentInfo = String.format(activity.getString(R.string.dialog_message_file_exist), exportFileName, exportFile.getParentFile().getAbsolutePath()); if (exportFile.exists()) {new AlertDialog.Builder(activity).setTitle(R.string.title_point).setMessage(contentInfo).setPositiveButton(R.string.dialog_action_exist_not_override, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {}}).setNegativeButton(R.string.dialog_action_exist_override, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {copyFile(activity,srcFile, exportFile);}}).setNeutralButton(R.string.dialog_action_exist_watch_now, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {NavigationManager.browseFile(activity,exportFile.getParentFile());}}).show();} else {String pointInfo = String.format(activity.getString(R.string.dialog_message_export),entity.getAppName(),exportFile.getParentFile().getAbsolutePath()); new AlertDialog.Builder(activity).setTitle(R.string.title_point).setMessage(pointInfo).setPositiveButton(R.string.dialog_confirm_export, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {copyFile(activity,srcFile, exportFile);}}).setNegativeButton(R.string.dialog_cancel,null).show();}}public static void deleteApkFile(final Activity activity, final AppEntity entity){String pointInfo = String.format(activity.getString(R.string.dialog_message_delete),entity.getAppName()); new AlertDialog.Builder(activity).setTitle(R.string.title_point).setMessage(pointInfo).setPositiveButton(R.string.dialog_confirm_delete, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {if(FileUtil.deleteExportedFile(entity)){Bundle data = new Bundle();data.putParcelable("entity",entity);RxBus.getInstance().send(new RxEvent(EEvent.DELETE_SINGLE_EXPORT_FILE_SUC,data));}else{RxBus.getInstance().send(RxEvent.get(EEvent.DELETE_SINGLE_EXPORT_FILE_FAIL));}}}).setNegativeButton(R.string.dialog_cancel,null).show();}private static void copyFile(final Activity activity,File srcFile, final File exportFile) {View view = LayoutInflater.from(activity).inflate(R.layout.dialog_progress, null);ProgressBar progressBar = (ProgressBar) view.findViewById(android.R.id.progress);TextView textView = (TextView) view.findViewById(R.id.content);//改变Progress的背景为MaterialDesigner规范的样式if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {progressBar.setIndeterminateDrawable(new CircularProgressDrawable(Utils.getColorWarp(activity, R.color.colorAccent), activity.getResources().getDimension(R.dimen.loading_border_width)));}final AlertDialog progressDialog = DialogUtil.getProgressDialog(activity,activity.getString(R.string.title_point),activity.getString(R.string.please_wait));progressDialog.show(); try {FileUtil.copyFileUsingFileChannelsAsyn(srcFile, exportFile).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() {@Overridepublic void call(Boolean aBoolean) {progressDialog.dismiss();String contentInfo = String.format(activity.getString(R.string.dialog_message_export_finish), exportFile.getName(), exportFile.getParentFile().getAbsolutePath()); new AlertDialog.Builder(activity).setTitle(R.string.title_export_finish).setMessage(contentInfo).setPositiveButton(R.string.dialog_confirm_watch, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {RxBus.getInstance().send(new RxEvent(EEvent.OPEN_EXPORT_DIR)); if(!(activity instanceof MainActivity)){activity.finish();}}}).setNegativeButton(R.string.dialog_cancel_watch, null).show();}});} catch (IOException e) {e.printStackTrace();}}}

好了 就这么多 这里有很多冷门东西,可以以后开发中用到作为工具

2022-05-09 22:07:09
0