从 JNI/C++ 获取 Android 蓝牙适配器名称
Getting Android Bluetooth Adapter Name from JNI/C++
问题中的 Android API 是 android.bluetooth.BluetoothAdapter,它有一个成员函数 getName()
,returns 适配器的用户友好名称。
在 java 中:BluetoothAdapter.getDefaultAdapter().getName()
我知道我可以将它包装在一个 java 函数中,我通过 jni
调用它,但是,我怎样才能在 C++
中实现相同的功能,只有 jni/android-ndk?
首先,您需要有读取此值的权限(无论它是本机的,您都需要)。
添加到AndroidManifest.xml
:
<uses-permission android:name="android.permission.BLUETOOTH"/>
在本土jni
-land,事情有点麻烦。简而言之,这就是您所需要的:
- 获取class
android.bluetooth.BluetoothAdapter
- 获取静态方法
BluetoothAdapter.getDefaultAdapter()
- 获取方法
BluetoothAdapter.getName()
为了:
- 在
1
上调用 2
以获得默认的 BluetoothAdapter
实例
- 在
4.
的实例上调用 getName()
以获取适配器的名称。
这与 java 单线相同,只是分解了。
代码(假设你已经有一个JNIEnv
对象):
// 1. Get class
// The path matches the package hierarchy of
// 'android.bluetooth.BluetoothAdapter'
jclass classBta = env->FindClass("android/bluetooth/BluetoothAdapter");
// 2. Get id of the static method, getDefaultAdapter()
// Search the web for 'jni function signature' to understand
// the third argument. In short it's a function that takes no arguments,
// hence '()', and returns an object of type
// android.bluetooth.BluetoothAdapter, which uses syntax "L{path};"
jmethodID methodIdGetAdapter =
env->GetStaticMethodID(classBta,
"getDefaultAdapter",
"()Landroid/bluetooth/BluetoothAdapter;");
// 3. Get id of the non-static method, getName()
// The third argument is the getName function signature,
// no arguments, and returns a java.lang.String object.
jmethodID methodIdGetName =
env->GetMethodID(classBta,
"getName",
"()Ljava/lang/String;");
// 4. We get the instance returned by getDefaultAdapter()
jobject objBta = (jobject)
env->CallStaticObjectMethod(classBta, methodIdGetAdapter);
// 5. Call member method getName on instance
jstring strName = (jstring)
env->CallObjectMethod(objBta, methodIdGetName);
// Convert jstring to a regular string
const char *result = env->GetStringUTFChars(strName, 0);
std::string blueToothName(result);
为了清楚起见,我省略了合理的检查以查看各种功能是否成功,以及清理:
env->DeleteLocalRef(classBta);
env->DeleteLocalRef(objBta);
env->DeleteLocalRef(strName);
env->ReleaseStringUTFChars(strName, result);
问题中的 Android API 是 android.bluetooth.BluetoothAdapter,它有一个成员函数 getName()
,returns 适配器的用户友好名称。
在 java 中:BluetoothAdapter.getDefaultAdapter().getName()
我知道我可以将它包装在一个 java 函数中,我通过 jni
调用它,但是,我怎样才能在 C++
中实现相同的功能,只有 jni/android-ndk?
首先,您需要有读取此值的权限(无论它是本机的,您都需要)。
添加到AndroidManifest.xml
:
<uses-permission android:name="android.permission.BLUETOOTH"/>
在本土jni
-land,事情有点麻烦。简而言之,这就是您所需要的:
- 获取class
android.bluetooth.BluetoothAdapter
- 获取静态方法
BluetoothAdapter.getDefaultAdapter()
- 获取方法
BluetoothAdapter.getName()
为了:
- 在
1
上调用2
以获得默认的BluetoothAdapter
实例 - 在
4.
的实例上调用getName()
以获取适配器的名称。
这与 java 单线相同,只是分解了。
代码(假设你已经有一个JNIEnv
对象):
// 1. Get class
// The path matches the package hierarchy of
// 'android.bluetooth.BluetoothAdapter'
jclass classBta = env->FindClass("android/bluetooth/BluetoothAdapter");
// 2. Get id of the static method, getDefaultAdapter()
// Search the web for 'jni function signature' to understand
// the third argument. In short it's a function that takes no arguments,
// hence '()', and returns an object of type
// android.bluetooth.BluetoothAdapter, which uses syntax "L{path};"
jmethodID methodIdGetAdapter =
env->GetStaticMethodID(classBta,
"getDefaultAdapter",
"()Landroid/bluetooth/BluetoothAdapter;");
// 3. Get id of the non-static method, getName()
// The third argument is the getName function signature,
// no arguments, and returns a java.lang.String object.
jmethodID methodIdGetName =
env->GetMethodID(classBta,
"getName",
"()Ljava/lang/String;");
// 4. We get the instance returned by getDefaultAdapter()
jobject objBta = (jobject)
env->CallStaticObjectMethod(classBta, methodIdGetAdapter);
// 5. Call member method getName on instance
jstring strName = (jstring)
env->CallObjectMethod(objBta, methodIdGetName);
// Convert jstring to a regular string
const char *result = env->GetStringUTFChars(strName, 0);
std::string blueToothName(result);
为了清楚起见,我省略了合理的检查以查看各种功能是否成功,以及清理:
env->DeleteLocalRef(classBta);
env->DeleteLocalRef(objBta);
env->DeleteLocalRef(strName);
env->ReleaseStringUTFChars(strName, result);