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

MQTT в android service


Tarik Live

Вопрос

Здравствуйте! Уже почти неделю пытаюсь завести библиотеку org.eclipse.paho.client.mqttv3-1.2.0 в своём приложении. Я знаю о существовании компонента от TMS, но он не умеет работать в фоновом сервисе.
Вот код который я использую для тестов:
 

Спойлер

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, System.Android.Service,
  FMX.Controls.Presentation, FMX.StdCtrls, Androidapi.JNI.App, Androidapi.JNI.GraphicsContentViewText,
  Androidapi.Helpers, JavaInterfaces, System.Notification, Androidapi.JNI.JavaTypes,
  Androidapi.JNIBridge, System.IOUtils;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    NotificationCenter1: TNotificationCenter;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}

procedure TForm1.Button1Click(Sender: TObject);
begin
 TLocalServiceConnection.StartService('serviceTest2Service');
end;

procedure TForm1.Button2Click(Sender: TObject);
var
LIntent: JIntent;
begin
 LIntent := TJIntent.Create;
  LIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString('com.embarcadero.services.serviceTest2Service'));
  TAndroidHelper.Activity.stopService(LIntent);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
MyNotification: TNotification;
mqtt:JMqttClient;
mqttconopt:JMqttConnectOptions;
//presistance:JMqttDefaultFilePersistence;
jstr:jstring;
//context:JContext;
patch:tpath;
begin
MyNotification := NotificationCenter1.CreateNotification;
  MyNotification.Title := 'Service';  //заголовок
  MyNotification.AlertBody := (patch.GetPublicPath);//текст
  //MyNotification.Name:='Notification Name';
  MyNotification.EnableSound:=True;
  //presistance:=TJMqttDefaultFilePersistence.JavaClass.init(StringToJString(patch.GetPublicPath));
  NotificationCenter1.PresentNotification(MyNotification);
  mqtt:=TJMqttClient.JavaClass.init(StringToJString('tcp://m23.cloudmqtt.com:11021'), StringToJString('java'));
  //MyNotification.AlertBody := '2';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqttconopt:=TJMqttConnectOptions.JavaClass.init();
  //MyNotification.AlertBody := '3';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqttconopt.setUserName(StringToJString('wfntgpvq'));
  jstr:=StringToJString('MWPri3WtH_QZ');
  mqttconopt.setPassword(jstr.toCharArray);
  mqttconopt.setAutomaticReconnect(True);
  mqttconopt.setCleanSession(false);
  //MyNotification.AlertBody := '4';//текст
  //NotificationCenter1.PresentNotification(MyNotification);
  mqtt.connect() ;
  MyNotification.AlertBody := '5';//текст
  NotificationCenter1.PresentNotification(MyNotification);

end;

end.

 

Стандартная библиотека org.eclipse.paho.client.mqttv3-1.2.0 выпадает в ошибку initializer error сразу на строчке 

mqtt:=TJMqttClient.JavaClass.init(StringToJString('tcp://m23.cloudmqtt.com:11021'), StringToJString('java'));

по логам с телефона стало понятно, что проблема в логах ? а конкретно когда библиотека пытается создать логгер выпадает ошибка что не найден файл локализации ru_RU для logcat (сами файлы там вроде как есть). Ладно. Скачал исходники почистил код библиотеки от упоминаний логгера, собрал ииии и ничего. Продвинулся до строчки 

mqtt.connect();

также пробивал 

mqtt.connect(mqttconopt);

ничего не помагает, получаю ошибку сегментации класса 
Пока не понятно куда копать дальше? Возможно что не все библиотеки можно использовать в delphi приложениях? 

P.S Старая версия 1.1.1 тоже не завелась :(

service test2.rar

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

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

  • 0
В 25.11.2018 в 19:37, Tarik Live сказал:

https://github.com/fusesource/mqtt-client
без танцев с бубном не обошлось, но уже получилось подключится к серверу 

А можно ваш пример реализации приложения?

Ссылка на комментарий
  • 0
В 25.11.2018 в 18:35, Tarik Live сказал:

Вопрос закрыт. Удалось завести другую библиотеку

Пробовал сделать приложение с сервисом, в самом приложении MQTT работает, а вот сервис запускается и останавливается, но не работает с MQTT, ни отсылает на брокер ни принимает. Я правильно понимаю, этот код принимает сообщения и выдает сообщение MyNotification?

Procedure TDM.MqttMonitor;
var
MyNotification: TNotification;
mess:Jclient_Message;
Bytes: TJavaArray<Byte>;
JS2: JString;
begin
running:=True;
MyNotification := NotificationCenter1.CreateNotification;
MyNotification.Title := 'Mqtt Service';  //заголовок
while True do
begin
  mess:=connection.receive;

  Bytes:=mess.getPayload;
  JS2:=TJString.JavaClass.init(bytes);
  MyNotification.AlertBody := (JStringToString(JS2));//текст
  MyNotification.EnableSound:=True;
  NotificationCenter1.PresentNotification(MyNotification);
end;
end;

А при создании сервиса подписка на топик, который будет мониторится, верно?

topic:=TJTopic.JavaClass.init(StringToJString('android'), TJQoS.JavaClass.AT_LEAST_ONCE);

 

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

Пробовал сделать приложение с сервисом, в самом приложении MQTT работает, а вот сервис запускается и останавливается, но не работает с MQTT, ни отсылает на брокер ни принимает. Я правильно понимаю, этот код принимает сообщения и выдает сообщение MyNotification?


Procedure TDM.MqttMonitor;
var
MyNotification: TNotification;
mess:Jclient_Message;
Bytes: TJavaArray<Byte>;
JS2: JString;
begin
running:=True;
MyNotification := NotificationCenter1.CreateNotification;
MyNotification.Title := 'Mqtt Service';  //заголовок
while True do
begin
  mess:=connection.receive;

  Bytes:=mess.getPayload;
  JS2:=TJString.JavaClass.init(bytes);
  MyNotification.AlertBody := (JStringToString(JS2));//текст
  MyNotification.EnableSound:=True;
  NotificationCenter1.PresentNotification(MyNotification);
end;
end;

А при создании сервиса подписка на топик, который будет мониторится, верно?


topic:=TJTopic.JavaClass.init(StringToJString('android'), TJQoS.JavaClass.AT_LEAST_ONCE);

 

Подписка чуть больше, а так да все верно.

topicArray:=TJavaObjectArray<Jtopic>.Create(1);
topic:=TJTopic.JavaClass.init(StringToJString('android/java/'), TJQoS.JavaClass.AT_LEAST_ONCE);
topicArray.Items[0]:=topic;
connection.subscribe(topicArray);

Очень рад, что у вас получилось)

