介绍

Android10 因为提高了其安全性能,因此获取序列号和IMEI号的权限与以前的版本有了变化这里就举例Zebra 移动设备Android 10 系统下的如何获取相应权限。运行Android 10的移动计算机上访问序列号和IMEI号的过程。需要明确授予您的应用程序访问这些设备标识符的权限,这可以通过以下三种方式之一进行:

  1. 通过StageNow 的AccessManager授权

  2. 通过您的应用程序,使用EMDK配置文件管理器。

方法1,使用StageNow 授权应用程序权限

方法1使用的样例可以从下面网盘下载

链接:https://pan.baidu.com/s/1-bk8jUfucTe8ZOGy4PVz2w

提取码:zebr

步骤1,首先需要在程序的AndroidManifest.xml添加一条权限申明

步骤2,通过Zebra的App 签名工具SigTools来提取APK安装包的签名证书,下载链接如下(后面打包样例中也有该工具)

https://techdocs.zebra.com/emdk-for-android/latest/samples/sigtools/

SigTools的命令行格式如下,这里以从app.apk文件中提取证书文件,并将其命名为app.crt为例

java -jar SigTools.jar getcert -inform apk -outform der -in app.apk -outfile app.crt

在StageNow中新建一个配置文件,由于Android10的MX版本较高,建议选择MX9.3 以上(已测试通过)

Wizard选择最下面的XpertMode

  • 在SETTINGS中选择AccessMgr

  • 由于获取SN和IMEI的Service标识不同,如果需要同时授权获取这两个信息,可以再次点击选择AccessMgr,再在CONFIG里添加一个AccessMgr,这里我们先只添加一个

1. Service Access Action选择为 Allow Caller to Call Service

2.这里填写要授权的服务标识

如果要授权获取SN,填写以下标识内容

content://oem_info/oem.zebra.secure/build_serial

如果要授权获取IMEI,填写以下标识内容

content://oem_info/wan/imei

如果要允许您的应用同时访问这两者,则需要声明在AccessManager的设定两个不同实例。

3.这里填写应用程序的包名(小建议:如果不确定包名,可以在安装了该程序后,通过Datawedge的配置文件添加关联程序的功能来查看应用的包名

4. 点击这里,打开文件浏览窗口,选择之前提取生成签名证书文件

我们来对比一下效果


方法2:授予使用EMDK配置文件管理器通过您的应用程序访问设备标识符的权限。

方法二中引用的示例应用程序可在以下位置找到:

https://github.com/ZebraDevs/OEMIdentifiers-Java-Sample

下面是参考过程:

  1. 构建MX XML(使用程序包名称和以编程方式生成的程序包签名)

  2. 从EMDK初始化ProfileManager

  3. 使用ProfileManager处理XML

在示例应用程序中,我们使用一些关键类来实现此功能:

  • XML类

    • 使用包名称和签名创建MX XML

  • PackageManagerHelper.class

    • 用于生成我们的应用程序签名的Base64编码

  • PermissionsActivity.class

    • 使用ProfileManager API处理XML。

建立MX XML

我们首先要做的是生成要传递给ProfileManager API的XML,该XML将为您的应用程序授予必要的权限。

核心XML如下所示,其中包名称和签名的占位符分别为:

上面是授予串行权限所需的XML,在“ ServiceIdentifier”标签下表示。以下是授予IMEI权限所需的XML:

在应用此XML之前,我们需要填补“包名称和签名”的空白。

直接生成包名称,只需从有效的Context调用getPackageName()即可。

获取包签名的过程稍微有些复杂:首先,我们使用getApkContentsSigners()获取APK签名,然后,将其转换为Base64 –利用Apache Commons Hex和Base64库通过将签名转换为char来实现这一点。数组,将其解码为字节数组,最后编码为Base64:

public static String getSigningCertBase64(Context cx) throws PackageManager.NameNotFoundException, DecoderException {    //convert String to char array (1st step)    char[] charArray = getSigningCertificateHex(cx)[0].toChars();

    // decode the char array to byte[] (2nd step)    byte[] decodedHex = Hex.decodeHex(charArray);

    // The String decoded to Base64 (3rd step)    return Base64.encodeBase64String(decodedHex);}

@SuppressWarnings("deprecation")@SuppressLint("PackageManagerGetSignatures")public static Signature[] getSigningCertificateHex(Context cx)        throws PackageManager.NameNotFoundException {    Signature[] sigs;    SigningInfo signingInfo;    signingInfo = cx.getPackageManager().getPackageInfo(cx.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES).signingInfo;    sigs = signingInfo.getApkContentsSigners();    return sigs;}

我们将所有这些功能放到XML类中–在构造函数中,我们对上述API进行了两次调用,以获取包签名和名称。然后,我们将这些值存储为类中的成员变量:

// Holdersprivate String mPackageSignatureHex;private String mPackageName;

public XML(Context context) throws PackageManager.NameNotFoundException, DecoderException {    mPackageSignatureHex = PackageManagerHelper.getSigningCertBase64(context);    mPackageName = context.getPackageName();}

当我们的应用程序需要XML授予权限(Serial和IMEI)时,我们可以简单地调用getSerialPermissionXml()和getImeiPermissionXml()方法,并且将为我们填充值,如下所示:

public String getSerialPermissionXml() {    return  "\n" +            "  \n" +            "    \n" +            "    \n" +            "      \n" +            "      \n" +            "      \n" +            "      \n" +            "      \n" +            "    \n" +            "  \n" +            "";}

public String getImeiPermissionXml() {    return  "\n" +            "  \n" +            "    \n" +            "    \n" +            "      \n" +            "      \n" +            "      \n" +            "      \n" +            "      \n" +            "    \n" +            "  \n" +            "";}

至此,我们已经准备好将两组XML字符串传递给ProfileManager API,以将这些权限授予我们的应用程序。

初始化Profile Manager实例

在应用任何XML之前,我们首先需要从EMDK初始化ProfileManager的实例。在示例应用程序中,这是在PermissionsActivity类中完成的。我们使用startActivityForResult()从MainActivity启动此活动,因此可以将授予权限的成功/失败通知给我们。

在继续之前,请确保已将EMDK添加到build.gradle文件中:

// EMDKimplementation 'com.symbol:emdk:7.6.10'

现在,我们可以在活动中初始化EMDK:

// Init EMDKEMDKResults emdkManagerResults = EMDKManager.getEMDKManager(this, this);

这两个参数分别是上下文和EMDKListener回调,它们已在PermissionsActivity.class中实现。当EMDK实例准备就绪时,将在onOpened()回调中通知我们,然后我们可以在其中获取ProfileManager对象的实例:

@Overridepublic void onOpened(EMDKManager emdkManager) {    // Assign EMDK Reference    mEmdkManager = emdkManager;

    // Get Profile & Version Manager Instances    mProfileManager = (ProfileManager) mEmdkManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE);

    // Apply Profile    if (mProfileManager != null) {        try {            // Init XML            XML permissionXml = new XML(this);

            // Process            new ProcessProfile(XML.GRANT_SERIAL_PERMISSION_NAME, mProfileManager, onProfileApplied)                    .execute(permissionXml.getSerialPermissionXml());

            // Process            new ProcessProfile(XML.GRANT_IMEI_PERMISSION_NAME, mProfileManager, onProfileApplied)                    .execute(permissionXml.getImeiPermissionXml());

        } catch (PackageManager.NameNotFoundException | DecoderException e) {            e.printStackTrace();        }    } else {        Log.e(TAG, "Error Obtaining ProfileManager!");        Toast.makeText(this, "Error Obtaining ProfileManager!", Toast.LENGTH_LONG)                .show();    }}

