[fixed] Problems to pass byte arrays via JNDI for Bluetooth on Android
-
wrote on 19 Apr 2014, 21:27 last edited by
Hi,
I am trying to use an RFCOMM socket in a Qt Application for Android mobiles. Since the Bluetooth stuff is (not yet) implemented in Qt and Android provides only a Java interface, I have to use JNI. Please correct me if that's incorrect.First, I wrote some quick and dirty lines of Java code to evaluate the Java API, and it works fine.
@
BluetoothSocket socket=device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
socket.connect();
InputStream istream=socket.getInputStream();
OutputStream ostream=socket.getOutputStream();
ostream.write("oPA3,0\n".getBytes());
ostream.flush();
Thread.sleep(1000);
int avail=istream.available();
Log.w(this.getClass().getSimpleName(),"Received "+avail+" bytes");BufferedReader br = new BufferedReader(new InputStreamReader(istream)); String s=br.readLine(); Log.w(this.getClass().getSimpleName(),"Received: "+s); } }
@
Now I want to do the same in my Qt (c++) program. I can open the RFCOMM connection, and I can get the nput stream and output stream objects. But the remote device does not receive the command "oPA3,0" and the program does not receive the expected answer (3 bytes = "Ok\n").
@
qWarning("Opening RFCOMM connection");
QAndroidJniObject string = QAndroidJniObject::fromString("00001101-0000-1000-8000-00805F9B34FB");
if (!string.isValid()) qFatal("Cannot create String");
QAndroidJniObject uuid=QAndroidJniObject::callStaticObjectMethod("java/util/UUID","fromString","(Ljava/lang/String;)Ljava/util/UUID;",string.object<jstring>());
if (!uuid.isValid()) qFatal("Cannot create UUID");
QAndroidJniObject socket=testDevice->callObjectMethod("createRfcommSocketToServiceRecord","(Ljava/util/UUID;)Landroid/bluetooth/BluetoothSocket;",uuid.object<jobject>());
if (!socket.isValid()) qFatal("Cannot create RFCOMM socket");
socket.callMethod<void>("connect");
jboolean connected=socket.callMethod<jboolean>("isConnected");
if (!connected) qFatal("Cannot open RFCOMM connection");
qWarning("Connection established");
QAndroidJniObject istream=socket.callObjectMethod("getInputStream","()Ljava/io/InputStream;");
if (!istream.isValid()) qFatal("Cannot open input stream");
QAndroidJniObject ostream=socket.callObjectMethod("getOutputStream","()Ljava/io/OutputStream;");
if (!ostream.isValid()) qFatal("Cannot open output stream");qWarning("Sending test data"); QAndroidJniEnvironment env; char data[100]; strcpy(data,"oPA3,0\n"); jbyteArray buffer=env->NewByteArray(100); env->SetByteArrayRegion(buffer,0,strlen(data),(jbyte*)data); ostream.callMethod<void>("write","([BII)",buffer,0,strlen(data)); ostream.callMethod<void>("flush"); QThread::msleep(1000); jint read=istream.callMethod<jint>("available"); qWarning("Received %i bytes",read); }
@
I think my probloem is that I have no idea how to pass the command string to Java and how to pass the response back to C++. Does anybody here know how to do that? Or maybe there is somewhere and example that I could look at?
-
wrote on 20 Apr 2014, 08:09 last edited by
I also tried sending single bytes instead of byte arrays, but again the bluetooth device did not receive a single character.
At least sending byte arrays should work, because it's described here: http://codeforfun.wordpress.com/2010/04/22/sharing-output-streams-through-a-jni-interface/
Any ideas?
-
wrote on 20 Apr 2014, 20:22 last edited by
I found the problen cause: I needed to add some few type castings to ostream.callMethod and add the return type "V" to the method signature.
So I was able to finish my class which I now use to communicate with serial bluetooth devices (RFCOMM protocol, SPP profile).
If you are interested in the full source, checkout http://stefanfrings.de/android_qt/index-en.html
1/3