MTK平台Android9.0 NVRAM的读写---上层实现SN和MAC读写

前言

MTK平台有自己的序列号和MAC地址烧录工具,但只能用于个人的调试,如果产品要量产,还使用MTK平台自己的烧录工具,则就不合适了,因为满足不了工厂生产的一些客制化功能,比如SN号和MAC地址拼凑在一起同时烧录,MTK烧录工具就做不到。那么就需要设备厂商自己开发烧录工具了。本文就是解决MTK 平台Android9.0上如何通过应用层来进行读写SN号和MAC地址。

本人也开通了微信公众号【Android系统实战开发】,也可以扫描如下二维码查阅本文。
在这里插入图片描述

概述

在MTK平台中,SN号和MAC地址都是保存在NVRAM中的,所以读写SN号和MAC地址,实际上就是对NVRAM进行读写操作。而在Android9.0系统中,NVRAM的读写方式已经发生改变,跟Android8.0以前的读写方式不同。

Android8.0以前NVRAM的读写方式

Android8.0以前,是通过AIDL的方式去获取一个名为【NvRAMAgent】的服务,然后通过该服务调用相关接口进行读写,获取NVRAM服务的方式如下:

IBinder binder = ServiceManager.getService("NvRAMAgent");

NvRAMAgent agent = NvRAMAgent.Stub.asInterface(binder);

读写方式如下:

fid = getProductInfoLid(); //这里获取SN的lid
byte[] ret = agent.readFile(fid); //通过lid去读取产品SN

agent.writeFile(fid, ret); //向NVRAM中写入SN

Android8.0以前,向NVRAM中读写SN或者MAC地址等信息时,一般是通过LID的方式,LID的值是在native中定义的。可以通过一个native函数获取到SN或者MAC地址对应的LID号,然后再进行读写。

LID号可以简单理解为SN或者MAC地址在NVRAM中的地址。

Android9.0 NVRAM的读写方式

到了Android8.0之后(这里以Android9.0系统为例),NVRAM的读写方式已经变更,不再通过AIDL去获取NVRAM服务,然后进行读写。而是通过HIDL的方式去获取服务来进行读写,方法如下:

import vendor.mediatek.harware.nvram.V1_0.INvram;

INvram agent = INvram.getService();

读写方法:

import com.android.internal.util.HexDump;
//读取:
String buffer = agent.readFileByName(path,size);
//size读取多长的数据,处理数据要注意直接通过字符串getByte获取的长度
//会是size的两倍+1(size是有效大小,根据Nvram存储的数据结构决定)
//+1是因为字符串带有结束符

//写入:
byte[] buff = HexDump.hexStringToByteArray(buffer.subString(0,buffer.length() - 1);

ArrayList<Byte> dataArray = new ArrayList<Byte>(size);

/*修改buff数组中某一个字节的数据,然后重新写入到Nvram:
buff[index] = 0xff;
將修改后的字节数组存到Array中,*/
for(int index = 0; index < size; index ++) {

    dataArray.add(index,new Byte(buff[index]))  
}
//最后需要:
agent.writeFileByNamevec(path,size,dataArray);

可以看到,Android8.0前后,NVRAM读写的不同点如下:

1.获取NVRAM服务的方式不一样,一个是AIDL,一个是HIDL;
2.NVRAM服务的接口不一致,一个是通过LID号的方式来进行读写,一个是通过节点的方式来进行读写;

这里需要注意的是,调用NvRam的新读写方法,这里要在Android.mk中新增依赖库,否则会编译不通过:

LOCAL_STATIC_JAVA_LIBRARIES += \

vendor.mediatek.hardware.nvram-V1.0-java-static

上层如何使用NVRAM接口

Android9.0 NVRAM的接口在上一节已经大概介绍,细心的朋友已经注意到,新的NVRAM接口是通过节点方式来读写的,那么这个节点在哪里呢?节点路径如下:

/vendor/nvdata/APCFG/APRDEB/WIFI  //wifi mac 地址
/VENDOR/nvdata/APCFG/APRDEB/BT_Addr //蓝牙 mac地址
/VENDOR/nvdata/APCFG/APRDEB/PRODUCT_INFO //SN号

调用如上接口,传入以上路径,就可以读写SN号和MAC地址。

但是,这里要说一个比较坑的事。那就是,如果通过这种方法去读写SN号,那么系统重启之后,SN号并没有更新成我们所烧录的那个SN号。这是因为在MTK Android9.0中,有两种方式读写SN号:客户应用自己写或者通过MTK烧录工具烧写。专门提供给应用层读写的,路径就是如上提供的,但这个SN号读写之后并不会被系统所识别,也就是说不会被写入到序列号相关的属性中,如ro.serialno。另外一种通过烧录工具写入的,写入的地方为/dev/pro_info,重启后,这个可以被系统识别。

那如果即想要实现上层读写SN号&#x

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值