如何获取Android应用与系统信息

前言

本主要了解一下Android系统信息的获取,apk应用信息的获取。

本文相关源码在文末给出

Android系统信息的获取

有时我们想要获取手机系统的配置信息,通常可以从以下俩方面获取:

  • android.os.Build

  • SystemProperty

1、android.os.Build

android.os.Build包含了系统编译时的大量设备,配置信息,它里面的字段含义如下:

  • Build.BOARD; //主板
  • Build.BRAND; //Android系统指定商
  • supported_abis = null;//CPU指令集
  • Build.DEVICE;//设备参数
  • Build.DISPLAY;//显示屏参数
  • Build.FINGERPRINT;//唯一编号
  • Build.SERIAL;//硬件序列号
  • Build.ID;//修订版本列表
  • Build.MANUFACTURER;//硬件制造商
  • Build.MODEL;//版本
  • Build.HARDWARE;//硬件名
  • Build.PRODUCT;//手机产品名
  • Build.TAGS;//描述Build的标签
  • Build.TYPE;//Builder类型
  • Build.VERSION.CODENAME;//当前开发号
  • Build.VERSION.INCREMENTAL;//源码版本控制号
  • Build.VERSION.RELEASE;//版本字符串
  • Build.VERSION.SDK_INT;//版本号
  • Build.HOST;//Host值
  • Build.USER;//User名
  • Build.TIME;//编译时间

2、SystemProperty

SystemProperty包含许多系统,配置属性值和参数,很多与上面通过android.os.Build获取的相同,下面给出常用的信息:

  • System.getProperty(“os.version”);//os 版本
  • System.getProperty(“os.name”);//os 名称
  • System.getProperty(“os.arch”);//os 架构
  • System.getProperty(“user.home”);//Home 属性
  • System.getProperty(“user.name”);//Name 属性
  • System.getProperty(“user.dir”);//Dir 属性
  • System.getProperty(“user.timezone”);//时区
  • System.getProperty(“path.separator”);//路径分隔符
  • System.getProperty(“line.separator”);//行分隔符
  • System.getProperty(“file.separator”);//文件分隔符
  • System.getProperty(“java.vendor.url”);//java vender URL 属性
  • System.getProperty(“java.class.path”);//java Class 路径
  • System.getProperty(“java.class.version”);//java Class 版本
  • System.getProperty(“java.vendor”);//java Vender 属性
  • System.getProperty(“java.version”);//java 版本
  • System.getProperty(“java_home”);//java HOME属性

3、实例

通过一个简单的示例查看如何使用(更多细节查看文末源码),如下:

        /* 通过android.os.Build,可以直接获得一些Build提供的系统信息 */
        String board = Build.BOARD;
        String brand = Build.BRAND;
        Log.d(TAG, "android.os.Build,board:" + board);
        Log.d(TAG, "android.os.Build,brand: " + brand);
        /* 通过SystemProperty,要使用System.getProperty("XXX") */
        String os_version = System.getProperty("os.version");
        String os_name = System.getProperty("os.name");
        Log.d(TAG, "SystemProperty,os_version: " + os_version);
        Log.d(TAG, "SystemProperty, os_name: " + os_name);

可以看到,获取系统信息还是很简单的。

Apk应用信息的获取

Apk应用信息的获取无非分为,apk包信息的获取与应用进程信息的获取。

1、PackageManager

通过PackageManager可以获得应用的apk包信息,先看下面一张图:

最里面的框代表了整个Activity的信息,系统提供了ActivityInfo类来进行封装,以此类推。

1.1、下面列举一些常用的系统封装信息

