Android PackageManager 用法

Android 11.0 PackageManagerService(一)工作原理和启动流程 1. 概述 PackageManagerService是Android系统核心服务之一,也是Android中最常用的服务之一。它主要负责的工作如下: 1. 解析AndroidManifest.xml文件,解析清单文件中的所有节点信息。 2. 扫描.apk文件,安装系统应用,本地应用等。 3. 管理本地应用,主要有:安装、卸载、应用信息查询等。 2. 核心源码 /frameworks/base/core/java/android/app/ApplicationP... 阅读详情

参考资料:http://blog.youkuaiyun.com/qinjuning/article/details/6867806,有改动。

PackageManger的主要职责是管理应用程序包,通过它可以获取应用程序信息。


AnroidManifest.xml文件节点说明:



一 、相关类介绍

1. PackageItemInfo类

AndroidManifest.xml文件中所有节点的基类,并不直接使用,而是由子类继承然后调用相应方法。

常用字段:

int icon             资源图片在R文件中的值 (对应于android:icon属性)
int labelRes         label在R文件中的值(对应于android:label属性)
String name          节点的name值 (对应于android:name属性)
String packagename   应用程序的包名 (对应于android:packagename属性)

常用方法:
Drawable loadIcon(PackageManager pm)          获得当前应用程序的图标
CharSequence loadLabel(PackageManager pm)     获得当前应用程序的label,从上图可知是app_name

PackageItemInfo继承关系图:


2. ActivityInfo类

<activity>或者 <receiver>节点信息 。可获取theme 、launchMode、launchmode等属性

常用方法继承自PackageItemInfo类,下同。

3. ServiceInfo类

<service>节点信息。


4. ApplicationInfo类

<application>节点的信息。

字段说明:

flags字段:
FLAG_SYSTEM 系统应用程序
FLAG_EXTERNAL_STORAGE 表示该应用安装在sdcard中

5. ResolveInfo类

根据<intent-filter>节点获取其上一层目录的信息,通常是<activity>、<receiver>、<service>节点信息。
常用字段:
ActivityInfo activityInfo    获取 ActivityInfo对象,即<activity>或<receiver>节点信息
ServiceInfo serviceInfo     获取 ServiceInfo对象,即<service>节点信息

ApplicationInfo与ResolveInfo比较:前者能够得到Icon、Label、meta-data、description。后者只能得到Icon、Label。


6. PackageInfo类

AndroidManifest.xml文件的信息

常用字段:

String packageName               包名
ActivityInfo[] activities        所有<activity>节点信息
ApplicationInfo applicationInfo  <application>节点信息,只有一个
ActivityInfo[] receivers         所有<receiver>节点信息,多个
ServiceInfo[] services           所有<service>节点信息 ,多个


7. PackageManger 类

通过getPackageManager()方法获得。
常用方法:
PackageManager getPackageManager();
// 获得一个PackageManger对象

Drawable getApplicationIcon(String packageName);
// 返回给定包名的图标,否则返回null

ApplicationInfo getApplicationInfo(String packageName, int flags);
// 返回该ApplicationInfo对象
// flags标记通常直接赋予常数0

List<ApplicationInfo> getInstalledApplications(int flags);
// 返回给定条件的所有ApplicationInfo
// flag为一般为GET_UNINSTALLED_PACKAGES,后续可进一步过滤结果

List<PackageInfo> getInstalledPackages(int flags);
// 返回给定条件的所有PackageInfo

ResolveInfo resolveActivity(Intent intent, int flags);
// 返回给定条件的ResolveInfo对象(本质上是Activity) 
// intent 是查询条件,Activity所配置的action和category
// 可选flags:
// MATCH_DEFAULT_ONLY :Category必须带有CATEGORY_DEFAULT的Activity,才匹配
// GET_INTENT_FILTERS :匹配Intent条件即可
// GET_RESOLVED_FILTER :匹配Intent条件即可

List<ResolveInfo> queryIntentActivities(Intent intent, int flags);
// 返回给定条件的所有ResolveInfo对象(本质上是Activity)

ResolveInfo resolveService(Intent intent, int flags);
// 返回给定条件的ResolveInfo对象(本质上是Service) 

