I am developing a Bluetooth application for my MSc. End Project. It includes a server implemented in JAVA ME
, and a client written in Android
.
The problem is that Android SDP
seems to fail at recognizing the ServiceRecord
of my JAVA ME server.
If I use the methods BluetoothDevice.getUuids()
and BluetoothDevice.fetchUuidsWithSdp()
in my client, they return a set of UUIDs
, but my service's UUID
is nowhere among them, thus I cannot connect to it.
This is the code for JAVAME
server example:
/*IMPORTS*/
public class StackOverFlowServer extends MIDlet {
Display mDisplay;
Form mForm;
LocalDevice local;
StreamConnectionNotifier server;
ServiceRecord sr;
String conURL;
StreamConnection conn;
public StackOverFlowServer() {
mDisplay = Display.getDisplay(this);
mDisplay.setCurrent(mForm);
mForm = new Form(null);
conURL = "btspp://localhost:68EE141812D211D78EED00B0D03D76EC;"
+ "authenticate=false;encrypt=false;name=MySampleApp";
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
// TODO Auto-generated method stub
}
protected void pauseApp() {
// TODO Auto-generated method stub
}
protected void startApp() throws MIDletStateChangeException {
try {
local = LocalDevice.getLocalDevice();
} catch (BluetoothStateException e) {
// Error handling code here
}
/*
* When creating a StreamConnectionNotifier a service record
* will automatically be created for us, describing the new
* service. The service will have the Serial Port (0x1101)
* value in the ServiceClassIDList (id 0x0001) attribute. The
* service record will also have both the L2CAP (0x0100) and
* RFCOMM (0x0003) values in the ProtocolDescriptorList (id
* 0x0004) attribute. Other mandatory attributes will be set
* automatically by the JABWT implementation. The optional
* ServiceName (id 0x100) attribute will be set to the name
* parameter, "BTDemoApp" in this case.
*/
try {
server = (StreamConnectionNotifier)
Connector.open(conURL);
} catch (IOException e1) {
// Error handling code here
}
/*
* The automatically created service record can be obtained
* from the LocalDevice object, using the reference to the
* StreamConnectionNotifier.
*/
try {
sr = local.getRecord(server);
}
catch (IllegalArgumentException iae){
// Error handling code here
}
/*
* We create a new DataElement and set its content correctly.
*/
DataElement elm = null;
/*
* Setting public browse root in the browsegrouplist
* attribute. The BrowseGroupList (id 0x0005) attribute
* contains a DataElement sequence, which in turn contains
* DataElements with UUIDs. The DataElement sequence must be
* created before we can add DataElements to it.
*/
elm = new DataElement(DataElement.DATSEQ);
elm.addElement(new DataElement(
DataElement.UUID,new UUID(0x1002)));
/*
* The DataElement is now prepared. It must be added to the
* appropriate attribute ID, in this case the
* BrowseGroupList.
*/
sr.setAttributeValue(0x0005,elm);
/*
* Finally, the service record must be updated in our
* LocalDevice.
*/
try {
local.updateRecord(sr);
} catch (ServiceRegistrationException e3) {
// Error handling code here
}
try {
conn = server.acceptAndOpen();
} catch (ServiceRegistrationException sre){
// Error handling code here
} catch (IOException e2) {
// Error handling code here
}
/*
* At this point a client is connected. input and output
* streams can be obtained from the conn object,
* communication can begin.
*/
}
}
And this is part of the Android client:
package com.exampleproyect.stackoverflowclient;
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.os.Parcelable;
public class StackOverFlowClientActivity extends Activity {
BluetoothAdapter mBluetoothAdapter;
BluetoothDevice C702;
BroadcastReceiver mReceiver;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
C702 = mBluetoothAdapter.getRemoteDevice("00:23:F1:27:16:DA");
C702.fetchUuidsWithSdp();
mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_UUID.equals(action)){
Parcelable[] uuidExtra = intent.getParcelableArrayExtra("android.bluetooth.device.extra.UUID");
/*uuidExtra should contain my service's UUID among his files, but it doesn't!!*/
}
}
};
// Register the BroadcastReceiver
IntentFilter filter1 = new IntentFilter(BluetoothDevice.ACTION_UUID);
registerReceiver(mReceiver, filter1); // Don't forget to unregister during onDestroy
}
}
What bothers me the most, is that my computer can see my JAVAME
server correctly advertised:

What am I doing wrong?? :( Why can my PC's Bluetooth see my service correctly advertised in JAVAME
but Android can't?? Can Android
connect via Bluetooth to JAVAME
servers?
I have read tons of other similar questions here in StackOverFlow but I have not been able to come up with a working solution. :(
I'm using a Sony Ericsson C702 (Java Platform 8) as testing server. And a Samsung Galaxy S (ICS 4.0.3, Team ICSSGS RC4.2)
EDIT1
OK.
I know what the problem is.
I want the JAVAME server to advertise my service with UUID (for example): "68EE1418-12D2-11D7-8EED-00B0D03D76EC", but it seems that the code:
conURL = "btspp://localhost:68EE141812D211D78EED00B0D03D76EC;"
+ "authenticate=false;encrypt=false;name=MySampleApp";
server = (StreamConnectionNotifier)
Connector.open(conURL);
Adds the default serial port service UUID "00001101-0000-1000-8000-00805F9B34FB" as a ServiceClassIDList atribute:

Now, the funny thing is that the Android method BluetoothDevice.fetchUuidsWithSdp(); seems to fetch the default "00001101-0000-1000-8000-00805F9B34FB" UUID, instead of my "68EE1418-12D2-11D7-8EED-00B0D03D76EC" UUID, overlaping my service with the default Serial Port Service of the mobile phone.
Something similar Medieval Bluetooth Network Scanner, it recognizes my service, but advertised as "00001101-0000-1000-8000-00805F9B34FB":

What could I do to remove that extra UUID
that JAVAME
automatically adds to my service?
Please help, thanks!
EDIT2
OK, the issue comes with the Sony Ericsson phones. Apparently they insert standard serial port UUID {0x1101}
ahead of my custom UUID
, while Samsung and Nokia phones, for example, insert this standard UUID
behind my own on the service record. Android seems to fetch only the first value of attribute 0x001
on the service record, thus, confuses my service with the default serial port that comes with some devices.
So the solution will be:
Is there any way with current Android API to fetch more servicerecord
attributes apart from ServiceClassID (0x001)
?
or
IS there any way to update the servicerecord
stored on the Service Discovery Database (SDDB) after "acceptAndOpen" -JAVAME- has been called? -I have used LocalDevice.updateRecord
after service has been created on the SDDB
, it works on the emulator, but gives an exception and does nothing on actual devices.
来源:https://stackoverflow.com/questions/9405575/android-bluetooth-sdp-does-not-recognize-service-advertised-in-javame