Ссылка на комментарий
  • 0
В 18.04.2019 в 22:20, Tarik Live сказал:

Подписка чуть больше, а так да все верно.


topicArray:=TJavaObjectArray<Jtopic>.Create(1);
topic:=TJTopic.JavaClass.init(StringToJString('android/java/'), TJQoS.JavaClass.AT_LEAST_ONCE);
topicArray.Items[0]:=topic;
connection.subscribe(topicArray);

Очень рад, что у вас получилось)

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Ссылка на комментарий
  • 0
В 20.04.2019 в 01:40, tetronis сказал:

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Переподключение я не делал т.к использовал на сотовом интернете а он был всегда

Ссылка на комментарий
  • 0
В 20.04.2019 в 01:40, tetronis сказал:

Еще вопрос, а как вы реализовали отслеживание, если отключится от брокера? или будет переподключаться сам? но у меня так не происходит и через время телефон отрубает WiFi и видимо происходит отключение, сообщения не приходят.

Думаю у вашем случае будет полезно. Просто поставьте проверку значения данной функции

mqtt.JPG

Ссылка на комментарий
  • 0
1 час назад, Tarik Live сказал:

Переподключение я не делал т.к использовал на сотовом интернете а он был всегда

за пределы города хоть раз выезжали? :-)

Ссылка на комментарий
  • 0
17 часов назад, Tarik Live сказал:

Думаю у вашем случае будет полезно. Просто поставьте проверку значения данной функции

mqtt.JPG

Да, функции я смотрел и пробовал использовать, но безуспешно, все виснет при запуске. Вообще разные сборки ведут себя по разному, при отсутствии изменений в коде, что очень странно. Пробовал так же вставить таймер и по нему проверять, подключен ли клиент, но опять же, даже не стартует сервис с таймером(узнал что таймеры не работают в сервисах, так что этот вопрос попробую решить). Думал может вы какой-то код реализовали и обошли грабли.

Но про подключение я имел ввиду, что когда гаснет экран телефона/планшета, устройство выключает WiFi, и соответственно сервис отключается от MQTT брокера, а значит это нужно отлавливать и переподключаться.

Не совсем понятен этот код

if running = False then TTask.Run(MqttMonitor);

Сам running нигде не меняет значение, кроме TDM.MqttMonitor; (running:=True;), а при каких условиях выставляется false?

Изменено пользователем tetronis
Ссылка на комментарий
  • 0
19 часов назад, tetronis сказал:

Да, функции я смотрел и пробовал использовать, но безуспешно, все виснет при запуске. Вообще разные сборки ведут себя по разному, при отсутствии изменений в коде, что очень странно. Пробовал так же вставить таймер и по нему проверять, подключен ли клиент, но опять же, даже не стартует сервис с таймером(узнал что таймеры не работают в сервисах, так что этот вопрос попробую решить). Думал может вы какой-то код реализовали и обошли грабли.

Но про подключение я имел ввиду, что когда гаснет экран телефона/планшета, устройство выключает WiFi, и соответственно сервис отключается от MQTT брокера, а значит это нужно отлавливать и переподключаться.

Не совсем понятен этот код


if running = False then TTask.Run(MqttMonitor);

Сам running нигде не меняет значение, кроме TDM.MqttMonitor; (running:=True;), а при каких условиях выставляется false?

Т.к TDM.AndroidServiceStartCommand может срабатывать несколько раз я ввел   переменную running, чтобы по нескольку раз не стартовал сам mqtt клиент. По вопросу автоматического переподключения я пока не разбирался, нужно чуток больше свободного времени, но есть пару идей. Как протестирую отпишусь. И да, таймер и все что обращается к "форме" в сервисах не работает :(

Изменено пользователем Tarik Live
Ссылка на комментарий
  • 0
В 22.04.2019 в 22:02, Tarik Live сказал:

Т.к TDM.AndroidServiceStartCommand может срабатывать несколько раз я ввел   переменную running, чтобы по нескольку раз не стартовал сам mqtt клиент. По вопросу автоматического переподключения я пока не разбирался, нужно чуток больше свободного времени, но есть пару идей. Как протестирую отпишусь. И да, таймер и все что обращается к "форме" в сервисах не работает :(

С таймером разобрался, использую AndroidTimerSetInterval, сделал отсылку на брокер каждые 10 сек данные, но столкнулся с проблемой, сервис через время убивается, шлется какое-то время данные, а потом все, убивается и приложение и сервис...хоть и указано START_STICKY.

А вы как-то реализовывали отсылку из приложения через сервис и обратно, данные MQTT?

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

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

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

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

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

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

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

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

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

×
×
  • Создать...