日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

高通平台java层操作NV数据的方法

發布時間:2025/4/16 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 高通平台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;??
  • ??
  • ????/*FLAG?RESULT*/??
  • ????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;?//?1?for?show?log.??
  • static?int?SHOW_NV_LOG?=?0;?//?1?for?show?log.??
  • static?const?char*?const?className?=?"com/xxx/nv/NvWriter";??
  • ??
  • jint?NativeInit()?{??
  • ????/*?Calling?LSM?init??*/??
  • ????if(!Diag_LSM_Init(NULL))?{?//?調用diag初始化??
  • ????????LOGI("Diag_LSM_Init()?failed.");??
  • ????????return?-1;??
  • ????}??
  • ??
  • ????LOGI("Diag_LSM_Init?succeeded.?\n");??
  • ????/*?Register?the?callback?for?the?primary?processor?*/??
  • ????register_callback();??//?注冊回調方法??
  • ????return?1;??
  • }??
  • ??
  • jstring?CharTojstring(JNIEnv*?env,const?char*?str)?{?//?char轉化為jstring??
  • ????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;?//?我們要操作的NVID??
  • ????memset(tmp,?0,?sizeof(tmp));???//?申請mem??
  • ????memset(after,?0,?sizeof(after));??
  • ????diag_nv_read(nvId,tmp,?sizeof(tmp));??//?調用高通操作nv的api,讀取NV給tmp??
  • ????for(int?m=0;m?<?sizeof(tmp)-3;m++)?{??//?去掉tmp的前三個字段,重新賦值給after??
  • ????????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));??//?調用高通寫nv的api,重新寫nv??
  • }??
  • ??
  • jstring?android_native_readflag_NV(JNIEnv?*env)?{?//?讀取nv??
  • ????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));??//?調用高通操作nv的api,讀取NV給tmp??
  • ????for(int?m=0;m?<?sizeof(tmp)-3;m++)?{??//?去掉tmp的前三個字段,重新賦值給after??
  • ????????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);??//?char轉化為jstring??
  • ????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数据的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。