List<ResolveInfo> queryIntentServices(Intent intent, int flags);
// 返回给定条件的所有ResolveInfo对象(本质上是Service),集合对象
 
 
 
 

8. PackageStats 类

安装包的大小信息。AndroidSDK中并没有显式提供方法获得PackageStats对象,只能通过反射机制来调用系统中隐藏的函数(@hide)。

常用字段:

long cachesize      缓存大小
long codesize       应用程序大小
long datasize       数据大小
String packageName  包名


PS:应用程序的总大小 = cachesize  + codesize  + datasize。


二、常用代码片

1.根据PackageInfo对象获取APP信息:

ApplicationInfo applicationInfo = packageInfo.applicationInfo;
// APP 包名
String packageName = packageInfo.packageName;
// APP icon
Drawable icon = packageManager.getApplicationIcon(applicationInfo);
// APP 名称
String appName = packageManager.getApplicationLabel(applicationInfo).toString();
// APP 权限
String[] permissions = packageManager.getPackageInfo(packageName,PackageManager.GET_PERMISSIONS).requestedPermissions;

2.根据ResolveInfo对象获取APP信息:

// APP包名
resolve.activityInfo.packageName;
// APP icon
resolve.loadIcon(packageManager);
// APP名称
resolve.loadLabel(packageManager).toString();

3.根据包名获取APP中的主Activity:

Intent intent = new Intent(Intent.ACTION_MAIN);    
intent.setPackage(packageName);  
intent.addCategory(Intent.CATEGORY_LAUNCHER); 
List<ResolveInfo> resolveInfos = pManager.queryIntentActivities(intent, 0);
// 一个App中只有一个主Activity,直接取出。注意不是任何包中都有主Activity
String mainActivityName = "";
if (resolveInfos != null && resolveInfos.size() >= 1) {
    mainActivityName = resolveInfos.get(0).activityInfo.name;
}

4.根据包名获取APP信息:

PackageManager pManager = context.getPackageManager();
PackageInfo packageInfo = pManager.getPackageInfo(packageName, 0);
ApplicationInfo appInfo = packageInfo.applicationInfo;

// 获取App名
String appName = pManager.getApplicationLabel(appInfo).toString();
//// 也可以使用如下方法
//String appName = appInfo.loadLabel(pManager).toString();
// 获取App Icon
Drawable icon = pManager.getApplicationIcon(appInfo);
//// 也可以用如下两种方法
//Drawable icon = pManager.getApplicationIcon(packageName);
//Drawable icon = appInfo.loadIcon(pManager);
// 获取App versionName
String versionName = packageInfo.versionName; // versionName在xml的根节点中,只能用PackageInfo获取
// 获取权限
PackageInfo pPermissionInfo = pManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 
String[] permissions = pPermissionInfo.requestedPermissions;

5.批量获取App信息的两种方法:

PackageManager packageManager = getPackageManager();

// 法一:通过解析AndroidManifest.xml的<application>标签中得到,可获取所有的app。
List<ApplicationInfo> applicationList = packageManager
                  .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);

// 法二:通过Intent查找相关的Activity,更准确,但无法获取Provider等应用
// 通过解析<Intent-filter>标签得到
// <action android:name=”android.intent.action.MAIN”/>
// <action android:name=”android.intent.category.LAUNCHER”/>
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveList = packageManager.queryIntentActivities(intent, 0);

6.区分系统APP、第三方APP、安装在SDCard上的APP:

