我正在使用Android,正在编写一些JNI代码,并且正在寻找一种从设备查询移动设备标识符(MEID)的方法。
http://en.wikipedia.org/wiki/Mobile_equipment_identifier
我正在尝试编写可以在Android设备上自行运行的C或C++代码,因此我认为我不能使用Java(即从TelephonyManager
获取MEID)。
搜索StackOverflow发现:Is there an android shell or adb command that I could use to get a device's IMEI/MEID?
好的,dumpsys iphonesubinfo
可以获取我需要的信息。而且有效!
除了作为Android来源的一部分外,我找不到dumpsys
的来源。因此,我下载了该文件...在完成下载之前,硬盘已装满,但是我确实将源代码获取到dumpsys
。这是一个非常短的C++文件。它所做的只是查询Android的IBinder
接口(interface)。
所以,我的问题是:
0)有什么方法可以仅使用NDK中的内容针对IBinder
编写查询? dumpsys.cpp
使用的包含文件不在NDK中,而NDK目录中的grep
在任何包含文件或代码示例中均未找到IBinder
,因此我的猜测是“否”(但我想错了)。
1)还有其他获取MEID的好方法吗?
我很认真地认为我应该只使用system("dumpsys iphonesubinfo > /tmp/myprogname_dumpsys.tmp"
,然后打开生成的文件并进行解析。那应该可以,但是我很难称它为优雅……而且我不确定dumpsys
是否在每个Android设备上都可用。
编辑:使用system()
运行dumpsys
的想法将行不通,因为dumpsys
需要android.permission.DUMP
,而Android不再允许非系统应用程序具有该权限。
Dumpsys permission denial in java
最佳答案
我相信Dalvik可以实现与JVM相同的所有JNI接口(interface),因此虽然有点怪异,但完全有可能通过JNI从本机代码对任意Java类和方法进行调用。
/* assuming you already have */
JNIEnv *env;
jobject context;
/* then call (with error-checking) */
jclass cls = (*env)->FindClass(env, "android/context/Context");
jmethodId mid = (*env)->GetMethodID(env, context_cls, "getSystemService",
"(Ljava/lang/String;)Ljava/lang/Object;");
jfieldID fid = (*env)->GetStaticFieldID(env, cls, "TELEPHONY_SERVICE",
"Ljava/lang/String;");
jstring str = (*env)->GetStaticObjectField(env, cls, fid);
jobject telephony = (*env)->CallObjectMethod(env, context, mid, str);
cls = (*env)->FindClass(env, "android/telephony/TelephonyManager");
mid =(*env)->GetMethodID(env, cls, "getDeviceId", "()Ljava/lang/String;");
str = (*env)->CallObjectMethod(env, telephony, mid);
jsize len = (*env)->GetStringUTFLength(env, str);
char* deviceId = calloc(len + 1, 1);
(*env)->GetStringUTFRegion(env, str, 0, len, deviceId);
(*env)->DeleteLocalRef(env, str);
/* to get a string in deviceId */