下面这些封装信息与PackageManager在同一个包内。

  • ActivityInfo
    ActivityInfo 封装了在Manifest文件中<activity></activity>和<receiver></receiver>之间的所有信息,包括name,icon,label,launchmod等 。

  • ServiceInfo
    和ActivityInfo类似,它封装了<service></service>之间的所有信息 。

  • ApplicationInfo
    它封装了<application></application>之间的信息,特别的是,Application包含很多Flag,FLAG_SYSTEM表示为系统应用,FLAG_EXTERNAL_STORAGE表示为安装在sd卡上的应用等,通过这些FLAG可以很方便的判断应用类型 。

  • PackageInfo
    它用于封装Manifest文件相关节点的信息,包含了所有Activity、Service等信息 。

  • ResolveInfo
    这个比较特殊,它封装的是包含<intent>信息的上一级信息,所以它可以返回ActivityInfo,ServiceInfo等包含的信息,它经常用来帮助我们找到那些包含特定intent条件的信息,如带分享,播放功能的应用。

    通过上面的对象,PackageManager 就可以通过调用各种方法来返回不同类型的Bean

1.2、PackageManager常用方法
  • getPackagerManager: 通过调用这个方法返回一个PackageManager对象
  • getApplicationInfo: 以ApplicationInfo形式返回指定包名的Application
  • getApplicationIcon:返回指定包名的icon
  • getInstalledApplications: 以ApplicationInfo形式返回安装的应用
  • getInstalledPackages:以PackageInfo的形式返回安装的应用
  • queryIntentActivities: 返回指定intent的ResolveInfo对象、Activity集合
  • queryIntentServices:返回指定intent的ResolveInfo对象、service集合
  • resolveActivity:返回指定intent的Activity
  • resolveService:返回指定的intentService
1.3、实例

下面通过一个例子来了解如何通过PackageManager来选出不同类型的app,判断app类型的依据,就是利用Applicationinfo中的FLAG_SYSTEM来进行判断,如下:

app.flags & Applicationinfo.FLAG_SYSTEM
  • 如果flags & Applicationinfo.FLAG_SYSTEM != 0,则为系统应用
  • 如果flags & Applicationinfo.FLAG_SYSTEM <= 0, 则为第三方应用
  • 如果flags & Applicationinfo.FLAG_EXTERNAL_STORAGE != 0, 则为SD卡上的应用
  • 特殊的,当系统应用经过升级后,也将成为第三方应用:flags & Applicationinfo.FLAG_UPDATED_SYSTEM_APP != 0

首先封装一个Bean保存我所需要的app信息:

public class PMAppInfo {

    private String appName;//app名称
    private Drawable appIcon;//图标
    private String pkgName;//所在包名

    public PMAppInfo(String appLabel, Drawable appIcon, String pkgName) {
        this.appName = appLabel;
        this.appIcon = appIcon;
        this.pkgName = pkgName;
    }

    public String getAppLabel() {
        return appName;
    }

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

    public Drawable getAppIcon() {
        return appIcon;
    }

    public void setAppIcon(Drawable appIcon) {
        this.appIcon = appIcon;
    }

    public String getPkgName() {
        return pkgName;
    }

    public void setPkgName(String pkgName) {
        this.pkgName = pkgName;
    }

}

接下来,通过上面所说的方法判断各种类型的app:

