Перейти к содержанию
Fire Monkey от А до Я
  • 0

Восстановление соединение с BlueTooth устройством.


Вопрос

Сделал работу с BLueTooth , как в примере

https://www.programmersforum.ru/showthread.php?t=312413

 

procedure TServerConnectionTH.Connect(index: integer);
begin
  if (ServerConnectionTH = nil) and ManagerConnected then
  begin
    FAdapter := FBluetoothManager.CurrentAdapter;
    if (FSocket = nil) or (ItemIndex <> index) then
    begin
      if index > -1 then
      begin
        LDevice := FPairedDevices[index] as TBluetoothDevice;
        FSocket := LDevice.CreateClientSocket(StringToGUID(ServiceGUI), False);
        if FSocket <> nil then
        begin
          ItemIndex := index;
          FSocket.Connect;
          Start;
        end;
      end;
    end;
  end;
end;

Всё отлично работает, проблемы начинаются если разнести устройства и связь обрывается.

После этого они уже между собой знаться не хотят и выдаётся сообщение 'IOException: Broken Pipe' .

Иногда восстановления связи даже после однократного перезапуска программы не происходит. 

Кто-то решал подобную задачу? 

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
1.для ускорения соединения добавьте 
bluetoothAdapter.cancelDiscovery();

Перед 

 

  FSocket.Connect;

2. после 

FAdapter := FBluetoothManager.CurrentAdapter;

добавьте

if (FSocket <> nil) then
  FSocket.close;

When you're done with your BluetoothSocket, always call close(). Doing so immediately closes the connected socket and releases all related internal resources.

Ссылка на комментарий
  • 0

Я стал при восстановлении соедиениения делать дисконнект через 

if (FSocket <> nil) then
  FSocket.close;

А потом реконнект.

Стала вываливаться ошибка "socket closed" .  Видимо не рекоенктиваться потом.

 

По поводу 

bluetoothAdapter.cancelDiscovery();

Пишет, что cannot access to protected symbol... 

Ссылка на комментарий
  • 0
57 минут назад, OnePeople сказал:

FAdapter.cancelDiscovery;

На это и пишет 

 

Цитата

[DCC Error] EasyBlueTooth.pas(144): E2362 Cannot access protected symbol TBluetoothAdapter.CancelDiscovery

 

Можно выбрать такой вариант вроде как это оно, но неточно. 

Цитата

FBluetoothManager.cancelDiscovery();

 

Изменено пользователем Андрей Рулин
Дополнение.
Ссылка на комментарий
  • 0

В манифест добавьте    
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />


For apps targeting Build.VERSION_CODES#R or lower, this requires the Manifest.permission#BLUETOOTH_ADMIN permission which can be gained with a simple <uses-permission> manifest tag.
For apps targeting Build.VERSION_CODES#S or or higher, this requires the Manifest.permission#BLUETOOTH_SCAN permission which can be gained with Activity.requestPermissions(String[], int).
Requires Manifest.permission.BLUETOOTH_SCAN

Ссылка на комментарий
  • 0

Да, так работает, хотя в целом коннект и так и так занимает порядка секунды. 

Про подписку вы имеете ввиду что-то вроде этого кода на Java?

https://www.codeproject.com/Articles/814814/Android-Connectivity

  
  @Override
    protected void onResume() {
        super.onResume();
        // Register the BroadcastReceiver for ACTION_FOUND
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        this.registerReceiver(broadcastReceiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        this.unregisterReceiver(broadcastReceiver);
    }

 

Ссылка на комментарий
  • 0

Да, и еще обработчик. В вашем случае будет если устройство было соеденено, то вы запоминаете его идентификатор.

Затем устройство у вас отключается.

Затем когда находится устройство  и вы получаете broadcast 

BluetoothDevice.ACTION_FOUND

вы проверяете, если идентификатор совпадает с сохраненным, заново подключаетесь.

Я бы сделал так)

Ссылка на комментарий
  • 0

Ну кривенько-корявенько, заработало всё-таки по первыому подходу 

 

  try
    Port.Disconnect;
    Port.Suspend;
    Port.Connect(PortIndex,False);
  except                    //Подавляем вывод сообщения о глюке.
 
  end;

...

procedure TServerConnectionTH.Connect(index: integer;IsStart:Boolean=True);
begin
  if (ServerConnectionTH = nil) and ManagerConnected then
  begin
    FAdapter := FBluetoothManager.CurrentAdapter;
    if (FSocket = nil) or (ItemIndex <> index) then
    begin
      if index > -1 then
      begin
        LDevice := FPairedDevices[index] as TBluetoothDevice;
        FSocket := LDevice.CreateClientSocket(StringToGUID(ServiceGUI), False);
        if FSocket <> nil then
        begin
          ItemIndex := index;
          //FluetoothManager.cancelDiscovery();  //Может и не даёт ничего
          FSocket.Connect;
          if IsStart then Start
                     else Resume;
        end;
      end;
    end;
  end;
end;

procedure TServerConnectionTH.Disconnect;
begin
  if (FSocket <> nil) then
     FSocket.close;
 FSocket := nil;
end;

 

Добавил в Disconnect 

 FSocket := nil;

+ После дисконнекта остановку потока. 

 

Кривенько, потому, что информацию об отключении я получаю по факту того, что мне перестали подступать данные. А наверняка есть напрямую решение. 

 

 

 

Изменено пользователем Андрей Рулин
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...