/** 判断是不是系统APP **/
// FLAG_SYSTEM = 1<<0,if set, this application is installed in the device's system image.
// 下面&运算有两种结果:
// 1,则flags的末位为1,即系统APP
// 0,则flags的末位为0,即非系统APP
if ( (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1 ){
    ......
}

/** 判断是不是第三方APP **/
// FLAG_SYSTEM = 1<<0,同上
if ( (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
     ......
}
//本来是系统程序,被用户手动更新后,该系统程序也成为第三方应用程序了
// FLAG_UPDATED_SYSTEM_APP = 1<<7, this is set if this application has been 
// install as an update to a built-in system application.
else if ((applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {
     ......
}

/** 判断是不是安装在SDCard的应用程序 **/
// FLAG_EXTERNAL_STORAGE = 1<<18,Set to true if the application is
// currently installed on external/removable/unprotected storage
if ( (applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 1) {
    ......
} 

三、工具类

获取APP信息:
/**
 * 获取手机上安装的所有APP的信息 配合AppInfo类使用
 */
public class AppInfoUtil {
    public static final int GET_ALL_APP = 0; // 所有APP
    public static final int GET_SYSTEM_APP = 1; // 系统预装APP
    public static final int GET_THIRD_APP = 2; // 第三方APP
    public static final int GET_SDCARD_APP = 3; // SDCard的APP

    private static AppInfoUtil infoUtil;

    private PackageManager pManager;

    // 所有应用
    private List<PackageInfo> allPackageList;

    // 筛选结果
    private List<PackageInfo> result;

    /** 私有构造器 **/
    private AppInfoUtil(Context context) {
        pManager = context.getPackageManager();
        result = new ArrayList<PackageInfo>();
    }

    /** 单例 **/
    public static AppInfoUtil getInstance(Context context) {
        if (infoUtil == null) {
            infoUtil = new AppInfoUtil(context);
        }
        return infoUtil;
    }

    /** 获取已安装的APP **/
    public List<AppInfo> getInstalledApps(int type) {
        // 0 表示不接受任何参数。其他参数都带有限制
        // 版本号、APP权限只能通过PackageInfo获取,故这里不使用getInstalledApplications()方法
        allPackageList = pManager.getInstalledPackages(0);
        if (allPackageList == null) {
            Log.e("AppInfoUtil类", "getInstalledApps()方法中的allPackageList为空");
            return null;
        }
        // 根据APP名排序
        Collections.sort(allPackageList, new PackageInfoComparator(pManager));
        // 筛选
        result.clear();
        switch (type) {
        case GET_ALL_APP:
            result = allPackageList;
            break;
        case GET_SYSTEM_APP: // 系统自带APP
            for (PackageInfo info : allPackageList) {
                // FLAG_SYSTEM = 1<<0,if set, this application is installed in
                // the device's system image.
                // 下面&运算有两种结果:
                // 1,则flags的末位为1,即系统APP
                // 0,则flags的末位为0,即非系统APP
                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
                    result.add(info);
                }
            }
            break;
        case GET_THIRD_APP: // 第三方APP
            for (PackageInfo info : allPackageList) {
                // FLAG_SYSTEM = 1<<0,同上
                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                    result.add(info);
                }
                // 本来是系统程序,被用户手动更新后,该系统程序也成为第三方应用程序了
                // FLAG_UPDATED_SYSTEM_APP = 1<<7, this is set if this
                // application has been
                // install as an update to a built-in system application.
                else if ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {
                    result.add(info);
                }
            }
            break;
        case GET_SDCARD_APP: // 安装在SDCard的应用程序
            for (PackageInfo info : allPackageList) {
                // FLAG_EXTERNAL_STORAGE = 1<<18,Set to true if the application
                // is
                // currently installed on external/removable/unprotected storage
                if ((info.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 1) {
                    result.add(info);
                }
            }
            break;
        }
        return getAppInfoByPackageInfo(result);
    }

    public List<AppInfo> getAppInfoByIntent(Intent intent) {
        List<ResolveInfo> resolveInfos = pManager.queryIntentActivities(intent,
                PackageManager.GET_INTENT_FILTERS);
        // 调用系统排序 , 根据name排序
        // 此排序会将系统自带App与用户安装的APP分开排序
        Collections.sort(resolveInfos, new ResolveInfo.DisplayNameComparator(
                pManager));
        // // 此排序会将系统自带App与用户安装的APP混合排序
        // Collections.sort(resolveInfos, new DisplayNameComparator(pManager));
        return getAppInfobyResolveInfo(resolveInfos);
    }

    /** 获取单个App图标 **/
    public Drawable getAppIcon(String packageName) throws NameNotFoundException {
        Drawable icon = pManager.getApplicationIcon(packageName);
        return icon;
    }

    /** 获取单个App名称 **/
    public String getAppName(String packageName) throws NameNotFoundException {
        ApplicationInfo appInfo = pManager.getApplicationInfo(packageName, 0);
        String appName = pManager.getApplicationLabel(appInfo).toString();
        return appName;
    }

    /** 获取单个App版本号 **/
    public String getAppVersion(String packageName)
            throws NameNotFoundException {
        PackageInfo packageInfo = pManager.getPackageInfo(packageName, 0);
        String appVersion = packageInfo.versionName;
        return appVersion;
    }

    /** 获取单个App的所有权限 **/
    public String[] getAppPermission(String packageName)
            throws NameNotFoundException {
        PackageInfo packageInfo = pManager.getPackageInfo(packageName,
                PackageManager.GET_PERMISSIONS);
        String[] permission = packageInfo.requestedPermissions;
        return permission;
    }

    /** 获取单个App的签名 **/
    public String getAppSignature(String packageName)
            throws NameNotFoundException {
        PackageInfo packageInfo = pManager.getPackageInfo(packageName,
                PackageManager.GET_SIGNATURES);
        String allSignature = packageInfo.signatures[0].toCharsString();
        return allSignature;
    }

    // /** 使用示例 **/
    // public static void main(String[] args) {
    // AppInfoUtil appInfoUtil = AppInfo.getInstance(context);
    //
    // // 获取所有APP
    // List<AppInfo> allAppInfo = appInfoUtil.getInstalledApps(AppInfoUtil.GET_ALL_APP);
    // for (AppInfo app : allAppInfo) {
    // String packageName = app.getPackageName();
    // String appName = app.getAppName();
    // Drawable icon = app.getIcon();
    // String versionName = app.getVersionName();
    // String[] permissions = app.getPermissions();
    // // 自由发挥...
    // }
    //
    // // 获取单个APP的信息
    // String appName = appInfoUtil.getAppName(packageName);
    // ...
    // }

    /** 从PackageInfo的List中提取App信息 **/
    private List<AppInfo> getAppInfoByPackageInfo(List<PackageInfo> list) {
        List<AppInfo> appList = new ArrayList<AppInfo>();
        for (PackageInfo info : list) {
            // 获取信息
            String packageName = info.applicationInfo.packageName;
            String appName = pManager.getApplicationLabel(info.applicationInfo)
                    .toString();
            Drawable icon = pManager.getApplicationIcon(info.applicationInfo);
            // // 也可以用如下方法获取APP图标,显然更烦琐
            // ApplicationInfo applicationInfo =
            // pManager.getApplicationInfo(packageName, 0);
            // Drawable icon = applicationInfo.loadIcon(pManager);
            String versionName = info.versionName;
            String[] permissions = info.requestedPermissions;
            String launchActivityName = getLaunchActivityName(packageName);
            // 储存信息
            AppInfo appInfo = new AppInfo();
            appInfo.setPackageName(packageName);
            appInfo.setAppName(appName);
            appInfo.setIcon(icon);
            appInfo.setVersionName(versionName);
            appInfo.setPermissions(permissions);
            appInfo.setLaunchActivityName(launchActivityName);
            appList.add(appInfo);
        }
        return appList;
    }

    /** 从ResolveInfo的List中提取App信息 **/
    private List<AppInfo> getAppInfobyResolveInfo(List<ResolveInfo> list) {
        List<AppInfo> appList = new ArrayList<AppInfo>();
        for (ResolveInfo info : list) {
            String packageName = info.activityInfo.packageName;
            String appName = info.loadLabel(pManager).toString();
            Drawable icon = info.loadIcon(pManager);
            String launchActivityName = getLaunchActivityName(packageName);
            AppInfo appInfo = new AppInfo();
            appInfo.setPackageName(packageName);
            appInfo.setAppName(appName);
            appInfo.setIcon(icon);
            appInfo.setLaunchActivityName(launchActivityName);
            appList.add(appInfo);
        }
        return appList;
    }

    /** 获取指定包中主Activity的类名,并不是所有包都有主Activity **/
    private String getLaunchActivityName(String packageName) {
        // 根据PackageInfo对象取不出其中的主Activity,须用Intent
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.setPackage(packageName);
        List<ResolveInfo> resolveInfos = pManager.queryIntentActivities(intent,
                0);
        String mainActivityName = "";
        if (resolveInfos != null && resolveInfos.size() >= 1) {
            mainActivityName = resolveInfos.get(0).activityInfo.name;
        }
        return mainActivityName;
    }

    /** 此比较器直接复制Android源码,但是却可以把系统APP与用户APP混合排列,何解? **/
    private static class DisplayNameComparator implements
            Comparator<ResolveInfo> {
        public DisplayNameComparator(PackageManager pm) {
            mPM = pm;
        }

        public final int compare(ResolveInfo a, ResolveInfo b) {
            CharSequence sa = a.loadLabel(mPM);
            if (sa == null)
                sa = a.activityInfo.name;
            CharSequence sb = b.loadLabel(mPM);
            if (sb == null)
                sb = b.activityInfo.name;
            return sCollator.compare(sa.toString(), sb.toString());
        }

        private final Collator sCollator = Collator.getInstance();
        private PackageManager mPM;
    }

    /** 自定义的PackageInfo排序器 **/
    private static class PackageInfoComparator implements
            Comparator<PackageInfo> {
        public PackageInfoComparator(PackageManager pm) {
            mPM = pm;
        }

        public final int compare(PackageInfo a, PackageInfo b) {
            CharSequence sa = mPM.getApplicationLabel(a.applicationInfo);
            CharSequence sb = mPM.getApplicationLabel(b.applicationInfo);
            return sCollator.compare(sa.toString(), sb.toString());
        }

        private final Collator sCollator = Collator.getInstance();
        private PackageManager mPM;
    }

}

配套Model,AppInfo.java:
/**
 * App信息类
 */
public class AppInfo {
    // 包名
    private String packageName;
    // APP名
    private String appName;
    // 图标
    private Drawable icon;
    // 版本号
    private String versionName;
    // 权限
    private String[] permissions;
    // 主Activity的类名
    private String launchActivityName; 
    
    public String getLaunchActivityName() {
        return launchActivityName;
    }

    public void setLaunchActivityName(String launchActivityName) {
        this.launchActivityName = launchActivityName;
    }

    public AppInfo() {}

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public Drawable getIcon() {
        return icon;
    }

    public void setIcon(Drawable icon) {
        this.icon = icon;
    }

    public String getVersionName() {
        return versionName;
    }

    public void setVersionName(String versionName) {
        this.versionName = versionName;
    }

    public String[] getPermissions() {
        return permissions;
    }

    public void setPermissions(String[] permissions) {
        this.permissions = permissions;
    };
    
    
}


四、通过反射获取APP包的大小

AndroidSDK中并没有显式提供方法获得PackageStats对象,只能通过反射机制来调用系统中隐藏的函数(@hide)。

具体方法如下:
第一步、  通过反射机制调用getPackageSizeInfo() ,方法原型为:

/*
 * @param packageName 应用程序包名
 * @param observer 当查询包的信息大小操作完成后
 * 将回调给IPackageStatsObserver类中的onGetStatsCompleted()方法,
 * 并且我们需要的PackageStats对象也封装在其参数里.
 * @hide //隐藏函数的标记
 */
public abstract void getPackageSizeInfo(String packageName, IPackageStatsObserver observer);
{
    //
}

内部调用流程如下,这个知识点较为复杂,知道即可:
getPackageSizeInfo方法内部调用getPackageSizeInfoLI(packageName, pStats)方法来完成包状态获取。
getPackageSizeInfoLI方法内部调用Installer.getSizeInfo(String pkgName, String apkPath,String fwdLockApkPath, PackageStats
pStats),继而将包状态信息返回给参数pStats。
getSizeInfo这个方法内部是以本机Socket方式连接到Server,然后向server发送一个文本字符串命令,格式:getsize apkPath fwdLockApkPath 给server。
Server将结果返回,并解析到pStats中。
掌握这个调用知识链即可。


实现代码:

/** 获取指定包的大小信息 **/
public void queryPackageSize(String packageName) throws Exception {
    Log.i(TAG, "packageName:" + packageName);
    if (packageName != null) {
        // 使用反射机制得到PackageManager类的隐藏函数getPackageSizeInfo  
        PackageManager pManager = getPackageManager();
        //通过反射机制获得该隐藏函数  
        Method getPackageSizeInfo = pManager.getClass().getMethod("getPackageSizeInfo"
                                    , String.class,IPackageStatsObserver.class);  
        //调用该函数,并且给其分配参数 ,待调用流程完成后会回调PkgSizeObserver类的函数  
        getPackageSizeInfo.invoke(pManager, packageName,new PkgSizeObserver());  
    }
}


第二步、由于需要获得系统级的服务或类,我们必须加入Android系统形成的AIDL文件,共两个: IPackageStatsObserver.aidl 和 PackageStats.aidl文件。将它们放置在android.content.pm包路径下。 


IPackageStatsObserver.aidl 文件:

package android.content.pm;  
  
import android.content.pm.PackageStats;  
/** 
 * API for package data change related callbacks from the Package Manager. 
 * Some usage scenarios include deletion of cache directory, generate 
 * statistics related to code, data, cache usage(TODO) 
 * {@hide} 
 */  
oneway interface IPackageStatsObserver {  
      
    void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);  
}  


PackageStats.aidl文件:

package android.content.pm;  
  
parcelable PackageStats; 

第三步、创建一个类继承至IPackageStatsObserver.Stub()它本质上实现了Binder机制。当我们把该类的一个实例通过getPackageSizeInfo()调用时,该函数启动中间流程去获取相关包的信息大小,扫描完成后,将查询信息回调至该类的onGetStatsCompleted(PackageStats pStats, boolean succeeded)方法,信息大小封装在此实例上。

实现代码:
/** aidl文件形成的Bindler机制服务类 **/
public class PkgSizeObserver extends IPackageStatsObserver.Stub{  
    /*** 回调函数, 
     * @param pStatus ,返回数据封装在PackageStats对象中 
     * @param succeeded  代表回调成功 
     */   
    @Override  
    public void onGetStatsCompleted(PackageStats pStats, boolean succeeded) throws RemoteException {  
        cachesize = pStats.cacheSize; //缓存大小  
        datasize = pStats.dataSize;  //数据大小   
        codesize = pStats.codeSize;  //应用程序大小  
        totalsize = cachesize + datasize + codesize; 
    }  
}  


第四步、获取pStats的属性值(代码见上),再转换为对应的以kb/mb为计量单位的字符串。下面代码中,1 << 10是二进制的左移,相当于乘以2的10次方,即乘1024

实现代码:

/** 系统函数,字符串转换**/
private String formateFileSize(long size){
    String str = "";
    double newSize = 0;
    if (size == 0) {
        str = "0.00 B";
    } else if (size < (1 << 10)) {
        newSize = size;
        str = newSize + " B";
    } else if (size < (1 << 20)){
        newSize = 1.0 * size / (1 << 10);
        str = String.format("%.2f", newSize) + " KB";
    } else if (size < (1 << 30)) {
        newSize = 1.0 * size / (1 << 20);
        str = String.format("%.2f", newSize) + " MB";
    }
    return str;   
}  

为了能够通过反射获取应用程序大小,必须加入以下权限,否则会出现警告且得不到实际值。

<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"></uses-permission> 

流程图如下:


五、Demo


代码见笔者的Github: https://github.com/kinglearnjava/AppInfo

Android PMS(PackageManagerService) 原理 为什么要有 PMS 手机里面的 apk 都会在 data/app 目录下,知道这个 apk 路径很简单,难的地方在于怎么管理 apk 里面的信息,例如怎么提供给 AMS 需要的 Activity 信息等。所以就需要 PMS 提前将 apk 的信息缓存起来。 PMS 缓存信息是在手机开机启动这段时间处理解析的,所以这也是为什么手机开启启动比较慢的原因之一。 PMS 分析 apk 压缩文件 当手机开机时,PMS 会扫描 data/app/package/base.apk,还有 system/app/packag 阅读详情

相关推荐

Android FrameWork——PackageManager框架,整理几个重要的Android知识

大部分情况我们是在Activity中使用getPackageManager方法获取一个ApplicationPackageManager的对象,ApplicationPackageManager实际上是包装了一个IPackageManager.Stub.Proxy的对象由IPackageManager.Stub.Proxy代理执行PackageManager相关操作,IPackageManager.Stub.Proxy实际代理的是PackageManagerService,

2401_87361641的博客 1263

Android PackageManager详解

Android系统为我们提供了很多服务管理的类,包括ActivityManager、PowerManager(电源管理)、AudioManager(音频管理)等。除此之外,还提供了一个PackageManger管理类,它的主要职责是管理应用程序包。 通过PackageManager,我们就可以获取应用程序信息。   提到PackageManager,就得提一下AndroidManifest.XML文件了。AndroidManifest.xml是Android应用程序中最重要的文件之一。它是Android.

看美丽风晴 9905

Android系统PackageManagerService简介

Android PackageManagerServer 应用安装过程详解,apk安装过程

Android PackageManager

这两个管理器其实没什么好扯的,看一下源代码基本上就知道了,用途的话除了系统本身用的最多,PackageManager在桌面Launcher APP使用. PackageManager管理器主要负责APP Package的管理,比如安装,卸载,Package的解析,Package包的各种信息,如版本,APP图标,资源,权限等等,android系统在安装APP的时候,会弹出一个提示框,提示框中就会显

刘志保的博客 1224

行人重识别技术(Re-ID)概述、研究现状以及相关数据集下载

ReID技术概述什么是ReID一般流程Re-ID特点研究现状难点数据集reid常用数据集以及下载链接评价指标实现思路研究方式基于表征学习基于度量学习基于局部特征全局特征切片姿态基于视频序列RQEN基于GANCamStyleDG-NetGAN总结对比未来方向建议文献 什么是ReID 行人重识别是指利用计算机视觉技术,判断在不同时间段、不同监控下出现的行人图像是否属于同一人员的技术。行人重识别是最近几年在视频分析领域下热门的研究领域,可以看做是人脸识别应用的拓展。现在大街上的监控较多,由于设备质量、成像光线、.

留缘的博客 1万+

车载以太网测试技术解析

在智能汽车与HiL测试领域,高效解析与模拟车载网络通信是开发验证的关键。ZD-Converter 2000以媒体/介质转换器、嗅探器、拦截器、仿真器四合一的颠覆性设计,成为工程师应对复杂车载以太网测试的瑞士军刀。它支持双路车载/标准以太网智能转换、实时通信嗅探、硬件级数据拦截及ECU通信模拟,更通过串口命令实现全参数远程配置,赋能自动化测试流程。本文将深度解析其核心功能与实战应用场景。

Triv2025的博客 1143

android packageManager用法

今天要讲的是PackageManager。Android系统为我们提供了很多服务管理的类,包括ActivityManager、PowerManager(电源管理)、AudioManager(音频管理)等。除此之外,还提供了一个PackageManger管理类,它的主要职责是管理应用程序包。 通过PackageManager,我们就可以获取应用程序信息。   提到PackageManager,就得...

qianshanyany的博客 732

PCIe扫盲(三)

需要特别注意的是,PCIe的Spec中明确规定只有Root有权限发起配置请求(Originate Configuration Requests),也就是说PCIe系统里面的其他设备是不允许去配置其他设备的配置空间的,即peer-to-peer的配置请求是不允许的。当配置请求进行BDF路由的时候,正是依靠这些信息来确定要找的设备的。前面的文章还介绍过,Root和Switch的每一个端口中都包含一个P2P桥,并且知道桥的配置空间头(Configuration Space Header)是Type1型的。

Liuqz2009的专栏 2402

android基础学习之PackageManager和activityManager的用法

Android系统为应用管理功能提供了大量的API。根据功能的不同,这些API分为两大类:PackageManager相关和ActivitManager相关。 PackageManager相关       本类API是对所有基于加载信息的数据结构的封装,包括以下功能:     安装,卸载应用     查询permission相关信息     查询Application相关信息(a

xinguanyiban07的专栏 1021

MQTT阿里云OTA 调试记录

2.验证,这个验证是什么意思呢,就是阿里云会把你包的信息,比如包大小,streamid(相当于包的识别码),版本号发送给你的设备,然后如果你没发送升级成功的包给阿里云,这里会是一直验证中的状态,那你的设备每次重新连接阿里云,发送connect包给阿里云的时候,阿里云就会发送一次这个验证(upgrade)包。提取到了之后就可以发送请求包了,这个请求包比较坑,也可能是我没付费,他的包一次最多只有1024个字节的数据。之前说了,验证状态下,设备发送connect包给阿里云,阿里云就会发一个upgrade包给你。

qq_42585211的博客 1231

Waymo数据集里的隐藏彩蛋:5个激光雷达数据融合实战(附Python代码)

本文深入解析Waymo数据集中5个激光雷达的数据融合技术,提供Python实战代码,帮助开发者掌握多传感器协同工作的关键方法。通过时间同步、坐标转换和运动补偿等技术,实现高精度3D场景重建,提升自动驾驶系统的环境感知能力。

weixin_30399821的博客 81

Android PackageManager查询、安装、读取meta等用法

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34390996的博客 634

FPS游戏自动枪械识别+压枪(以PUBG为例)

使用Python3.9作为开发环境,实现一个通用的FPS游戏自动检测枪械配件+压枪宏的软件开发思路

weixin_37827742的博客 3万+

android 命令pm 全称 packagemanager,07 Android包管理机制-pm命令用法

一、Pm命令1.1 命令列表命令格式:pm 命令列表:命令功能实现方法list packages列举app包信息PMS.getInstalledPackagesinstall [options] 安装应用PMS.installPackageAsUseruninstall [options]卸载应用IPackageInstaller.uninstallenable enablePMS.setEnab...

weixin_33364945的博客 612

scDeepCluster_pytorch代码解读与文章理解

论文:Clustering single-cell RNA-seq data with a。

qq_34179307的博客 915

13、深入理解 Microsoft 365 的安全与合规概念

本文深入探讨了 Microsoft 365 的安全与合规概念,涵盖文档存储、文件共享、审计、保留、eDiscovery、分类和保护以及网络等多个关键方面。通过合理配置这些功能,组织可以更好地管理和保护其数据资源,满足法规要求,并提升工作效率。文章还提供了最佳实践建议及流程图,帮助读者全面理解 Microsoft 365 的安全架构和管理策略。

k8s6orchestrator的博客 211

PackageManager详解

Android系统为我们提供了很多服务管理类,包括ActivityManager、PowerManager(电源管理)、AudioManager(音频管理)。PackageManager主要是管理应用程序包,通过它就可以获取应用程序信息。 PackageManger 类 说明: 获得已安装的应用程序信息 。可以通过getPackageManager()方法获得。 常用方法: p

Android小怪 912

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

几个比较混淆概念,android中的Info类以及PackageManager和ActivityManager ... ...

在Android开发过程中经常遇到以下几种类,对这些比较混淆,今天VincentTung对其进行逐一认识和学习。 1.PackageManager 查了一下API,就一句话: Classforretrievingvariouskindsofinformationrelatedtotheapplicationpackages...

weixin_34189116的博客 168

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

android-各种管理器 - 随心

1.ConnectivityManager : 网络连接状态管理 2.PackageManager : app管理 3.DevicePolicyManager :设备管理的主类

Super_Level的专栏 779

android meta-data 使用详解

这是该元素的基本结构.可以包含在 四个元素中。 这个名字值是额外的任意的可以提供给父组件的数据。一个组件元素能够包含任意数量的meta-data子元素。它们所有的值都会被收集在Bundle对象中并且使其可以作为组件的 PackageItemInfo.metaData 字段。 一般的值可以通过value属性来指定,但是如果要指定一个资源id作为一个值,那么就要用r...

iteye_1576的博客 89

由packagename得到应用程序信息

有的时候,项目会需要调用别人的应用程序,比如拨号、短信什么的(都是现在rom改的太多了,这些基础应用都一样,碎片化太严重),下面我给出两种方法来实现: 一、通过packmanager的getLaunchIntentForPackage方法 [html] view plaincopy PackageManager packageManager

jcgu的专栏 1996
上一篇: Android 获取当前APP和系统的版本信息
下一篇: 【Android笔记】多线程与 UI 交互的方法
KingLearnJava
博客等级 码龄12年 93粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值