问题描述
我正在尝试将以下反射转换为 Kotlin。下面使用反射来调用 RFCOMMs 函数,因此它可以将端口/通道作为输入而不是 UUID。我的所有程序都在 Kotlin 中。有人知道如何在 Kotlin 中编写此代码吗?
int bt_port_to_connect = 5;
BluetoothDevice device = mDevice;
BluetoothSocket deviceSocket = null;
...
// IMPORTANT: we create a reference to the 'createInsecureRfcommSocket' method
// and not(!) to the 'createInsecureRfcommSocketToServiceRecord' (which is what the
// android SDK documentation publishes
Method m = device.getClass().getMethod("createInsecureRfcommSocket",new Class[] {int.class});
deviceSocket = (BluetoothSocket) m.invoke(device,bt_port_to_connect);
更新推荐:
class BluetoothClient(device: BluetoothDevice): Thread() {
// https://stackoverflow.com/questions/9703779/connecting-to-a-specific-bluetooth-port-on-a-bluetooth-device-using-android
// Need to reflection - create RFCOMM socket to a port number instead of UUID
// Invoke btdevice as 1st parameter and then the port number
var bt_port_to_connect = 5
var deviceSocket: BluetoothSocket? = null
private val socket = device.createInsecureRfcommSocketToServiceRecord(uuid)
val m = device::class.declaredFunctions.single { it.name == "createInsecureRfcommSocket" }
m.call(device,bt_port_to_connect)
override fun run() {
try {
Log.i("client","Connecting")
this.socket.connect()
Log.i("client","Sending")
val outputStream = this.socket.outputStream
val inputStream = this.socket.inputStream
try {
outputStream.write(message.toByteArray())
outputStream.flush()
Log.i("client","Sent")
} catch(e: Exception) {
Log.e("client","Cannot send",e)
} finally {
outputStream.close()
inputStream.close()
this.socket.close()
}
}
catch (e: IOException) {
println("Socket Failed")
}
}
}
解决方法
您真的可以使用完全相同的代码,只需将其转换为 Kotlin:
val m = device::class.java.getMethod("createInsecureRfcommSocket",Int::class.java)
m.invoke(device,bt_port_to_connect)
或者你可以使用 Kotlin 反射:
val m = device::class.declaredFunctions.single { it.name == "createInsecureRfcommSocket" }
m.call(device,bt_port_to_connect)
我不知道是否有更好的方法可以找到具有提供名称的函数。您可以创建一个扩展函数以使其更清晰。如果此函数具有覆盖,您可能还需要检查参数。