蓝牙与 Android 上的 Qt。通过抽象类上的jni调用java类
Posted
技术标签:
【中文标题】蓝牙与 Android 上的 Qt。通过抽象类上的jni调用java类【英文标题】:Bluetooth with Qt on Android. Calling java classes through jni on abstract class 【发布时间】:2014-01-02 02:10:40 【问题描述】:here 可能重复,但接受的答案很短,没有多大帮助。
我正在使用适用于 android 的 Qt 5.2。我想使用 Qt 框架目前不直接支持的我的 android 设备蓝牙功能。因此我开始使用 JNI 来访问 Android Java 类和方法。
我可以通过这样做来创建 AudioTimestamp 类的对象:
QAndroidJniObject audioTimestamp2("android/media/AudioTimestamp");
if(!audioTimestamp2.isValid())
qDebug() << "audioTimestamp2 is not a valid object";
return false;
第一行调用了默认构造函数,所以它工作正常。这只是一个测试,看看我是否能够创建一个有效的对象。
当我从 developer.android.com 开始使用蓝牙实现时,我需要通过以下方式获取设备的蓝牙适配器:
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
所以我尝试这样做:
//Create Java string used to obtain bluetooth adapter.
QAndroidJniObject systemService = QAndroidJniObject::fromString("BLUETOOTH_SERVICE");
//Create Context Object.
QAndroidJniObject context("android/content/Context");
if(!context.isValid())
qDebug() << "context is not a valid object";
return false;
//Call getSystemService method on context object and return manager object.
QAndroidJniObject bluetoothManager = context.callObjectMethod("getSystemService", "(Ljava/lang/String;)Landroid/bluetooth/BluetoothManager;", systemService.object<jstring>());
if(!bluetoothManager.isValid())
qDebug() << "bluetoothManager is not a valid object";
return false;
//Call getAdapter() on manager.
QAndroidJniObject bluetoothAdapter = bluetoothManager.callObjectMethod("getAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
//More code
if (!bluetoothAdapter.callMethod<jboolean>("isEnabled"))
qDebug() << "Bluetooth is off";
//Code to ask user to turn bluetooth on here...
我很快发现“getSystemService(Context.BLUETOOTH_SERVICE)”似乎是突然被调用的。它属于抽象类Context.java。如何在抽象类上使用 Qt JNI 调用来获取 bluetoothManager?
编辑:
我也试过这样做:
QAndroidJniObject context("android/app/Service");
但仍然得到:
D/Qt (22736): ..\AndroidTest\bluetooth.cpp:33 (bool Bluetooth::start()): context is not a valid object
【问题讨论】:
看起来像是要报告的错误? @LaszloPapp:不确定是不是。我怀疑您必须在 Java 程序中调用这种代码才能获得正确的上下文?这是在我在问题顶部提供的链接中完成的。我认为您可以使用 registerNatives() 方法将上下文从 Java 发送到 C++。我更倾向于认为这是缺乏功能而不是错误。 【参考方案1】:getSystemService() 是android.content.Context 的一个方法。我认为您会得到“上下文不是有效对象”,因为它是一个无法以这种方式实例化的抽象类。 android.app.Service 也是如此。
“发现“getSystemService(Context.BLUETOOTH_SERVICE)”似乎被突然调用了” - 在您来自 developer.android.com 的示例中,它是在 this 上调用的,这可能是从 Activity 派生的类,因此是 Context。
您需要一个上下文对象来调用 getSystemService()。
此外,您似乎正在调用具有错误签名的对象方法:“(Ljava/lang/String;)Ljava/lang/Object;”
【讨论】:
是的,我需要一个上下文对象才能调用 getSystemService(),但那是行不通的。我通过编写一些可调用的 java 代码暂时解决了这个问题。【参考方案2】:仅对于可能最终在这里的其他人,您可以使用
获取主要上下文QtAndroid::androidActivity()
这就是你在你的情况下使用它的方式:
// from https://developer.android.com/reference/android/content/Context.html#BLUETOOTH_SERVICE
// note that the actual string value is "bluetooth" not "BLUETOOTH_SERVICE", Context.BLUETOOTH_SERVICE is a constant that holds "bluetooth" string value
QAndroidJniObject service_name = QAndroidJniObject::fromString("bluetooth");
// this is your context
QAndroidJniObject activity = QtAndroid::androidActivity();
// now you get your bluetooth manager
QAndroidJniObject bluetoothManager = activity.callObjectMethod("getSystemService","(Ljava/lang/String;)Ljava/lang/Object;", service_name.object<jstring>());
【讨论】:
以上是关于蓝牙与 Android 上的 Qt。通过抽象类上的jni调用java类的主要内容,如果未能解决你的问题,请参考以下文章
抽象类上的 Json.reads(不支持密封特征:没有已知的子类)
通过蓝牙将 Android 应用程序连接到 Mac OS X 上的 Python 脚本
如何将 Android 应用程序正确连接到支持蓝牙的 Arduino 微控制器上的 RFCOMM 插座?