生活随笔
收集整理的這篇文章主要介紹了
高通平台java层操作NV数据的方法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊打開鏈接
文檔目的
在Android手機生產過程中,有時需要做一些器件測試或者其他壓力測試,并且保存測試結果,即使手機恢復出場設置或者重新下載版本也不會擦出這些結果,這個時候就要用到NV來保存。本文主要介紹高通平臺上層通過調用jni層方法保存NV和讀取NV的方法。
java層方法定義
使用高通的工具QXDM連接手機,用NV Browser查看手機的NV數據:
接下來以NVID[02497] Factory Data Storage Area 1為例。
新建一個java文件: NvWriter.java
[java]?view plaincopy
public?class?NvWriter?{??????private?static?final?String?TAG?=?"NvWriter-TAG";??????private?static?NvWriter?sInstance?=?null;??????????????public?static?final?char?PASS?=?'P';??????public?static?final?char?FAIL?=?'F';??????public?static?final?char?NA?=?'?';????????static?{????????System.loadLibrary("nvwriter_jni");??????}??????private?native?String?native_readflag_NV();??????private?native?void?native_writeflag_NV(int?index,char?result);????????public?static?NvWriter?getInstance()?{????????if?(sInstance?==?null)?{??????????sInstance?=?new?NvWriter();????????}????????return?sInstance;??????}????????public?String?readFlagNV()?{????????String?mFlagNv?=?native_readflag_NV();????????Log.i(TAG,"readFlagNV:?mFlagNv?=?"?+?mFlagNv);????????return?mFlagNv;??????}????????public?void?writeFlagNV(int?index,char?result)?{????????native_writeflag_NV(index,result);??????}????????public?char?getFlag(int?index)?{????????String?mFlagNv?=?readFlagNV();????????char?flag?=?NA;????????if?(mFlagNv?!=?null?&&?mFlagNv.length()?>=?index)?{??????????flag?=?mFlagNv.charAt(index);????????}????????Log.i(TAG,index?+?":?flag?=?"?+?flag);????????return?flag;??????}??}??這個類中只有幾個簡單的方法:1.一個單實例的構造方法2.3個public的操作NV的java方法3.2個native方法這樣我們在需要操作NV的地方,可以像下面這樣:1.寫NV:
[java]?view plaincopy
NvWriter.getInstance().writeFlagNV(index,NvWriter.PASS);??? ? 2.讀取NV:
[java]?view plaincopy
NvWriter.getInstance().getFlag(index);??上述方法具體實現都是在jni層,我們接下來看一下jni層是如何實現的。
Jni層方法實現
新建一個cpp文件nvwriter.cpp:
[cpp]?view plaincopy
#include?<unistd.h>??#include?<utils/Log.h>??#include?<cutils/log.h>??#include?<jni.h>??#include?<JNIHelp.h>??#include?<stdlib.h>??#include?"android_runtime/AndroidRuntime.h"????#include?<android/log.h>??#include?"nv.h"??#ifdef?LOG_TAG??#undef?LOG_TAG??#endif??#define?LOG_TAG?"NVWriter-TAG-JNI"??#define?LOGI(...)?__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)????static?int?SHOW_LOG?=?1;???static?int?SHOW_NV_LOG?=?0;???static?const?char*?const?className?=?"com/xxx/nv/NvWriter";????jint?NativeInit()?{????????????if(!Diag_LSM_Init(NULL))?{???????????LOGI("Diag_LSM_Init()?failed.");??????????return?-1;??????}????????LOGI("Diag_LSM_Init?succeeded.?\n");????????????register_callback();????????return?1;??}????jstring?CharTojstring(JNIEnv*?env,const?char*?str)?{???????jsize?len?=?strlen(str);??????jclass?clsstring?=?env->FindClass("java/lang/String");??????jstring?strencode?=?env->NewStringUTF("utf-8");??????jmethodID?mid?=?env->GetMethodID(clsstring,"<init>","([BLjava/lang/String;)V");??????jbyteArray?barr?=?env->NewByteArray(len);??????env->SetByteArrayRegion(barr,0,len,(jbyte*)str);??????return?(jstring)env->NewObject(clsstring,mid,barr,strencode);??}????void?android_native_writeflag_NV(JNIEnv?*env,jobject?this_,jint?index,jchar?result)?{???????if?(SHOW_LOG)?{??????????LOGI("android_native_writeflag_NV");??????}??????if?(NativeInit()?<?0)?{????????????return;??????}??????unsigned?char?tmp[22]?=?{?0?};??????unsigned?char?after[20]?=?{?0?};??????nv_items_enum_type?nvId?=?NV_FACTORY_DATA_3_I;???????memset(tmp,?0,?sizeof(tmp));?????????memset(after,?0,?sizeof(after));??????diag_nv_read(nvId,tmp,?sizeof(tmp));????????for(int?m=0;m?<?sizeof(tmp)-3;m++)?{????????????if?(tmp[m+3]?==?NULL)?{??????????????after[m]?=?'?';??????????}?else?{??????????????after[m]?=?tmp[m+3];??????????}??????}??????LOGI("android_native_writeflag_NV?index?=?%d\n",(int)index);??????after[sizeof(tmp)-3+1]?=?'\0';??????after[index]?=?result;????????if?(SHOW_NV_LOG)?{??????????for?(int?n=0;n?<?sizeof(after);n++)?{??????????????LOGI("android_native_writeflag_NV,after[%d]?=?%02x?\n",n,after[n]);??????????}??????}??????diag_nv_write(nvId,after,?sizeof(after));????}????jstring?android_native_readflag_NV(JNIEnv?*env)?{???????if?(SHOW_LOG)?{??????????LOGI("android_native_readflag_NV");??????}??????if?(NativeInit()?<?0)?{???????????return?NULL;??????}??????unsigned?char?tmp[23]?=?{?0?};??????unsigned?char?after[21]?=?{?0?};??????memset(tmp,?0,?sizeof(tmp));??????memset(after,?0,?sizeof(after));??????nv_items_enum_type?nvId?=?NV_FACTORY_DATA_3_I;??????diag_nv_read(nvId,tmp,?sizeof(tmp));????????for(int?m=0;m?<?sizeof(tmp)-3;m++)?{????????????if?(tmp[m+3]?==?NULL)?{??????????????after[m]?=?'?';??????????}?else?{??????????????after[m]?=?tmp[m+3];??????????}??????}??????after[sizeof(tmp)-3+1]?=?'\0';??????const?char*?p?=?(const?char*)(char*)after;??????if?(SHOW_NV_LOG)?{??????????for(int?i=0;i?<?sizeof(after);i++)?{??????????????LOGI("android_native_readflag_NV?p[%d]?=?%02x\n",i,p[i]);??????????}??????}????????jstring?flag_string?=?CharTojstring(env,p);????????return?flag_string;??}????JNINativeMethod?gMethods[]?=?{??????????{?"native_writeflag_NV",?"(IC)V",(void*)?android_native_writeflag_NV?},??????????{?"native_readflag_NV",?"()Ljava/lang/String;",(void*)?android_native_readflag_NV?}??};????int?registerNativeMethods(JNIEnv*?env)?{?????????jclass?clazz;??????clazz?=?env->FindClass(className);??????if?(env->RegisterNatives(clazz,?gMethods,??????????????sizeof(gMethods)?/?sizeof(gMethods[0]))?<?0)?{??????????return?-1;??????}??????return?0;??}????jint?JNI_OnLoad(JavaVM*?vm,?void*?reserved)?{??????JNIEnv*?env?=?NULL;??????jint?result?=?-1;????????if?(vm->GetEnv((void**)?&env,?JNI_VERSION_1_4)?==?JNI_OK)?{??????????if?(NULL?!=?env?&&?registerNativeMethods(env)?==?0)?{??????????????result?=?JNI_VERSION_1_4;??????????}??????}??????return?result;??}??這個cpp要做的事情主要有以下幾點:
1.注冊JNI方法
2.調用高通平臺自帶的操作nv的方法進行讀取和寫NV
3.處理返回的值并傳遞給java層
有三點需要注意:
1.diag_nv_read讀取返回的nv值前三位要去掉
2.返回的char要轉化為jstring才能傳遞給上層
3.nv操作必須要先調用Diag_LSM_Init(NULL)初始化,并register_callback();
總結一下:
由于高通平臺自帶的源碼中就有操作NV的函數,但是是位于cpp中的(vendor/qcom/proprietary/fastmmi和vendor/qcom/proprietary/diag中),但是我們自己的java文件無法直接調用高通的cpp文件,所以我們需要寫一個jni文件進行中轉。
即:我們的java->我們的jni->高通的cpp
最終實現我們的需求。
最后再注:
在jni文件對應的Android.mk中要加入以下語句,不然會編譯報錯:
[plain]?view plaincopy
LOCAL_C_INCLUDES?+=?\??????vendor/qcom/proprietary/fastmmi/libmmi?\??????external/libcxx/include?\??????external/skia/include/core?\??????external/libxml2/include?\??????external/icu/icu4c/source/common?\??????$(QC_PROP_ROOT)/diag/include?\??????$(QC_PROP_ROOT)/diag/src/?\??????$(TARGET_OUT_HEADERS)/common/inc????LOCAL_SHARED_LIBRARIES?:=?\??????libutils?\??????libcutils?\??????libc?\??????libmmi?\??????libdiag??
總結
以上是生活随笔為你收集整理的高通平台java层操作NV数据的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。