Я занимаюсь разработкой приложения Bluetooth для моего MSc. Завершить проект. Он включает в себя сервер, реализованный в JAVA ME
, и клиент, написанный в Android
.
Проблема в том, что Android SDP
не может распознать ServiceRecord
моего сервера JAVA ME.
Если я использую методы BluetoothDevice.getUuids()
и BluetoothDevice.fetchUuidsWithSdp()
в моем клиенте, они возвращают набор UUIDs
, но моего сервиса UUID
нет среди них, поэтому я не могу подключиться к нему.
Это код для JAVAME
примера сервера:
/*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.
*/
}
}
И это часть Android-клиента:
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
}
}
Что меня больше всего беспокоит, так это то, что мой компьютер видит, что мой сервер JAVAME
правильно объявлен:
Что я делаю не так ?? :( Почему мой ПК Bluetooth видит, что мой сервис правильно объявлен в JAVAME
, но Android не может ?? Может ли Android
подключаться через Bluetooth к JAVAME
серверам?
Я прочитал множество других подобных вопросов здесь, в StackOverFlow, но мне не удалось найти работающее решение. (
Я использую Sony Ericsson C702 (Java Platform 8) в качестве тестового сервера. И Samsung Galaxy S (ICS 4.0.3, команда ICSSGS RC4.2)
EDIT1
OK.
Я знаю, в чем проблема.
Я хочу, чтобы сервер JAVAME объявил мой сервис с UUID (например): "68EE1418-12D2-11D7-8EED-00B0D03D76EC", но, похоже, код:
conURL = "btspp://localhost:68EE141812D211D78EED00B0D03D76EC;"
+ "authenticate=false;encrypt=false;name=MySampleApp";
server = (StreamConnectionNotifier)
Connector.open(conURL);
Добавляет UUID службы последовательного порта по умолчанию «00001101-0000-1000-8000-00805F9B34FB» в качестве атрибута ServiceClassIDList:
Теперь забавно то, что в Android метод BluetoothDevice.fetchUuidsWithSdp ();
Похоже, что он извлекает UUID по умолчанию «00001101-0000-1000-8000-00805F9B34FB» вместо моего UUID «68EE1418-12D2-11D7-8EED-00B0D03D76EC», перекрывая мою службу со службой серийного порта по умолчанию мобильного телефона.
Что-то похожее на средневековый сетевой сканер Bluetooth, он распознает мой сервис, но рекламируется как "00001101-0000-1000-8000-00805F9B34FB":
Что я могу сделать, чтобы удалить лишние UUID
, которые JAVAME
автоматически добавляют к моему сервису?
Пожалуйста, помогите, спасибо!
EDIT2
ОК, проблема возникает с телефонами Sony Ericsson. Очевидно, они вставляют стандартный последовательный порт UUID {0x1101}
перед моим пользовательским UUID
, в то время как телефоны Samsung и Nokia, например, вставляют этот стандартный UUID
позади моего собственного в служебной записи. Похоже, что Android извлекает только первое значение атрибута 0x001
в служебной записи, поэтому путает мой сервис со стандартным последовательным портом, который поставляется с некоторыми устройствами.
Так что решение будет:
Есть ли способ с текущим API Android, чтобы получить больше servicerecord
атрибутов, кроме ServiceClassID (0x001)
?
или
Есть ли способ обновить servicerecord
, хранящийся в базе данных обнаружения служб (SDDB), после вызова метода acceptAndOpen -JAVAME-? -Я использовал LocalDevice.updateRecord
после создания сервиса на SDDB
, он работает на эмуляторе, но выдает исключение и ничего не делает на реальных устройствах.