Android系统开发 android8之后版本读写Nvram
<h1><span style="color: rgba(0, 128, 128, 1)">前言</span></h1><p><span style="color: rgba(0, 128, 128, 1)"> <span style="color: rgba(0, 0, 0, 1)">此博客讲解</span></span><span style="color: rgba(0, 0, 0, 1)">Android8之后的版本为准,Android8.0以前,是通过AIDL的方式去获取一个名为【NvRAMAgent】的服务。 到了Android8.0之后,NVRAM的读写方式已经变更,不再通过AIDL去获取NVRAM服务,然后进行读写。而是通过HIDL的方式去获取服务来进行读写。</span></p>
<p><span style="color: rgba(0, 0, 0, 1)"> 另外请注意,此博客讲解的是如何使用Android studio上编译的apk工程读写Nvram中的SN与WiFi的Mac地址。如果是系统工程apk请拉到博客最下面。</span></p>
<h1><span style="color: rgba(0, 128, 128, 1)">了解文件位置</span></h1>
<p>在开始实现具体操作流程之前先了解下在系统工程目录里新的NVRAM是怎么生成的。HIDL的是需要依靠系统编译成so与jar形成接口来调用的,类似于AIDL与JNI的组合使用。另外这里只需要了解,并不需要修改这些文件与代码。因为我们需要得到经过系统编译后的so与jar文件,将其导入到后续我们的apk项目里。</p>
<h2><span style="color: rgba(0, 51, 102, 1)">hal文件</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">路径:</span></p>
<div class="cnblogs_code">
<pre>vendor/mediatek/proprietary/hardware/interfaces/nvram/<span style="color: rgba(128, 0, 128, 1)">1.0</span>/INvram.hal</pre>
</div>
<p> 代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* </span><span style="color: rgba(0, 128, 0, 1); text-decoration: underline">http://www.apache.org/licenses/LICENSE-2.0</span><span style="color: rgba(0, 128, 0, 1)">
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
package vendor.mediatek.hardware.nvram@</span><span style="color: rgba(128, 0, 128, 1)">1.0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* Purpose:
* Nvram hidl interface is used by java layer to access nvram file
* Note:
* Support nvram file list in nvram@1.0 was listed as below
* Please update nvram interface and versoin if new nvram file need to be supported
*
/vendor/nvdata/APCFG/APRDEB/BT_Addr
/vendor/nvdata/APCFG/APRDCL/AUXADC
/vendor/nvdata/media/CAMERA_Para
/vendor/nvdata/media/CAMERA_3A
/vendor/nvdata/media/CAMERA_SHADING
/vendor/nvdata/media/CAMERA_DEFECT
/vendor/nvdata/media/CAMERA_SENSOR
/vendor/nvdata/media/CAMERA_LENS
/vendor/nvdata/APCFG/APRDCL/UART
/vendor/nvdata/APCFG/APRDCL/FACTORY
/vendor/nvdata/APCFG/APRDCL/BWCS
/vendor/nvdata/APCFG/APRDCL/HWMON_ACC
/vendor/nvdata/APCFG/APRDCL/HWMON_GYRO
/vendor/nvdata/media/Voice_Recognize_Param
/vendor/nvdata/media/Audio_AudEnh_Control_Opt
/vendor/nvdata/media/Audio_VOIP_Param
/vendor/nvdata/APCFG/APRDCL/HWMON_PS
/vendor/nvdata/APCFG/APRDCL/MD_Type
/vendor/nvdata/APCFG/APRDCL/EXT_MD_Type
/vendor/nvdata/APCFG/APRDCL/SDIO
/vendor/nvdata/media/CAMERA_VERSION
/vendor/nvdata/media/CAMERA_FEATURE
/vendor/nvdata/media/CAMERA_GEOMETRY
/vendor/nvdata/APCFG/APRDCL/MD_SBP
/vendor/nvdata/media/CAMERA_SHADING2
/vendor/nvdata/media/CAMERA_PLINE
/vendor/nvdata/media/CAMERA_AF
/vendor/nvdata/media/CAMERA_FLASH_CALIBRATION
/vendor/nvdata/media/Audio_Sph
/vendor/nvdata/APCFG/APRDEB/GPS
/vendor/nvdata/media/Audio_CompFlt
/vendor/nvdata/media/Audio_Effect
/vendor/nvdata/APCFG/APRDEB/WIFI
/vendor/nvdata/APCFG/APRDEB/WIFI_CUSTOM
/vendor/nvdata/media/Audio_Sph_Med
/vendor/nvdata/media/Audio_Vol_custom
/vendor/nvdata/media/Sph_Dual_Mic
/vendor/nvdata/media/Audio_Wb_Sph
/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO
/vendor/nvdata/media/Headphone_CompFlt
/vendor/nvdata/media/Audio_gain_table
/vendor/nvdata/media/Audio_ver1_Vol_custom
/vendor/nvdata/media/Audio_Hd_Record_Param
/vendor/nvdata/media/Audio_Hd_Record_Scene_Table
/vendor/nvdata/media/Audio_Buffer_DC_Calibration_Param
/vendor/nvdata/media/VibSpk_CompFlt
/vendor/nvdata/media/MusicDRC_CompFlt
/vendor/nvdata/media/RingToneDRC_CompFlt
/vendor/nvdata/media/Audio_MAGI_CONFERENCE
/vendor/nvdata/media/Audio_HAC_Param
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> INvram {
readFileByName(</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> filename, uint32_t size)
generates (</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> data);
writeFileByNamevec(</span><span style="color: rgba(0, 0, 255, 1)">string</span> filename, uint32_t size, vec<uint8_t><span style="color: rgba(0, 0, 0, 1)"> data)
generates (int8_t retval);
};</span></pre>
</div>
<h2><span style="color: rgba(0, 51, 102, 1)">.h文件</span></h2>
<p><span style="color: rgba(0, 51, 102, 1)">路径</span></p>
<div class="cnblogs_code">
<pre>vendor/mediatek/proprietary/external/libnvram/nvram_hidl/<span style="color: rgba(128, 0, 128, 1)">1.0</span>/NvRam.h</pre>
</div>
<p>代码:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">#ifndef VENDOR_MEDIATEK_HARDWARE_NVRAM_V1_0_NVRAM_H
</span><span style="color: rgba(0, 0, 255, 1)">#define</span> VENDOR_MEDIATEK_HARDWARE_NVRAM_V1_0_NVRAM_H<span style="color: rgba(0, 0, 0, 1)">
#include </span><vendor/mediatek/hardware/nvram/<span style="color: rgba(128, 0, 128, 1)">1.0</span>/INvram.h><span style="color: rgba(0, 0, 0, 1)">
#include </span><hidl/MQDescriptor.h><span style="color: rgba(0, 0, 0, 1)">
#include </span><hidl/Status.h>
<span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> vendor {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> mediatek {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> hardware {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> nvram {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> V1_0 {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> implementation {
</span><span style="color: rgba(0, 0, 255, 1)">using</span> ::android::hidl::<span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">::V1_0::DebugInfo;
</span><span style="color: rgba(0, 0, 255, 1)">using</span> ::android::hidl::<span style="color: rgba(0, 0, 255, 1)">base</span><span style="color: rgba(0, 0, 0, 1)">::V1_0::IBase;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::vendor::mediatek::hardware::nvram::V1_0::INvram;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::hidl_array;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::hidl_memory;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::hidl_string;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::hidl_vec;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::Return;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::hardware::Void;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> ::android::sp;
</span><span style="color: rgba(0, 0, 255, 1)">struct</span> Nvram : <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> INvram {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Methods from ::vendor::mediatek::hardware::nvram::V1_0::INvram follow.</span>
Return<<span style="color: rgba(0, 0, 255, 1)">void</span>> readFileByName(<span style="color: rgba(0, 0, 255, 1)">const</span> hidl_string& filename, uint32_t size, readFileByName_cb _hidl_cb) <span style="color: rgba(0, 0, 255, 1)">override</span><span style="color: rgba(0, 0, 0, 1)">;
Return</span><int8_t> writeFileByNamevec(<span style="color: rgba(0, 0, 255, 1)">const</span> hidl_string& filename, uint32_t size, <span style="color: rgba(0, 0, 255, 1)">const</span> hidl_vec<uint8_t>& data) <span style="color: rgba(0, 0, 255, 1)">override</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Methods from ::android::hidl::base::V1_0::IBase follow.</span>
<span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">C</span><span style="color: rgba(128, 0, 0, 1)">"</span> INvram* HIDL_FETCH_INvram(<span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">char</span>*<span style="color: rgba(0, 0, 0, 1)"> name);
}</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace implementation</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace V1_0</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace nvram</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace hardware</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace mediatek</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace vendor</span>
<span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> VENDOR_MEDIATEK_HARDWARE_NVRAM_V1_0_NVRAM_H</span></pre>
</div>
<h2><span style="color: rgba(0, 51, 102, 1)">.cpp文件</span></h2>
<p><span style="color: rgba(0, 51, 102, 1)">路径</span></p>
<div class="cnblogs_code">
<pre>vendor/mediatek/proprietary/external/libnvram/nvram_hidl/<span style="color: rgba(128, 0, 128, 1)">1.0</span>/NvRam.cpp</pre>
</div>
<p>代码:</p>
<div class="cnblogs_code">
<pre>#include <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Nvram.h</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
#include </span><android-<span style="color: rgba(0, 0, 255, 1)">base</span>/logging.h><span style="color: rgba(0, 0, 0, 1)">
#include </span><log/log.h><span style="color: rgba(0, 0, 0, 1)">
#include </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">libnvram.h</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
#include </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">libnvram_log.h</span><span style="color: rgba(128, 0, 0, 1)">"</span>
<span style="color: rgba(0, 0, 255, 1)">using</span> std::<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">#define</span> NVRAM_LOG(...) \
<span style="color: rgba(0, 0, 255, 1)">do</span><span style="color: rgba(0, 0, 0, 1)"> { \
ALOGD(__VA_ARGS__); \
} </span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> vendor {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> mediatek {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> hardware {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> nvram {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> V1_0 {
</span><span style="color: rgba(0, 0, 255, 1)">namespace</span><span style="color: rgba(0, 0, 0, 1)"> implementation {
</span><span style="color: rgba(0, 0, 255, 1)">void</span> covertVector2Array(std::vector<uint8_t> <span style="color: rgba(0, 0, 255, 1)">in</span>, <span style="color: rgba(0, 0, 255, 1)">char</span>* <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">int</span> size = <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)">.size();
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < size; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">out</span> = <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)">.at(i);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">void</span> covertArray2Vector(<span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">char</span>* <span style="color: rgba(0, 0, 255, 1)">in</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> len, std::vector<uint8_t>& <span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">out</span><span style="color: rgba(0, 0, 0, 1)">.clear();
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < len; i++<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">out</span>.push_back(<span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)">);
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Methods from ::vendor::mediatek::hardware::nvram::V1_0::INvram follow.</span>
Return<<span style="color: rgba(0, 0, 255, 1)">void</span>> Nvram::readFileByName(<span style="color: rgba(0, 0, 255, 1)">const</span> hidl_string&<span style="color: rgba(0, 0, 0, 1)"> filename, uint32_t size, readFileByName_cb _hidl_cb) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO implement</span>
<span style="color: rgba(0, 0, 255, 1)">int</span> pRecSize=<span style="color: rgba(128, 0, 128, 1)">0</span>,pRecNum=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsRead=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> *buff=<span style="color: rgba(0, 0, 0, 1)">NULL;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> file_lid = -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> result;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> *nvramstr = (<span style="color: rgba(0, 0, 255, 1)">char</span>*)malloc(<span style="color: rgba(128, 0, 128, 1)">2</span>*size+<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">char</span> *nvramptr =<span style="color: rgba(0, 0, 0, 1)"> nvramstr;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> *cstr=<span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">char</span>;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (nvramstr==NULL || size==<span style="color: rgba(128, 0, 128, 1)">0</span> || cstr==<span style="color: rgba(0, 0, 0, 1)">NULL) {
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nvramstr==NULL\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(nvramstr!=<span style="color: rgba(0, 0, 0, 1)">NULL)
free(nvramstr);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(cstr!=<span style="color: rgba(0, 0, 0, 1)">NULL)
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
snprintf(cstr, filename.size()</span>+<span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%s</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, filename.c_str());
file_lid </span>=<span style="color: rgba(0, 0, 0, 1)"> NVM_GetLIDByName(cstr);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(file_lid < <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Get LID by name fail! %s\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,cstr);
free(nvramstr);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
F_ID fd</span>=NVM_GetFileDesc(file_lid,&pRecSize,&<span style="color: rgba(0, 0, 0, 1)">pRecNum,IsRead);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (fd.iFileDesc==-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
LOG(ERROR) </span><< <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">open file Error!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
free(nvramstr);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
LOG(ERROR) </span><< <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RecNum is </span><span style="color: rgba(128, 0, 0, 1)">"</span><<<span style="color: rgba(0, 0, 0, 1)">pRecNum;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">size=pRecSize*pRecNum;</span>
buff=(<span style="color: rgba(0, 0, 255, 1)">char</span> *<span style="color: rgba(0, 0, 0, 1)">)malloc(size);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(buff ==<span style="color: rgba(0, 0, 0, 1)"> NULL)
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Malloc Error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">NVM_CloseFileDesc(fd))
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
free(nvramstr);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span>((ssize_t)size ==<span style="color: rgba(0, 0, 0, 1)"> read(fd.iFileDesc,buff,(ssize_t)size))
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(NVM_CloseFileDesc(fd))
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Read Done!Size is %d\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,size);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">return buff;</span>
<span style="color: rgba(0, 0, 0, 1)"> }
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Close file error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
free(buff);
free(nvramstr);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">read File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">NVM_CloseFileDesc(fd))
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
free(buff);
free(nvramstr);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nvramstr buff%x, buff%x, buff%x, buff%x, buff%x, buff%x, buff%x, buff%x, buff%x \n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
buff[</span><span style="color: rgba(128, 0, 128, 1)">0</span>],buff[<span style="color: rgba(128, 0, 128, 1)">1</span>],buff[<span style="color: rgba(128, 0, 128, 1)">2</span>],buff[<span style="color: rgba(128, 0, 128, 1)">3</span>],buff[<span style="color: rgba(128, 0, 128, 1)">4</span>],buff[<span style="color: rgba(128, 0, 128, 1)">5</span>],buff[<span style="color: rgba(128, 0, 128, 1)">6</span>],buff[<span style="color: rgba(128, 0, 128, 1)">7</span>],buff[<span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">for</span>(i=<span style="color: rgba(128, 0, 128, 1)">0</span>; i<(<span style="color: rgba(0, 0, 255, 1)">int</span>)size; i++<span style="color: rgba(0, 0, 0, 1)">)
{
nvramptr </span>+= sprintf(nvramptr, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%02X</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,buff);
}
sprintf(nvramptr,</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span>*(nvramptr+<span style="color: rgba(128, 0, 128, 1)">1</span>)=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">\0</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">nvramstr %s\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,nvramstr);
_hidl_cb(nvramstr);
free(buff);
delete[] cstr;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Void();
}
Return</span><int8_t> Nvram::writeFileByNamevec(<span style="color: rgba(0, 0, 255, 1)">const</span> hidl_string& filename, uint32_t size, <span style="color: rgba(0, 0, 255, 1)">const</span> hidl_vec<uint8_t>&<span style="color: rgba(0, 0, 0, 1)"> data) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO implement</span>
<span style="color: rgba(0, 0, 255, 1)">char</span> *cstr_filename=<span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">char</span>;
</span><span style="color: rgba(0, 0, 255, 1)">char</span> *cstr_data=<span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">char</span>;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (cstr_data==NULL || size==<span style="color: rgba(128, 0, 128, 1)">0</span> || cstr_filename==<span style="color: rgba(0, 0, 0, 1)">NULL) {
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">cstr_data==NULL\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(cstr_data!=<span style="color: rgba(0, 0, 0, 1)">NULL)
delete[] cstr_data;
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(cstr_filename!=<span style="color: rgba(0, 0, 0, 1)">NULL)
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
snprintf(cstr_filename, filename.size()</span>+<span style="color: rgba(128, 0, 128, 1)">1</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">%s</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, filename.c_str());
covertVector2Array(data, cstr_data);
</span><span style="color: rgba(0, 0, 255, 1)">int</span> pRecSize=<span style="color: rgba(128, 0, 128, 1)">0</span>,pRecNum=<span style="color: rgba(128, 0, 128, 1)">0</span>,looptimes=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">bool</span> IsRead=<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">int</span> file_lid = -<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
file_lid </span>=<span style="color: rgba(0, 0, 0, 1)"> NVM_GetLIDByName(cstr_filename);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(file_lid < <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Get LID by name fail!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
delete[] cstr_data;
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
F_ID fd</span>=NVM_GetFileDesc(file_lid,&pRecSize,&<span style="color: rgba(0, 0, 0, 1)">pRecNum,IsRead);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (fd.iFileDesc==-<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">open file Error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
delete[] cstr_data;
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
</span><span style="color: rgba(0, 0, 255, 1)">#if</span> 0
<span style="color: rgba(0, 0, 255, 1)">if</span>(size !=<span style="color: rgba(0, 0, 0, 1)"> pRecSize)
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Input size (%d) and RecSize (%d) not match!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,size,pRecSize);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">NVM_CloseFileDesc(fd))
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">return 0;</span>
<span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> GetFileDesc should return right pos and this would cause pro_info multi lids issue.</span>
<span style="color: rgba(0, 0, 255, 1)">#if</span> 0
<span style="color: rgba(0, 0, 255, 1)">if</span>(<span style="color: rgba(128, 0, 128, 1)">0</span> != lseek(fd.iFileDesc,<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,SEEK_SET)){
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">lseek error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">NVM_CloseFileDesc(fd))
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">#endif</span><span style="color: rgba(0, 0, 0, 1)">
looptimes </span>=<span style="color: rgba(0, 0, 0, 1)"> pRecNum;
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">RecNum is :%d\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,pRecNum);
</span><span style="color: rgba(0, 0, 255, 1)">while</span>(looptimes--<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span>((ssize_t)size !=<span style="color: rgba(0, 0, 0, 1)"> write(fd.iFileDesc,cstr_data,(ssize_t)size))
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">write file error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span>(!<span style="color: rgba(0, 0, 0, 1)">NVM_CloseFileDesc(fd))
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
delete[] cstr_data;
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)">(NVM_CloseFileDesc(fd))
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Write file Done!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
delete[] cstr_data;
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
NVRAM_LOG(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">close File error!\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
delete[] cstr_data;
delete[] cstr_filename;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> int8_t {};
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">return int8_t {};</span>
<span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Methods from ::android::hidl::base::V1_0::IBase follow.</span>
<span style="color: rgba(0, 0, 0, 1)">
INvram</span>* HIDL_FETCH_INvram(<span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">char</span>* <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> name </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Nvram();
}
}</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace implementation</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace V1_0</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace nvram</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace hardware</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace mediatek</span>
}<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> namespace vendor</span></pre>
</div>
<h2><span style="color: rgba(0, 51, 102, 1)">经过系统编译后输出的so文件路径与jar文件路径</span></h2>
<p><span style="color: rgba(0, 51, 102, 1)">so路径</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">out</span>\target\product\A8385_JS04\obj\SHARED_LIBRARIES\vendor.mediatek.hardware.nvram@<span style="color: rgba(128, 0, 128, 1)">1.0</span>.vendor_intermediates</pre>
</div>
<p>jar路径</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">out</span>\target\common\obj\JAVA_LIBRARIES\vendor.mediatek.hardware.nvram-V1.<span style="color: rgba(128, 0, 128, 1)">0</span>-java_intermediates</pre>
</div>
<p>其中classes.jar就包含了INvram这个类,这里可以用反编译工具解包后查看</p>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108143408766-1015074942.png" alt=""></p>
<p> 如图:</p>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108143903706-942084213.png" alt=""></p>
<h1><span style="color: rgba(0, 128, 128, 1)">读写Nvram中SN号的操作流程</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">这里是Android studio上编译的工程</span></p>
<h2><span style="color: rgba(0, 51, 102, 1)">第一步 导入系统编译Nvram的so与jar</span></h2>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108143625553-1960685561.png" alt=""></p>
<p> 在build里添加</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">android {
compileSdk </span><span style="color: rgba(128, 0, 128, 1)">28</span><span style="color: rgba(0, 0, 0, 1)">
defaultConfig {
applicationId </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">com.xxx.xxxx</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
minSdk </span><span style="color: rgba(128, 0, 128, 1)">26</span><span style="color: rgba(0, 0, 0, 1)">
targetSdk </span><span style="color: rgba(128, 0, 128, 1)">28</span><span style="color: rgba(0, 0, 0, 1)">
versionCode </span><span style="color: rgba(128, 0, 128, 1)">11</span><span style="color: rgba(0, 0, 0, 1)">
versionName </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1.10</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
testInstrumentationRunner </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">androidx.test.runner.AndroidJUnitRunner</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加</span>
<span style="color: rgba(0, 0, 0, 1)"> sourceSets {
main {
jniLibs.srcDirs </span>= [<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">libs</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">]
}
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">略...</span>
<span style="color: rgba(0, 0, 0, 1)">}
dependencies {
implementation fileTree(dir: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">libs</span><span style="color: rgba(128, 0, 0, 1)">'</span>, include: [<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">*.jar</span><span style="color: rgba(128, 0, 0, 1)">'</span>])<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加</span>
implementation files(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">libs\\classes.jar</span><span style="color: rgba(128, 0, 0, 1)">'</span>)<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">添加</span>
}</pre>
</div>
<h2><span style="color: rgba(0, 51, 102, 1)">第二步 项目必须是系统权限与系统签名</span></h2>
<p>怎么实现请参考博客:https://www.cnblogs.com/guanxinjing/p/11410915.html</p>
<h2><span style="color: rgba(0, 51, 102, 1)">第三步 项目必须架包framework</span></h2>
<p>怎么实现请参考博客:https://www.cnblogs.com/guanxinjing/p/16613716.html</p>
<p>这里说一下为什么需要架framework,因为Android studio在编译的时候会检查到代码里没有IHwInterface这个类并且抛出编译异常,而这个类在framework中。</p>
<div class="cnblogs_code">
<pre>android.os.IHwInterface;</pre>
</div>
<p>这里在啰嗦一下为什么会检查这个类。因为在调用INvram.getService()方法的时候,INvram的基类是IBase</p>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108143057128-1308081574.png" alt=""></p>
<p> </p>
<p>而IBase继承了IHwInterface</p>
<p> <img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108143135438-108068402.png" alt=""></p>
<p> </p>
<h2><span style="color: rgba(0, 51, 102, 1)">第四步 修改系统工程里的代码,删除Nv写入保护的代码</span></h2>
<p>系统工程修改文件路径</p>
<div class="cnblogs_code">
<pre>vendor\mediatek\proprietary\bootable\bootloader\lk\platform\mt6765\write_protect.c</pre>
</div>
<p>修改代码位置</p>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108144246384-657102252.png" alt=""></p>
<p> 如果不删除写入保护set_write_protect,会出现在写入NV的时候如下报错</p>
<p><img src="https://img2022.cnblogs.com/blog/1497956/202211/1497956-20221108145923965-1470317031.png" alt=""></p>
<h2><span style="color: rgba(0, 51, 102, 1)">第五步 使用下面工具类读写SN号,或者Nv里的其他数据 </span></h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.util.Log;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.android.internal.util.HexDump;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.nio.ByteBuffer;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.nio.CharBuffer;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.nio.charset.Charset;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.ArrayList;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> java.util.Arrays;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> vendor.mediatek.hardware.nvram.V1_0.INvram;
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
*
* /vendor/nvdata/APCFG/APRDEB/BT_Addr
* /vendor/nvdata/APCFG/APRDCL/AUXADC
* /vendor/nvdata/media/CAMERA_Para
* /vendor/nvdata/media/CAMERA_3A
* /vendor/nvdata/media/CAMERA_SHADING
* /vendor/nvdata/media/CAMERA_DEFECT
* /vendor/nvdata/media/CAMERA_SENSOR
* /vendor/nvdata/media/CAMERA_LENS
* /vendor/nvdata/APCFG/APRDCL/UART
* /vendor/nvdata/APCFG/APRDCL/FACTORY
* /vendor/nvdata/APCFG/APRDCL/BWCS
* /vendor/nvdata/APCFG/APRDCL/HWMON_ACC
* /vendor/nvdata/APCFG/APRDCL/HWMON_GYRO
* /vendor/nvdata/media/Voice_Recognize_Param
* /vendor/nvdata/media/Audio_AudEnh_Control_Opt
* /vendor/nvdata/media/Audio_VOIP_Param
* /vendor/nvdata/APCFG/APRDCL/HWMON_PS
* /vendor/nvdata/APCFG/APRDCL/MD_Type
* /vendor/nvdata/APCFG/APRDCL/EXT_MD_Type
* /vendor/nvdata/APCFG/APRDCL/SDIO
* /vendor/nvdata/media/CAMERA_VERSION
* /vendor/nvdata/media/CAMERA_FEATURE
* /vendor/nvdata/media/CAMERA_GEOMETRY
* /vendor/nvdata/APCFG/APRDCL/MD_SBP
* /vendor/nvdata/media/CAMERA_SHADING2
* /vendor/nvdata/media/CAMERA_PLINE
* /vendor/nvdata/media/CAMERA_AF
* /vendor/nvdata/media/CAMERA_FLASH_CALIBRATION
* /vendor/nvdata/media/Audio_Sph
* /vendor/nvdata/APCFG/APRDEB/GPS
* /vendor/nvdata/media/Audio_CompFlt
* /vendor/nvdata/media/Audio_Effect
* /vendor/nvdata/APCFG/APRDEB/WIFI
* /vendor/nvdata/APCFG/APRDEB/WIFI_CUSTOM
* /vendor/nvdata/media/Audio_Sph_Med
* /vendor/nvdata/media/Audio_Vol_custom
* /vendor/nvdata/media/Sph_Dual_Mic
* /vendor/nvdata/media/Audio_Wb_Sph
* /vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO
* /vendor/nvdata/media/Headphone_CompFlt
* /vendor/nvdata/media/Audio_gain_table
* /vendor/nvdata/media/Audio_ver1_Vol_custom
* /vendor/nvdata/media/Audio_Hd_Record_Param
* /vendor/nvdata/media/Audio_Hd_Record_Scene_Table
* /vendor/nvdata/media/Audio_Buffer_DC_Calibration_Param
* /vendor/nvdata/media/VibSpk_CompFlt
* /vendor/nvdata/media/MusicDRC_CompFlt
* /vendor/nvdata/media/RingToneDRC_CompFlt
* /vendor/nvdata/media/Audio_MAGI_CONFERENCE
* /vendor/nvdata/media/Audio_HAC_Param
</span><span style="color: rgba(0, 128, 0, 1)">*/</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SNParamUtils {
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String PRODUCT_INFO_FILENAME = "/vendor/nvdata/APCFG/APRDEB/PRODUCT_INFO"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> <span style="color: rgba(0, 0, 255, 1)">int</span> SN_LENGTH = 32<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> writeSn(String sn) {
</span><span style="color: rgba(0, 0, 255, 1)">char</span> sn_chars[] =<span style="color: rgba(0, 0, 0, 1)"> sn.toCharArray();
</span><span style="color: rgba(0, 0, 255, 1)">byte</span> sn_bytes[] =<span style="color: rgba(0, 0, 0, 1)"> getBytes(sn_chars);
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
INvram agent </span>=<span style="color: rgba(0, 0, 0, 1)"> INvram.getService();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (agent != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
ArrayList</span><Byte> dataArray = <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> b : sn_bytes) {
dataArray.add(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Byte(b));
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span> ret_1 =<span style="color: rgba(0, 0, 0, 1)"> agent.writeFileByNamevec(PRODUCT_INFO_FILENAME, SN_LENGTH, dataArray);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ret_1 == 0<span style="color: rgba(0, 0, 0, 1)">) {
Log.e(</span>"zh", "writeSn success " +<span style="color: rgba(0, 0, 0, 1)"> ret_1);
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
Log.e(</span>"zh", "writeSn failed" +<span style="color: rgba(0, 0, 0, 1)"> ret_1);
}
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
Log.e(</span>"zh", "writeSn: agent null"<span style="color: rgba(0, 0, 0, 1)">);
}
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
Log.e(</span>"zh", "writeSn exception:" +<span style="color: rgba(0, 0, 0, 1)"> e.getLocalizedMessage());
e.printStackTrace();
}
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> String readSn() {
</span><span style="color: rgba(0, 0, 255, 1)">int</span> targets = 0<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
String buff </span>= <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
INvram agent </span>=<span style="color: rgba(0, 0, 0, 1)"> INvram.getService();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (agent != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
buff </span>=<span style="color: rgba(0, 0, 0, 1)"> agent.readFileByName(PRODUCT_INFO_FILENAME, SN_LENGTH);
Log.e(</span>"zh", "buff: " +<span style="color: rgba(0, 0, 0, 1)"> buff );
}
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] buffArr = HexDump.hexStringToByteArray(buff.substring(0, buff.length() - 1<span style="color: rgba(0, 0, 0, 1)">));
targets </span>= (buffArr & 0xff) | ((buffArr << 8) & 0xff00) | ((buffArr << 24) >>> 8) | (buffArr << 24<span style="color: rgba(0, 0, 0, 1)">);
Log.e(</span>"zh","readSn: chars=>" + Arrays.toString(getChars(buffArr)) + ", targets == " +<span style="color: rgba(0, 0, 0, 1)"> targets);
Log.e(</span>"zh","readSn: bytes=>" + Arrays.toString((buffArr)) + ", targets == " +<span style="color: rgba(0, 0, 0, 1)"> targets);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> String.valueOf(getChars(buffArr));
} </span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception e) {
Log.e(</span>"zh","readSn exception:" +<span style="color: rgba(0, 0, 0, 1)"> e.getLocalizedMessage());
e.printStackTrace();
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span> "123456789"<span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">char</span>[] getChars(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] bytes) {
Charset cs </span>= Charset.forName("UTF-8"<span style="color: rgba(0, 0, 0, 1)">);
ByteBuffer bb </span>=<span style="color: rgba(0, 0, 0, 1)"> ByteBuffer.allocate(bytes.length);
bb.put(bytes);
bb.flip();
CharBuffer cb </span>=<span style="color: rgba(0, 0, 0, 1)"> cs.decode(bb);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> cb.array();
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] getBytes(<span style="color: rgba(0, 0, 255, 1)">char</span><span style="color: rgba(0, 0, 0, 1)">[] chars) {
Charset cs </span>= Charset.forName("UTF-8"<span style="color: rgba(0, 0, 0, 1)">);
CharBuffer cb </span>=<span style="color: rgba(0, 0, 0, 1)"> CharBuffer.allocate(chars.length);
cb.put(chars);
cb.flip();
ByteBuffer bb </span>=<span style="color: rgba(0, 0, 0, 1)"> cs.encode(cb);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bb.array();
}
}</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">假如你是系统</span><span style="color: rgba(0, 128, 128, 1)">工程</span><span style="color: rgba(0, 128, 128, 1)">编译apk</span></h1>
<h3>可以在apk工程的android.mk里直接导入,不需要以上的第一步到第三步,但是依然需要第四步与第五步</h3>
<pre class="highlighter-hljs" data-dark-theme="true"><code>LOCAL_STATIC_JAVA_LIBRARIES := vendor.mediatek.hardware.nvram-V1.0-java</code></pre>
<div class="cnblogs_code">
<pre>LOCAL_PATH:= $(call my-<span style="color: rgba(0, 0, 0, 1)">dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS :</span>=<span style="color: rgba(0, 0, 0, 1)"> optional
LOCAL_CERTIFICATE :</span>=<span style="color: rgba(0, 0, 0, 1)"> platform
# Add </span><span style="color: rgba(0, 0, 255, 1)">static</span> library <span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> nvram
# LOCAL_STATIC_JAVA_LIBRARIES :</span>= vendor.mediatek.hardware.nvram-V1.1-java-<span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)">
LOCAL_STATIC_JAVA_LIBRARIES :</span>= vendor.mediatek.hardware.nvram-V1.0-<span style="color: rgba(0, 0, 0, 1)">java
LOCAL_SRC_FILES :</span>= $(call all-subdir-java-<span style="color: rgba(0, 0, 0, 1)">files)
LOCAL_PACKAGE_NAME :</span>=<span style="color: rgba(0, 0, 0, 1)"> JNvRAM_V11
LOCAL_PRIVATE_PLATFORM_APIS :</span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
include $(BUILD_PACKAGE)</span></pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">MTK平台如何用Build.getSerial()方法读取写入的SN号</span></h1>
<p><strong><span style="color: rgba(0, 0, 0, 1)">这里直接复制MTK论坛那边的开发回复(下面提是MTK的写号工具SN Write,但是我们这个写NV的方法同样适用):</span></strong></p>
<p>在/vendor/mediatek/proprietary/bootable/bootloader/lk/app/mt_boot/mt_boot.c<br>中,将 #define SERIAL_NUM_FROM_BARCODE 宏定义打开<br>这时SN Write工具写Barcode即可,其他无需修改。<br>这是最简单的方式,相当于serial no取Barcode空间的值。</p>
<p><span style="color: rgba(0, 128, 128, 1)"><img src="https://img2023.cnblogs.com/blog/1497956/202212/1497956-20221219114049817-1344626868.png" alt=""></span></p>
<h1><span style="color: rgba(22, 145, 121, 1)">在NV中读写WiFi的Mac地址</span></h1>
<p><strong><span style="color: rgba(186, 55, 42, 1)">请注意!</span>在Android10版本以后,WiFi已经默认使用随机mac地址</strong>,意思是说,哪怕你写到了NV中,在WifiManager中也不会读取到,这需要你手动设置或者修改代码将,下面的选项从随机Mac地址修改成固定设备的Mac地址。如下图位置:</p>
<p><img src="https://img2023.cnblogs.com/blog/1497956/202310/1497956-20231020144621293-664473884.png"></p>
<p><img src="https://img2023.cnblogs.com/blog/1497956/202310/1497956-20231020144650235-930652558.png"></p>
<p>代码部分:</p>
<p>其他流程与上面一样,这里直接提供读写代码。 </p>
<pre class="language-java highlighter-hljs" data-dark-theme="true"><code>import android.app.Application;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.util.Log;
import com.android.internal.util.HexDump;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.StringTokenizer;
import vendor.mediatek.hardware.nvram.V1_0.INvram;
public class MacParamUtils {
public static final String MAC_ADDRESS_FILENAME = "/vendor/nvdata/APCFG/APRDEB/WIFI";
private static final int MAC_ADDRESS_OFFSET = 4;
private static final int MAC_ADDRESS_DIGITS = 6;
/**
* 通过WifiManager获取WiFi Mac地址
*/
public static String getMACAddress(Application application) {
try {
WifiManager wifiManager = (WifiManager)application.getSystemService(Context.WIFI_SERVICE);
Method getFactoryMacAddresses = wifiManager.getClass().getMethod("getFactoryMacAddresses");
String[] macAddresses= (String[]) getFactoryMacAddresses.invoke(wifiManager);
String macAddress = "";
if (macAddresses.length > 0) {
macAddress = macAddresses;
}
return macAddress;
} catch (Exception e) {
return null;
}
}
/**
* 直接从NV中读取Mac地址
* @return
*/
public static String getWifiMacFromNvram() {
StringBuffer nvramBuf = new StringBuffer();
try {
int i = 0;
String buff = null;
INvram agent = INvram.getService();
if (agent == null) {
Log.e("zh", "NvRAMAgent is null");
return ""; }
try {
buff = agent.readFileByName(MAC_ADDRESS_FILENAME, MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS);
} catch (Exception e) {
e.printStackTrace();
return "";
}
Log.e("zh", "Raw data:" + buff);
if (buff.length() < 2 * (MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS)) {
return "";
}
// Remove the \0 special character.
int macLen = buff.length() - 1;
for (i = MAC_ADDRESS_OFFSET * 2; i < macLen; i += 2) {
if ((i + 2) < macLen) {
nvramBuf.append(buff.substring(i, i + 2));
nvramBuf.append(":");
} else {
nvramBuf.append(buff.substring(i));
}
}
} catch (Exception e) {
e.printStackTrace();
return "";
}
return nvramBuf.toString();
}
/**
* 更新WiFi Mac地址到NV中
* @param mac
* @return
*/
public static int updateWifiMacToNvram(String mac){
try {
int i = 0;
INvram agent = INvram.getService();
byte[] macAddr = new byte;
if (agent == null) {
Log.e("zh", "NvRAMAgent is null");
return 0;
}
//parse mac address firstly
StringTokenizer txtBuffer = new StringTokenizer(mac, ":");
while (txtBuffer.hasMoreTokens()) {
macAddr = (byte) Integer.parseInt(txtBuffer.nextToken(), 16);
i++;
}
if(i != MAC_ADDRESS_DIGITS){
Log.e("zh", "Wrong length of macAddr:" + i);
return 0;
}
String buff = null;
try {
buff = agent.readFileByName(MAC_ADDRESS_FILENAME, MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
byte[] buffArr = HexDump.hexStringToByteArray(buff.substring(0, buff.length() - 1));
for (i = 0; i < MAC_ADDRESS_DIGITS; i ++) {
buffArr = macAddr;
}
ArrayList<Byte> dataArray = new ArrayList<Byte>(MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS);
for (i = 0; i < MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS; i++) {
dataArray.add(i, new Byte(buffArr));
}
int flag = 0;
try {
flag = agent.writeFileByNamevec(MAC_ADDRESS_FILENAME,MAC_ADDRESS_OFFSET + MAC_ADDRESS_DIGITS,dataArray);
return flag;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}catch (Exception e) {
e.printStackTrace();
}
return 0;
}
private static char[] getChars(byte[] bytes) {
Charset cs = Charset.forName("UTF-8");
ByteBuffer bb = ByteBuffer.allocate(bytes.length);
bb.put(bytes);
bb.flip();
CharBuffer cb = cs.decode(bb);
return cb.array();
}
private static byte[] getBytes(char[] chars) {
Charset cs = Charset.forName("UTF-8");
CharBuffer cb = CharBuffer.allocate(chars.length);
cb.put(chars);
cb.flip();
ByteBuffer bb = cs.encode(cb);
return bb.array();
}
}</code></pre>
<p> </p>
<p> </p>
<p>End</p>
</div>
<div id="MySignature" role="contentinfo">
<div style="text-align: center">
<p style="color:orange;font-size:16px;" >本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/16869583.html </p>
<div style="color:orange;font-size:16px;">本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。 </div>
</div><br><br>
来源:https://www.cnblogs.com/guanxinjing/p/16869583.html
頁:
[1]