Using QBluetooth for Rfcomm / SPP communication on Android device
-
Hello,
I'm trying to use the Qt 5.3 beta to create a connection between a device and my Android phone using a Serial port over bluetooth.
in DlgMain.h:
@
QBluetoothDeviceDiscoveryAgent *m_BT_DiscoveryAgent;
QBluetoothServiceDiscoveryAgent *m_BT_ServiceDiscoveryAgent;
QBluetoothLocalDevice *m_BT_LocalDevice;
QBluetoothSocket *m_BT_socket;
QList <QBluetoothDeviceInfo> m_BT_FoundDevices;
QList<QBluetoothHostInfo> m_localAdapters;
@in DlgMain .cpp
@
static const QLatin1String serviceUuid("00001101-0000-1000-8000-00805F9B34FB");void DlgMain::SetupBT()
{
m_localAdapters = QBluetoothLocalDevice::allDevices();
QBluetoothHostInfo hi;
foreach(hi , m_localAdapters)
{
qDebug()<<"m_localAdapters name:"<<hi.name()<<"adress"<<hi.address().toString();
}// on my phone only 1 BT device
if (m_localAdapters.count() > 0)
{
m_BT_DiscoveryAgent = new QBluetoothDeviceDiscoveryAgent(m_localAdapters.at(0).address(),this);
m_BT_LocalDevice = new QBluetoothLocalDevice(m_localAdapters.at(0).address(),this);
m_BT_ServiceDiscoveryAgent = new QBluetoothServiceDiscoveryAgent(m_localAdapters.at(0).address(),this);
}
else
{
qDebug()<<"ERROR NO ADAPTER !!!! ";
}QList <QBluetoothUuid> uuidfilter; m_BT_ServiceDiscoveryAgent->setUuidFilter(QBluetoothUuid(serviceUuid)); m_BT_socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol,this); connect(m_BT_DiscoveryAgent, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)),this, SLOT(slot_BTdeviceDiscovered(QBluetoothDeviceInfo))); connect(m_BT_ServiceDiscoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)),this, SLOT(slot_BTserviceDiscovered(QBluetoothServiceInfo))); connect(m_BT_ServiceDiscoveryAgent, SIGNAL(finished()),this, SLOT(slot_BTserviceDiscoverFinished())); connect(m_BT_DiscoveryAgent, SIGNAL(finished()),this, SLOT(slot_BTdeviceDiscoverFinished())); connect(m_BT_socket, SIGNAL(error(QBluetoothSocket::SocketError error)),this, SLOT(slot_BTsocketError(QBluetoothSocket::SocketError error))); connect(m_BT_socket, SIGNAL(connected()),this, SLOT(slot_BTsocketConnected())); connect(m_BT_socket, SIGNAL(disconnected()),this, SLOT(slot_BTsocketDisconnected())); connect(m_BT_LocalDevice, SIGNAL(pairingFinished(QBluetoothAddress,QBluetoothLocalDevice::Pairing)) , this, SLOT(slot_pairingDone(QBluetoothAddress,QBluetoothLocalDevice::Pairing)));
}
void DlgMain::slot_clicked_ScanBT()
{
m_BT_LocalDevice->setHostMode(QBluetoothLocalDevice::HostDiscoverable);
m_BT_DiscoveryAgent->start();
m_BT_ServiceDiscoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
ui->m_Ctrl_ComboBox_foundDevices->clear();
}void DlgMain::slot_BTdeviceDiscovered(const QBluetoothDeviceInfo &device)
{
int Completeness = -1;qDebug() << "Found new device:" << device.name() << '(' << device.address().toString() << ')'<<"services: "<<device.serviceUuids(( QBluetoothDeviceInfo::DataCompleteness*)
&Completeness);
qDebug() << "Completeness"<<Completeness; ui->m_Ctrl_ComboBox_foundDevices->addItem(device.name()); m_BT_FoundDevices.append(device);
}
void DlgMain::slot_BTdeviceDiscoverFinished()
{
qDebug() << "Finished !";
}void DlgMain::slot_BTserviceDiscovered(const QBluetoothServiceInfo &service)
{
qDebug() << " Found new service:" << service.serviceName()<<"device:"<<service.device().name();
}void DlgMain::slot_BTserviceDiscoverFinished()
{
qDebug() << "slot_BTserviceDiscoverFinished";
}void DlgMain::slot_BTsocketConnected()
{
qDebug() << "slot_BTsocketConnected ";
connect(m_BT_socket, SIGNAL(readyRead()), this, SLOT(slot_BTreadSocket()));
}void DlgMain::slot_BTsocketDisconnected()
{
qDebug() << "slot_BTsocketDisconnected !!!";
}void DlgMain::slot_BTsocketStateChanged(QBluetoothSocket::SocketState state)
{
qDebug() << "slot_BTsocketStateChanged !!"<<state;
}void DlgMain::slot_BTreadSocket()
{
qDebug() << " slot_BTreadSocket available:"<<m_BT_socket->bytesAvailable();
QByteArray data = m_BT_socket->read(m_BT_socket->bytesAvailable());
qDebug() << "read gave :"<<data;
}void DlgMain::slot_clicked_ConnectBT()
{
int nIndex = ui->m_Ctrl_ComboBox_foundDevices->currentIndex();if (nIndex != -1) { if (nIndex < m_BT_FoundDevices.count() && m_BT_FoundDevices.count() > 0) { m_BT_LocalDevice->requestPairing(m_BT_FoundDevices.at(nIndex).address(),QBluetoothLocalDevice::Paired); } }
}
void DlgMain::slot_pairingDone(QBluetoothAddress address,QBluetoothLocalDevice::Pairing pairing)
{
qDebug()<<"pairing done:";
m_BT_socket->connectToService(address,QBluetoothUuid(serviceUuid));
}
@Here is my console output :
void DlgMain::slot_BTdeviceDiscovered(const QBluetoothDeviceInfo&)): Found new device: "MyDevice" ( "00:A0:96:18:45:3B" ) services: ()
Completeness 2=> so my device is well discovered but no service available ; and DataIncomplete
...and when I try to pair... it asks a Pin code (no pin on my embedded device...so "0000" to try...)then the console shows :
(virtual void LocalDeviceBroadcastReceiver::onReceive(JNIEnv*, jobject, jobject)): qt.bluetooth.android: Unknown pairing variant: 0
kernel\qobject.cpp:2247 (void err_method_notfound(const QObject*, const char*, const char*)): QObject::connect: No such signal InputStreamThread::error()and then (void DlgMain::slot_BTsocketConnected()): slot_BTsocketConnected
but nothing comes throught data reception...
What is wrong with my set up ?
To connect :- Should I request a pairing then once paired use the connectTo with my socket
or - Only connectTo (similar problem)
Hope somebody can help, regards,
Paul - Should I request a pairing then once paired use the connectTo with my socket
-
Pairing means that both devices exchange passwords and key to establish a connection. The discovering and pairing process is done by the operating system (like in Windows and Linux). Once the devices are paired, they can connect to each other. The pairing data are stored by the operating system.
So next time when you want to open a connection, you don't need to discover and you also dont need to pair them again.
To keep it simple, I dont initiate the pairing in my Qt applications. I simply tell the users that they shall do that outside my application using the android settings. My Windows and Linux applications are also simplified in the same way.
The benefit is: Discovering and Pairing fails often. If that happens within my applications, then the users expect help from me. When I tell them to pair with operating system features, then the users understand that this part is not under control of my application, so they don't aks me (the application developer) for help. Instead they go to the PC tech support - and these guys are the right people to help with the OS or hardware.
My application does the following:
1) Check if bluetooth is enabled.
2) Get a list of all paired (aka bounded) devices.
3) Iterate though the list to find the target device by its name or address (or ask the user).
4) Connect to the device
5) Open streams for input and output.I did not checkout the Qt bluetooth classes, I wait for the final release of Qt 5.3. In the meantime, I use my own JNI wrapper to call the Android Bluetooth API directly.
It's straight forward. I think it might help to read the API documentation of Google and compare with the following simple Java example:
@
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
...
try {
BluetoothAdapter adapter=BluetoothAdapter.getDefaultAdapter();
// search target device in list of paired devices
Set<BluetoothDevice> pairedDevices=adapter.getBondedDevices();
Iterator<BluetoothDevice> iterator=pairedDevices.iterator();
while (iterator.hasNext()) {
BluetoothDevice device=iterator.next();
Log.w(this.getClass().getSimpleName(),"Found "+device.getAddress()+" = "+device.getName());
if (device.getName().equals("HC-06")) {// connect BluetoothSocket socket=device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); socket.connect(); InputStream istream=socket.getInputStream(); OutputStream ostream=socket.getOutputStream(); // send ostream.write("whatever\n".getBytes()); // receive 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); } } } catch(Exception e) { e.printStackTrace(); } }
...
}
@http://developer.android.com/guide/topics/connectivity/bluetooth.html
Maybe you prefer my simple wrapper class on http://stefanfrings.de/android_qt/index.html
my device is well discovered but no service available
AFAIK Android does not support querying the services offered by a device. You just need to try to connect. -
Hello !!!
i am try connect my device using qserialport to android phone,
whitout success...and i want to try using bluetooth, any member have sucess to connet bluetooth under android phone over serial port ????
possible send me a code ???
thanks.....
-
Qt does not support serial ports on Android.
This question repeats every week. -
sorry...but my question is
any members have sucess to connect
android phone whit device over
BLUETOOTH in serial mode.
or using
qbluetoothserialport???? -
I'm pretts sure that the author of the library had success.
Are you aware that some Tablets/Phones do not support the SPP profile at all? For example the Acer Iconia B1 of my daughter. I wasted lots of hours trying to get it working until I found that information in a discussion Forum.
So it might be a good idea to try another phone/tablet or compare with another application that is known to run fine. For example https://play.google.com/store/apps/details?id=mobi.dzs.android.BluetoothSPP&hl=de.
(It will prompt you to upgrade to a newer "pro" version, which did not work my phones. Better use the older one). -
Hi s.frings74
i testing. thanks for this, but you have a code example to use this or a link ???
..
-
SImply install the examples package with Qt. There are some for bluetooth.
stefan@stefanspc:/opt/qt/Examples/Qt-5.3/bluetooth$ ls
btfiletransfer
picturetransfer
scanner
btchat
btscanner
pingpong -
Its ok, i testing and work wonderfull, but dont,have serial comunication model !!!!
thanks