private List<PMAppInfo> getAppInfoList(int flag){
        pm = this.getPackageManager();
        //获取应用信息
        List<ApplicationInfo> applicationInfoList = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
        List<PMAppInfo> appInfoList = new ArrayList<>();
        //判断应用类型
        switch (flag){
            case ALL_APP:
                appInfoList.clear();
                for (ApplicationInfo app : applicationInfoList) {
                    appInfoList.add(new PMAppInfo(
                            ((String) app.loadLabel(pm)),
                            app.loadIcon(pm),
                            app.packageName));
                }
                break;
            case SYSTEM_APP:
                appInfoList.clear();
                for (ApplicationInfo app : applicationInfoList) {
                    if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                        appInfoList.add(new PMAppInfo(
                                ((String) app.loadLabel(pm)),
                                app.loadIcon(pm),
                                app.packageName));
                    }
                }
                break;
            case THIRD_APP:
                appInfoList.clear();
                for (ApplicationInfo app : applicationInfoList) {
                    if ((app.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
                        appInfoList.add(new PMAppInfo(
                                ((String) app.loadLabel(pm)),
                                app.loadIcon(pm),
                                app.packageName));
                    } else if ((app.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
                        appInfoList.add(new PMAppInfo(
                                ((String) app.loadLabel(pm)),
                                app.loadIcon(pm),
                                app.packageName));
                    }
                }
                break;
            case SDCARD_APP:
                appInfoList.clear();
                for (ApplicationInfo app : applicationInfoList) {
                    if ((app.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
                        appInfoList.add(new PMAppInfo(
                                ((String) app.loadLabel(pm)),
                                app.loadIcon(pm),
                                app.packageName));
                    }
                }
                break;
            default:
                return null;
            }
        return appInfoList;
    }

运行效果图:

如上图所示,通过点击不同的按钮,在下方显示出不同类型的apk信息。

2、ActivityManager

前面使用了PackageManager获得了应用包的信息,PackageMessager重点在于获得应用的包信息,而ActivityManager重点在于获得在运行时的应用程序的进程信息。

2.1、同PackageManager一样, ActivityManager也封装了很多Bean对象

下面的封装类都在ActivityManager的类中。

  • ActivityManager.MemoryInfo
    它封装了内存信息,MemoryInfo中有几个重要的字段:availMem - 系统可用内存,totalMen - 总内存,threshold - 低内存的阈值,即区分是否是低内存,lowMemory - 是否处于低内存。

  • Debug.MemoryInfo
    android中还有一个MemoryInfo,它来自Debug.MemoryInfo,前面的MemoryInfo通常用于获取全局的内存使用信息,而它用于统计进程下的内存信息。

  • RunningAppProcessInfo
    顾名思义,就是运行间进程信息,储存的字段自然进程相关的信息,processName - 进程名, pid - 进程pid, uid - 进程uid,pkgList - 该进程下所有的包 。

  • RunningServiceInfo
    RunningServiceInfo与RunningAppProcessInfo类似,用于封装运行时的服务信息,它包含了进程信息的同时还包含了其他的信息,activeSince - 第一次被激活的时间,方式,foreground - 服务是否在后台运行。

2.2、实例

下面同样通过一个例子来使用ActivityManager,先封装一个Bean来保存一个我们需要的字段:

public class AMProcessInfo {

    private String uid;
    private String pid;
    private String memorySize;
    private String processName;

    public AMProcessInfo() {
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getMemorySize() {
        return memorySize;
    }

    public void setMemorySize(String memorySize) {
        this.memorySize = memorySize;
    }

    public String getProcessName() {
        return processName;
    }

    public void setProcessName(String processName) {
        this.processName = processName;
    }
}

通过调用getRunningAppProcesses()返回当前运行时的进程信息集合:

  private List<AMProcessInfo> getRunningProcessesInfo() {
        amProcessInfoList = new ArrayList<>();
        //获取正在运行的进程集合
        List<ActivityManager.RunningAppProcessInfo> appProcessList = am.getRunningAppProcesses();
        for (int i = 0; i < appProcessList.size(); i++) {
            ActivityManager.RunningAppProcessInfo info = appProcessList.get(i);
            int pid = info.pid;
            int uid = info.uid;
            String processName = info.processName;
            //获取该进程下的内存
            int[] memoryPid = new int[]{pid};
            Debug.MemoryInfo[] memoryInfo = am.getProcessMemoryInfo(memoryPid);
            int memorySize = memoryInfo[0].getTotalPss();
            AMProcessInfo processInfo = new AMProcessInfo();
            //
            processInfo.setPid("" + pid);
            processInfo.setUid("" + uid);
            processInfo.setMemorySize("" + memorySize);
            processInfo.setProcessName(processName);
            amProcessInfoList.add(processInfo);
        }
        return amProcessInfoList;
    }

运行效果图:

上图运行给出了当前运行的一个进程的pid,uid,占用内存,进程名的信息。

结语

PackageManager是用来获取apk包信息的,ActivityManager是用来获取运行时进程信息的,如果想要获取手机系统信息,可以通过SystemProperty和android.os.Build,本文同样是一篇学习记录,希望大家读完后和我一样有所收获。

本文相关源码位置

参考资料:

《android群英传》

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值