如您在上面的代码示例中所看到的,我们通过调用getInstance API并通过FEATURE_TYPE.PROFILE作为唯一参数从emdkManager中获取ProfileManager的实例。

一旦获得了ProfileManager的实例,就可以利用一个名为ProcessProfile的实用程序类,它将为我们异步处理(使用AsyncTask)此配置文件,并在onProfileApplied回调中通知完成。请注意,我们必须执行两次此操作-一次是授予IMEI编号许可,一次是授予序列号许可,因此我们需要在回调中执行检查以确保两个配置文件均得到处理:

private OnProfileApplied onProfileApplied = new OnProfileApplied() {

    // Holder - this is needed because we can't apply two access manager permissions in a single profile    int numberOfResults = 0;    int numberOfPermissionsToGrant = 2;

    // Return Intent for StartActivityForResult    Intent resultIntent = new Intent();

    @Override    public void profileApplied(String statusCode, String extendedStatusCode) {        // Update Results Holder        if (++numberOfResults == numberOfPermissionsToGrant) {            resultIntent.putExtra(PERMISSIONS_GRANTED_EXTRA, true);            resultIntent.putExtra(PERMISSIONS_STATUS_CODE, statusCode);            resultIntent.putExtra(PERMISSIONS_EXTENDED_STATUS_CODE, extendedStatusCode);            setResult(RESULT_OK, resultIntent);            finish();        }    }

    @Override    public void profileError(String statusCode, String extendedStatusCode) {        resultIntent.putExtra(PERMISSIONS_GRANTED_EXTRA, false);        resultIntent.putExtra(PERMISSIONS_STATUS_CODE, statusCode);        resultIntent.putExtra(PERMISSIONS_EXTENDED_STATUS_CODE, extendedStatusCode);        setResult(RESULT_OK, resultIntent);        finish();    }};

在回调中通知我们两个权限均已授予后,我们将通知调用活动并完成权限活动。

现在,我们可以返回MainActivity并访问“序列号和IMEI号”权限

如果您想了解有关如何使用我们的内容提供程序访问这些权限的更多详细信息,

请参阅RetrieveOEMInfo.class或 达里·坎贝尔(Darryn Campbell)的分享: https://developer.zebra.com/blog/access-serial-number-and-imei-mobile-computers-running-android-10

**同时感谢 Wang,Jian 提供的方法1和演示程序


谢谢你的关注和转发

欢迎收藏

android h5可以获取设备的imei 和iccid_Android10 下获取序列号和IMEI号的权限相关推荐

  1. html怎么获取设备宽度,css - 在javascript中获取设备宽度

    css - 在javascript中获取设备宽度 有没有办法使用javascript获取用户设备宽度,而不是视口宽度? 正如我所说,CSS媒体查询提供了这一点 @media screen and (m ...

  2. 浏览器获取设备信息_一条命令获取 IE 浏览器保存网站的账号和密码信息

    渗透攻击红队 一个专注于红队攻击的公众号 大家好,这里是 渗透攻击红队 的第 41 篇文章,本公众号会记录一些我学习红队攻击的复现笔记(由浅到深),不出意外每天一更 Powershell 内网渗透一直 ...

  3. linux获取机器cpuid地址函数,Linux下获取CPUID、硬盘序列号与MAC地址

    在很多系统软件的开发中,需要使用一些系统的唯一性信息.所以,得到主机的CPUID.硬盘序列号及网卡的MAC地址,就成个一件很重要的应用. 本人经过一番google即自己的钻研,基本上实现了这几个功能. ...

  4. Android专业获取设备信息如:AndroidID、唯一设备ID、制造商、型号、版本号、版本码等

    在开发app中很多时候需要获取设备的基本信息等运用到项目中,就需要一些方法获取,网上资源中方法五花八门,有的还获取不到,令人头大,话不多说,鄙人整理了一套方法,话不多说真机测试如下>上图: 接下 ...

  5. Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)

    Android获取设备各项信息(设备id.ip地址.APP应用名称.设备名称.运行商.品牌.型号.分辨率.处理器.国家码.系统语言.网络类型.oaid.android版本.操作系统版本.mac地址.应 ...

  6. 在Java中获取Android端登陆的设备信息

    最近在项目中有个需求,需要获取Android设备的信息,例如:华为,Android10. 可以通过request.getHeader("User-Agent");中来解析出.但是实 ...

  7. 安卓获取设备及系统信息小结

    安卓开发过程中,免不了要获取一些系统信息,大致就是从 Build.PackageInfo.ApplicationInfo.TelephonyManager 四个类中拿. 下面开始介绍四个常用获取设备信 ...

  8. 前端获取计算机设备信息,前端获取设备/APP信息

    HWH5.getDeviceInfo 获取系统信息:包含设备OS类型.设备版本.设备名称 扫码体验: 请求参数 无. 返回结果参数说明deviceName设备名称 osType设备平台类型,可选值:i ...

  9. unity安卓获取设备的gpu和cpu并进行适配

    unity怎么获取设备的gpu: 链接:https://docs.unity3d.com/cn/current/ScriptReference/SystemInfo.html 官方systemInfo ...

最新文章

  1. 卷积神经网络CNN---权值共享
  2. MySQL图形处理软件Navicat字体配置(乱码解决)
  3. 企业工作流程化重要吗?
  4. VS2010 LNK1123:转换到 COFF期间失败:文件无效或损坏”的解决方法
  5. linux bind日志级别,BIND日志相关(一)
  6. 30个基于jQuery的日期时间选择插件
  7. 解决gensim fasttext官方案例报错TypeError: Either one of corpus_file or corpus_iterable value must be provide
  8. ARM 指令集 比较指令
  9. 【图论】昂贵的聘礼(最短路变形)
  10. CCNA学习指南记录
  11. mysql 数据库编码格式_查看mysql编码方式 mysql数据库编码查看方法
  12. 如何实现流水号二维码批量生成
  13. arcgis 空间交集 计算_基于ArcGIS的GIS缓冲区与叠加分析的综合应用——以大型商场选址为例...
  14. 计算机无法连接到宽带,win10提示无法连接到宽带连接不能建立到远程计算机怎么解决...
  15. vue点击把某个区域变成图片数据
  16. 十五个闭目养神、调养身心的方法
  17. MATLAB 数据频数统计
  18. 闻道有先后,术业有专攻
  19. 张晓楠讲如何提高英语听力
  20. 解密一个量化对冲基金开发人员的工作内容

热门文章

  1. CentOS 7 安装harbor1.5.0
  2. Scala中Manifest、ClassTag、TypeTag的学习
  3. (Oracle)PL SQL的相关知识与实例
  4. 发现check_nginx.sh 里的一个小bug~~~
  5. linux 进程 地址空间 内存分布 简介
  6. python3 配置文件操作库 configparser 读取配置文件后 元组列表转字典
  7. java -cp 和 java -jar 的区别
  8. git 比较两个版本之间的区别
  9. nmap 获取主机名
  10. 各类攻击 单一协议 pcap数据包 下载网站