Я пытаюсь преобразовать Java-приложение в Android-приложение, но не могу заставить его работать. Приложение предназначено для общения с устройством, которое использует OBEX Push. Устройство не может принимать входящие соединения, и у него нет пользовательского интерфейса, но есть некоторые светодиоды.
Фрагмент кода Java, который я пытаюсь переделать, выглядит следующим образом:
LocalDevice local;
local = LocalDevice.getLocalDevice();
local.setDiscoverable(DiscoveryAgent.LIAC);
String sConnectionURL = "btspp://localhost:" + myUUID + ";name=" + obexName;
this.server = (StreamConnectionNotifier) Connector.open(sConnectionURL);
Я не эксперт по java, но, насколько мне известно, этот фрагмент должен зарегистрировать службу SPP с именем obexName и начать прослушивать входящие соединения через UUID myUUID. Это работает как задумано.
Когда устройство подключается к телефону с запущенным Java-мидлетом, оно устанавливает бит для отправки SPP с UUID на телефоне или не отправляет вообще. Если он не может найти SPP с UUID во время сопряжения, он попытается подключиться к телефону, используя обычный OBEX.
Это метод, который я не могу заставить работать на телефоне Android, ни на HTC Hero, ни на HTC Desire, оба с версией 2.1-update1. Как бы я ни старался, телефон подключается только к телефону, а не к приложению по желанию.
Я создал класс, очень похожий на пример на developer.android.com:
private class AcceptThread extends Thread
{
private final BluetoothServerSocket __serverSocket;
public AcceptThread()
{
BluetoothServerSocket tmpSocket = null;
trace("Creating AcceptThread");
try
{
trace("Starting to listen");
tmpSocket = _bluetoothAdapter.listenUsingRfcommWithServiceRecord(obexName, myUUID);
trace("Listening successful");
}
catch (Exception e)
{
trace("Listening NOT successful");
// TODO: handle exception
}
__serverSocket = tmpSocket;
trace("AcceptThread created");
}
public void run()
{
BluetoothSocket socket = null;
trace("AcceptThread started");
while(true)
{
try
{
trace("Waiting for socket acceptance");
socket = __serverSocket.accept();
trace( "Socket accepted");
}
catch (Exception e)
{
trace("Error when accepting socket: " + e.getLocalizedMessage());
break;
// TODO: handle exception
}
if (socket != null)
{
synchronized (BTTransfer.this)
{
trace("Socket exists");
try
{
__serverSocket.close();
trace("Socket successfully closed");
}
catch (Exception e) {}
break;
}
}
trace("Socket does not exist");
}
}
public void cancel()
{
try
{
__serverSocket.close();
}
catch (Exception e) {}
trace("AcceptThread cancelled and Socket successfully closed");
}
}
Комментарии к коду:
Функция trace - это синхронизированная функция, передающая текст в объект Handler, предоставляющий информацию о пользовательском интерфейсе.
Приложение сознательно ничего не делает, но закрывает соединение после успешного соединения.
Приложение достигает «Ожидание принятия сокета», но никогда не отслеживает после этого.
У меня есть приложение для ПК .NET, которое может маскироваться под устройство, и при использовании правильного UUID оно работает безупречно, но тогда ПК уже подключен к телефону, и у него нет бита, говорящего о том, что он должен отправлять поверх обычного OBEX, если не может найти указанный.
Я работаю с этим уже несколько дней и не могу найти решение. У кого-нибудь есть идеи?
Заранее спасибо,
/ Trygg
Со вторым сообщением я имею в виду следующее:
Когда устройство связывается с телефоном, в выпадающем меню появляется уведомление о том, что устройство связывается. Через несколько секунд (в зависимости от размера файла) файл передается, и появляется второе уведомление о том, что файл передан. Это второе «сообщение».
Поскольку я прислушиваюсь к отключению от устройства, а клиент через мою программу уже знает, что файл передается, это второе уведомление совершенно бесполезно. Тем не менее, он будет появляться каждый раз, когда устройство отправляет файлы на телефон.
В наших тестах на Legend и Hero мы никогда не приходили ко второму уведомлению. Вот где эти телефоны выходят из строя. Приходит первое уведомление, затем ничего, и устройство возвращает ошибку через несколько секунд.
Надеюсь, это поможет уточнить, что я имел в виду.
/ Trygg
Я не получил эту работу, но сделал своего рода обходной путь. Я зарегистрировал BroadcastReceiver на событие BluetoothDevice.ACTION_ACL_DISCONNECTED, а затем проверил, какое устройство было отключено. Если это был "мой", я искал файлы в папке входящих сообщений Bluetooth.
Мне пришло сообщение от производителя устройства о том, что оно пока не будет работать, но они работают над новой прошивкой. Вот почему я не работал здесь и не работал над лучшим решением.