问题描述
我在 Android 中工作,正在编写一些 JNI 代码,并且正在寻找一种从设备查询移动设备标识符 (MEID) 的方法.
I'm working in Android, writing some JNI code, and I'm looking for a way to query the Mobile Equipment Identifier (MEID) from the device.
http://en.wikipedia.org/wiki/Mobile_equipment_identifier
我正在尝试编写可以在 Android 设备上自行运行的 C 或 C++ 代码,所以我认为我不能使用 Java(即,从 TelephonyManager
获取 MEID).
I'm trying to write C or C++ code that can run by itself on an Android device, so I don't think I can use Java (i.e., get MEID from TelephonyManager
).
搜索 StackOverflow 发现:是否有 android shell 或 adb 命令可用于获取设备的 IMEI/MEID?
A search of StackOverflow finds: Is there an android shell or adb command that I could use to get a device's IMEI/MEID?
好的,dumpsys iphonesubinfo
可以得到我需要的信息.它有效!
Okay great, dumpsys iphonesubinfo
can get the info I need. And it works!
我找不到 dumpsys
的源代码,除非它是 Android 源代码的一部分.所以我下载了那个......我的硬盘在下载完成之前就已经装满了,但我确实得到了dumpsys
的源代码.这是一个非常短的 C++ 文件.它所做的只是查询 Android 的 IBinder
接口.
I couldn't find the source for dumpsys
except as part of the source for Android. So I downloaded that... my hard disk filled up before the download finished, but I did get the source code to dumpsys
. It is a surprisingly short C++ file. All it does is query Android's IBinder
interface.
所以,我的问题:
0) 有什么方法可以仅使用 NDK 中的内容编写针对 IBinder
的查询?dumpsys.cpp
使用的include文件不在NDK中,NDK目录下的grep
在任何include文件中都没有找到IBinder
或代码示例,所以我的猜测是否"(但我想错了).
0) Is there any way I can write a query against IBinder
using just the stuff in the NDK? The include files used by dumpsys.cpp
are not in the NDK, and grep
in the NDK directory didn't find IBinder
in any include files or code samples, so my guess is "no" (but I would like to be wrong).
1) 还有其他获取 MEID 的好方法吗?
1) Is there any other good way to get the MEID?
我在认真考虑我应该只使用 system("dumpsys iphonesubinfo >/tmp/myprogname_dumpsys.tmp"
然后打开生成的文件并解析它.应该可以,但我会很难称之为优雅...而且我不确定 dumpsys
是否在每个 Android 设备上都可用.
I'm seriously thinking I should just use system("dumpsys iphonesubinfo > /tmp/myprogname_dumpsys.tmp"
and then open the resulting file and parse it. That should work, but I would hardly call it elegant... and I'm not sure if dumpsys
is available on every Android device or not.
使用 system()
来运行 dumpsys
的想法是行不通的,因为 dumpsys
需要 android.permission.DUMP
和 Android 不再允许非系统应用拥有该权限.
The idea of using system()
to run dumpsys
will not work, because dumpsys
needs android.permission.DUMP
and Android no longer allows non-system apps to have that permission.
推荐答案
我相信 Dalvik 实现了与 JVM 相同的所有 JNI 接口,所以虽然有点繁琐,但完全可以通过 JNI 从本地代码调用任意 Java 类和方法.
I believe Dalvik implements all the same JNI interfaces that the JVM does, so while it's a bit fiddly, it's perfectly possible to make calls from native code through JNI to arbitrary Java classes and methods.
/* 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 */
这篇关于Android -- 从 JNI 获取 MEID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!