获取已安装应用程序信息
通过Activity的getPackageManager()方法可以得到PackageManager的对象
1.PackageManager 的getInstalledPackages(int flags)方法可以得到所有安装在机器上的程序的包信息类对象List<PackageInfo>,PackageInfo类中有一值applicationInfo可以得到Application的对象。
2.PackageManager的getInstalledApplications(int flags)方法可以得到所有安装在机器上的程序的application对象List<ApplicationInfo>;
Application类继承类PackageItemInfo,在PackageItemInfo类中有方法loadIcon(PackageManager pm)返回应用程序图标Drawable类型。有方法loadLabel(PackageManager pm)返回应用程序名称,CharSequence类型。
ApplicationInfo中无法获取版本号和版本名。PackageInfo类中有包名、版本名、版本号。
如果只需要安装程序的名字和图片而不需要版本号和版本名信息,用方法2获取ApplicationInfo。如果都需要,用方法1获取PackageInfo,再通过PackageInfo获取ApplicationInfo。
PackageItemInfo中有值
public int | icon | : A drawable resource identifier (in the package's resources) of this component's icon. |
public int | labelRes | : A string resource identifier (in the package's resources) of this component's label. |
是int型,基本用不上。
public String | packageName | : Name of the package that this item is in. |
这个是程序的包名,也就是说,可以在ApplicationInfo对象中得到安装程序的图片名字和包名。版本号和版本名只能在PackageInfo中获得。ApplicationInfo与PackageInfo中都能得到包名!
程序名和图片还可以通过PackageManager类获得,PackageManager有方法getApplicationIcon(String packageName)和getApplicationIcon(ApplicationInfo info)都可以获得应用程序的图片,getApplicationLabel(ApplicationInfo info)方法可以获得应用程序的名字。
下面这段代码可以得到所有已安装应用启动程序的Activity的信息,即Main Activity Info:
PackageManager pm = getPackageManager(); Intent filter = new Intent(Intent.ACTION_MAIN); filter.addCategory(Intent.CATEGORY_LAUNCHER); List<ResolveInfo>list = pm.queryIntentActivities(filter, PackageManager.GET_RESOLVED_FILTER);启动手机里的第1个程序:
ComponentName cn =new ComponentName(list.get(0).activityInfo.packageName, list.get(0).activityInfo.name); Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); intent.setComponent(cn); startActivity(intent);
获取apk文件信息:
public static AppInfo getApkFileInfo(Context ctx, String apkPath) { // System.out.println(apkPath); long q=System.currentTimeMillis(); File apkFile = new File(apkPath); if (!apkFile.exists() || !apkPath.toLowerCase().endsWith(".apk")) { System.out.println("文件路径不正确"); return null; } AppInfo appInfoData; String PATH_PackageParser = "android.content.pm.PackageParser"; String PATH_AssetManager = "android.content.res.AssetManager"; try { //反射得到pkgParserCls对象并实例化,有参数 Class<?> pkgParserCls = Class.forName(PATH_PackageParser); Class<?>[] typeArgs = {String.class}; Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs); Object[] valueArgs = {apkPath}; Object pkgParser = pkgParserCt.newInstance(valueArgs); //从pkgParserCls类得到parsePackage方法 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults();//这个是与显示有关的, 这边使用默认 typeArgs = new Class<?>[]{File.class,String.class, DisplayMetrics.class,int.class}; Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod( "parsePackage", typeArgs); valueArgs=new Object[]{new File(apkPath),apkPath,metrics,0}; //执行pkgParser_parsePackageMtd方法并返回 Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs); //从返回的对象得到名为"applicationInfo"的字段对象 if (pkgParserPkg==null) { return null; } Field appInfoFld = pkgParserPkg.getClass().getDeclaredField( "applicationInfo"); //从对象"pkgParserPkg"得到字段"appInfoFld"的值 if (appInfoFld.get(pkgParserPkg)==null) { return null; } ApplicationInfo info = (ApplicationInfo) appInfoFld .get(pkgParserPkg); //反射得到assetMagCls对象并实例化,无参 Class<?> assetMagCls = Class.forName(PATH_AssetManager); Object assetMag = assetMagCls.newInstance(); //从assetMagCls类得到addAssetPath方法 typeArgs = new Class[1]; typeArgs[0] = String.class; Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod( "addAssetPath", typeArgs); valueArgs = new Object[1]; valueArgs[0] = apkPath; //执行assetMag_addAssetPathMtd方法 assetMag_addAssetPathMtd.invoke(assetMag, valueArgs); //得到Resources对象并实例化,有参数 Resources res = ctx.getResources(); typeArgs = new Class[3]; typeArgs[0] = assetMag.getClass(); typeArgs[1] = res.getDisplayMetrics().getClass(); typeArgs[2] = res.getConfiguration().getClass(); Constructor<Resources> resCt = Resources.class .getConstructor(typeArgs); valueArgs = new Object[3]; valueArgs[0] = assetMag; valueArgs[1] = res.getDisplayMetrics(); valueArgs[2] = res.getConfiguration(); res = (Resources) resCt.newInstance(valueArgs); // 读取apk文件的信息 appInfoData = new AppInfo(); if (info!=null) { if (info.icon != 0) {// 图片存在,则读取相关信息 Drawable icon = res.getDrawable(info.icon);// 图标 appInfoData.setImage(icon); } else//若从apk文件里读取不出图片,则用默认图片填补image空白。 { appInfoData.setImage(res.getDrawable(R.drawable.ic_launcher)); } //若label标签没有,则名字为文件名 if (info.labelRes != 0) { String neme = (String) res.getText(info.labelRes);// 名字 appInfoData.setName(neme); }else { String apkName=apkFile.getName(); appInfoData.setName(apkName.substring(0,apkName.lastIndexOf("."))); } String pkgName = info.packageName;// 包名 appInfoData.setPackagename(pkgName); }else { return null;//读不出info信息而返回空,影响待测。 } PackageManager pm = ctx.getPackageManager(); PackageInfo packageInfo = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); if (packageInfo != null) { appInfoData.setVersion(packageInfo.versionName);//版本号 // appInfoData.setAppversionCode(packageInfo.versionCode+"");//版本码 } //取得apk文件大小 File f=new File(apkPath); if(f.length()/1024>1024) { appInfoData.setFilesize(f.length()/(1024*1024)+"M"); } else { appInfoData.setFilesize(f.length()/1024+"kb"); } appInfoData.setApkpath(apkPath); System.out.println(System.currentTimeMillis()-q); return appInfoData; } catch (Exception e) { e.printStackTrace(); } return null; }
上面的方法是以前百度搜的,的确有效,用的是java的反射实现的,当时没看懂,现在明白了是代码中很多没用的代码,不建议试用上面的代码,使用下面的代码:
public static Drawable getApkIcon(Context context, String apkPath) { PackageManager pm = context.getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_ACTIVITIES); if (info != null) { ApplicationInfo appInfo = info.applicationInfo; appInfo.sourceDir = apkPath; appInfo.publicSourceDir = apkPath; try { return appInfo.loadIcon(pm); } catch (OutOfMemoryError e) { Log.e("ApkIconLoader", e.toString()); } } return null; }
--------------------------------------------------------------------获取拥有某权限的应用列表---------------------------------------------------------------------------
public List<PackageInfo> getAppListByPermission(String permissionName){ List<PackageInfo> appinfos = new ArrayList<PackageInfo>(); PackageManager mPackageManager = getPackageManager(); List<PackageInfo> mPackageInfo = mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS); // false framework switch for(int i=0;i< mPackageInfo.size(); i++) { String[] mPermissions; // ignore local application ,keep third_party application stay if((mPackageInfo.get(i).applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0 ) { Log.d("ss","OnePermissionTOApplicationList " + mPackageInfo.get(i).applicationInfo.flags + " " + ApplicationInfo.FLAG_SYSTEM); continue; } // ignore local application ,keep third_party application stay try { mPermissions = mPackageManager.getPackageInfo(mPackageInfo.get(i).packageName, PackageManager.GET_PERMISSIONS).requestedPermissions; if( mPermissions != null) { for(int j=0; j< mPermissions.length; j++) { if(permissionName.equals(mPermissions[j])) { appinfos.add(mPackageInfo.get(i)); } } } }catch (Exception e) { } } return appinfos; }