Перейти к содержанию
  • 0
Rusland

Получение GPS координат из сервиса

Вопросы

На радостях что сервис теперь может автоматически стартовать после перезагрузки системы (спасибо Ефимову Андрею), решил что пора научится получать координаты GPS через сервис.

 

Вариант 1.

 

Как-то я уже пробовал это сделать прицепив к dfm TLocationSensor, но был крах.

Сегодня я прочитал вот такую статейку где говорится как раз об этом - крошится из-за того что в System.Android.Sensors используется Activity, которое null (у нас же сервис, а не простое приложение) 

и предлагается решение в виде внесения изменение в System.Android.Sensors и System.Sensors.

Я внес указанные изменения (сами файлы в patch.zip прикрепил к сообщению), скачал их Демо пример отсюда, положил вышеуказанные файлы в папку patch, но при компиляции выдает 3 ошибки вида:

 

[DCC Error] System.SensorsDD.pas(805): E2010 Incompatible types: 'TSensorManager.TSensorManagerType' and 'class of TPlatformSensorManager'

[DCC Error] System.SensorsDD.pas(1144): E2361 Cannot access private symbol TGeocoder.GeocoderImplementer

[DCC Error] System.SensorsDD.pas(1449): E2362 Cannot access protected symbol TPlatformGpsStatus.GetGpsStatusImplementer

на строки соответственно

 

FSensorManagerType := TPlatformSensorManager;

TGeocoder.FCurrent := TPlatformGeocoder.GeocoderImplementer;

TGpsStatus.FCurrent := TPlatformGpsStatus.GetGpsStatusImplementer;

Попробуйте кто-нибудь скомпилировать у себя пожалуйста. Пример должен быть рабочий по идее...

 

тогда я решил действовать по другому:

 

Вариант 2.

 

Я вспомнил что можно обойтись без TLocationSensor и использовать LocationListener.

В сервисе  сделал так:

unit Unit2;

interface

uses
  System.SysUtils,
  System.Classes,
  System.Android.Service,
  AndroidApi.JNI.GraphicsContentViewText,
  Androidapi.JNI.Os,
  Androidapi.JNI.App,
  Androidapi.JNI.Location,Androidapi.JNIBridge,Androidapi.JNI.JavaTypes,Androidapi.Helpers, // для координат
  AndroidApi.Log; // лог смотреть через monitor.bat

type
  TLocationListener = class;

  TAndroidServiceDM = class(TAndroidService)
    function AndroidServiceStartCommand(const Sender: TObject;
      const Intent: JIntent; Flags, StartId: Integer): Integer;
  private
    { Private declarations }
    FLocationManager: JLocationManager;
    locationListener: TLocationListener;
  public
    destructor Destroy; override;
    { Public declarations }
    procedure StartLocator();
    procedure onLocationChanged(Location: JLocation);
  end;

  TLocationListener = class(TJavaLocal, JLocationListener)
  private
    [weak]
    FParent: TAndroidServiceDM;
  public
    constructor Create(AParent: TAndroidServiceDM);
    procedure onLocationChanged(Location: JLocation); cdecl;
    procedure onProviderDisabled(provider: JString); cdecl;
    procedure onProviderEnabled(provider: JString); cdecl;
    procedure onStatusChanged(provider: JString; status: Integer; extras: JBundle); cdecl;
  end;

var
  AndroidServiceDM: TAndroidServiceDM;

implementation

{%CLASSGROUP 'FMX.Controls.TControl'}


{$R *.dfm}

function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject;
  const Intent: JIntent; Flags, StartId: Integer): Integer;
begin
  StartLocator();
  Result:=TJService.JavaClass.START_STICKY;
end;

destructor TAndroidServiceDM.Destroy;
begin
  if Assigned(locationListener) then
    FLocationManager.removeUpdates(locationListener);
  inherited;
end;

procedure TAndroidServiceDM.onLocationChanged(Location: JLocation);
var
  M: TMarshaller;
begin
  if Assigned(Location) then
  begin
    Logi(M.AsUtf8('LogLatitude '+ Location.getLongitude.ToString).ToPointer);
    Logi(M.AsUtf8('LogLongitude '+Location.getLongitude.ToString).ToPointer);
  end;
end;

procedure TAndroidServiceDM.StartLocator();
var
  LocationManagerService: JObject;
  GPSLocation, NetworkLocation: JLocation;
begin
  if not Assigned(FLocationManager) then
  begin
    LocationManagerService := SharedActivityContext.getSystemService(TJContext.JavaClass.LOCATION_SERVICE);
    FLocationManager := TJLocationManager.Wrap((LocationManagerService as ILocalObject).GetObjectID);
    if not Assigned(locationListener) then
      locationListener := TLocationListener.Create(self);                                    
    FLocationManager.requestLocationUpdates(TJLocationManager.JavaClass.GPS_PROVIDER, 10000, 0, locationListener,
      TJLooper.JavaClass.getMainLooper);                                                         
    FLocationManager.requestLocationUpdates(TJLocationManager.JavaClass.NETWORK_PROVIDER, 10000, 0, locationListener,
      TJLooper.JavaClass.getMainLooper);
  end;
  GPSLocation := FLocationManager.getLastKnownLocation(TJLocationManager.JavaClass.GPS_PROVIDER);
  NetworkLocation := FLocationManager.getLastKnownLocation(TJLocationManager.JavaClass.NETWORK_PROVIDER);
  onLocationChanged(GPSLocation);
  onLocationChanged(NetworkLocation);
end;

constructor TLocationListener.Create(AParent: TAndroidServiceDM);
begin
  inherited Create;
  FParent := AParent;
end;

procedure TLocationListener.onLocationChanged(Location: JLocation);
begin
  FParent.onLocationChanged(Location);
end;

procedure TLocationListener.onProviderDisabled(provider: JString);
begin

end;

procedure TLocationListener.onProviderEnabled(provider: JString);
begin

end;

procedure TLocationListener.onStatusChanged(provider: JString; status: Integer; extras: JBundle);
begin

end;

end.

После старта приложения, через несколько секунд оно морозится и система спрашивает "Подождать?". 

Расстановка breakpoint-ов мне не помогла, ошибка случается раньше Segment fault 11.

 

Пример в архиве ASARservRepair2.zip прикрепляю.

Посмотрите пожалуйста в чем может быть проблема?

ASARservRepair2.zip

patch.zip

Отредактировал Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

  • 0

PS. Первое решение оказалось рабочим... не знаю почему у меня вчера отказывалось нормально работать  :) Пользуйтесь.

 

PPS. Надеюсь Embarcadero исправит этот баг в следующей версии и не придется делать столько телодвижений )

 

Странно что после закрытия программы сервис перестает слать координаты - значок GPS пропадает. Хотя в Настройки->Приложения->Работающие я вижу как процесс перезапускается.

Отредактировал Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 29.01.2016 в 13:19, Rusland сказал:

Странно что после закрытия программы сервис перестает слать координаты - значок GPS пропадает. Хотя в Настройки->Приложения->Работающие я вижу как процесс перезапускается.

Rusland, не нашлось решение этой проблемы?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Pax Beach, видимо у вас Delphi 10 Seattle, решение есть - я изменил согласно этой статье и все заработало. Если не получится, обращайтесь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
6 минут назад, Pax Beach сказал:

Пробую Ваше решение на 10 Update 1, но оно не до конца работает, как я понял из темы

А что значит не до конца работает? Вроде все работало... хоть в конечном итоге мне и пришлось отказаться от этой идеи.

Отредактировал Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, Rusland сказал:

А что значит не до конца работает?

Я имею ввиду фразу «Странно что после закрытия программы сервис перестает слать координаты - значок GPS пропадает. Хотя в Настройки->Приложения->Работающие я вижу как процесс перезапускается.». Эту проблему удалось решить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Pax Beach, Насколько помню, там дело обстоит так (и это касается сервисов в целом), после закрытия приложения - сервис отключается и не подает признаков жизни, но через некоторое время снова начинает работать. Я думаю это сделано специально, чтобы в случае какой-нибудь ошибки, суметь добраться до Настроек и удалить приложение :) 

То есть по идее через какое-то время значок GPS снова появится... вот только не знаю чему это время равно.

Отредактировал Rusland

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Нет, я неправ. Сейчас проверил. в 12:07 закрыл программу, значок GPS пропал и не появляется до настоящего времени (12:47) :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Rusland, второй способ вылетает с ошибкой, пробую первый способ (подключил в сервисе пропатченные модули ...DD, положил компонент TLocationSensor на форму) → при запуске сервиса вылетает ошибка и приложение закрывается. Подскажите, может я чего-то не сделал, например classes.dex надо как-то перестраивать или еще какие-нибудь ухищрения?

Код сервиса простой и лог монитора прилагаю.

function TAndroidServiceDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent;
  Flags, StartId: Integer): Integer;
begin
//  JavaService.stopSelf;
//  Log.D('Serice started?');
  if not LocationSensor.Active then
    LocationSensor.Active := true;

  Result := TJService.JavaClass.START_STICKY;
end;

procedure TAndroidServiceDM.LocationSensorLocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
var
  M: TMarshaller;
begin
//  if Assigned(NewLocation) then
//  begin
    Logi(M.AsUtf8('LogLatitude '+ NewLocation.Latitude.ToString).ToPointer);
    Logi(M.AsUtf8('LogLongitude '+NewLocation.Longitude.ToString).ToPointer);
//  end;
//  Log.D(Format('Coords:%8.8f;%8.8f', [NewLocation.Latitude, NewLocation.Longitude]));
end;

 

2016-05-05_12-55-35.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
42 минуты назад, Rusland сказал:

Нет, я неправ. Сейчас проверил. в 12:07 закрыл программу, значок GPS пропал и не появляется до настоящего времени (12:47) :(

Я пробую пример итальянского коллеги, он работает почему-то. В нем, когда убиваешь в памяти приложение, монитор выбрасывает такой Warning:

05-05 13:14:30.008: W/linker(22430): /data/app/com.embarcadero.LocationSensorDemo-1/lib/arm/libProxyAndroidService.so: is missing DT_SONAME will use basename as a replacement: "libProxyAndroidService.so"


Антенна GPS пропадает, лог больше ничего не собирает. Сервис самостоятельно не запускается.

 

Отредактировал Pax Beach

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
21 минуту назад, Rusland сказал:

Вот собрал проект на 10-ке LocationSensorPatch3.rar

Да, этот пример работает. Спасибо.

Описанная выше ошибка (не запускается сервис) вылетает, если я с нуля собираю проект. Видимо, как-то классы сервиса присоединять в classes.dex приложения нужно и пересобирать его.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, Pax Beach сказал:

Видимо, как-то классы сервиса присоединять в classes.dex приложения нужно и пересобирать его.

Думаю что нет. Я же прислал пример без готового classes.dex 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Rusland, спасибо за пример 2.

Много времени потратил на изучение работы из под сервиса.

В итоге, в Berlin в сервисе отлично работает JLocationManager и JLocationListener.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 05.05.2016 в 16:17, Rusland сказал:

Вот собрал проект на 10-ке LocationSensorPatch3.rar

Удалось решить проблему с вылетом сервиса? Приложение закрываешь и все, координаты не летят.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
2 минуты назад, MikeWuzHere сказал:

Удалось решить проблему с вылетом сервиса? Приложение закрываешь и все, координаты не летят.

Какое устройство, ОС, версия Delphi?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
5 минут назад, Pax Beach сказал:

Какое устройство, ОС, версия Delphi?

Андроид (Le Eco Le 2, самсунг гал 3), 10 seattle. Проблема в том, что как только чистится память или закрывается приложени в ручную умирает и сервис, точнее не сам сервис, а координаты идти перестают.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

ну вроде 100 раз писали, что из телефона трекер не нужно делать. мобильные ОС против.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, MikeWuzHere сказал:

Андроид (Le Eco Le 2, самсунг гал 3), 10 seattle. Проблема в том, что как только чистится память или закрывается приложени в ручную умирает и сервис, точнее не сам сервис, а координаты идти перестают.

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

Лог монитор в помощь. Что показывает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Только что, Pax Beach сказал:

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

Лог монитор в помощь. Что показывает?

Вроде писал start sticky, но почему то по выходу с приложения и сервиса не видно. С логами не разобрался как работать, но вот вроде что то нарыл (до этого видел что туда летят координаты).

592d0eb0736bc_.png.43c3d68ca30bfad7884457bac1b9d0a4.png

Судя по логам по завершеню работы самой программы - умирает и сервис, но старт стики почему то не срабатывает О_О

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, MikeWuzHere сказал:

Вроде писал start sticky, но почему то по выходу с приложения и сервиса не видно. С логами не разобрался как работать, но вот вроде что то нарыл (до этого видел что туда летят координаты).

592d0eb0736bc_.png.43c3d68ca30bfad7884457bac1b9d0a4.png

Судя по логам по завершеню работы самой программы - умирает и сервис, но старт стики почему то не срабатывает О_О

Что-то не так в логах. Фигурирует три пакета com.embarcadero... А должно быть максимум два.

Надо всё почистить и заново собрать. Если не заработает, смотреть код.

GPS трекер отлично работает нас телефонах. Только Xiomi не победил пока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
Только что, Pax Beach сказал:

Что-то не так в логах. Фигурирует три пакета com.embarcadero... А должно быть максимум два.

Надо всё почистить и заново собрать. Если не заработает, смотреть код.

GPS трекер отлично работает нас телефонах. Только Xiomi не победил пока.

А я код и не менял, пример от RUSLAND который был собран им под 10ку, все стоковое, собрал и вот такое вот.  Не менял прям вот совсем ничего, может как то по другому можно логи отфильтровать? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 30.05.2017 в 12:27, Pax Beach сказал:

Что-то не так в логах. Фигурирует три пакета com.embarcadero... А должно быть максимум два.

Надо всё почистить и заново собрать. Если не заработает, смотреть код.

GPS трекер отлично работает нас телефонах. Только Xiomi не победил пока.

Можете сделать сэмпл? Уже установил Rad Studio Tokio, сменил мобильник на LG, проблема не решается. Как только я тапаю на кнопку домой то gps данные перестают лететь в логи, а как только закрываю приложение то пропадает значок gps.

p.s. я уже было за голову схватился, но оказалось что gps все же шлет данные в свернутом виде. Проблема при закрытии самого приложения осталась. 

Прикладываю логи: 

Цитата

06-06 15:01:07.785: I/info(4760): New location available -> Latitude: 40,278767, Longitude: 70,895717 
06-06 15:01:15.730: I/info(4760): FMX: LocationSensorDemo: [Context Exception]: Error in context method 'DoFinalizeShader'.
06-06 15:01:15.730: I/info(4760): FMX: LocationSensorDemo: [Context Exception]: Error in context method 'DoFinalizeShader'.
06-06 15:01:15.730: I/info(4760): FMX: LocationSensorDemo: [Context Exception]: Error in context method 'DoFinalizeShader'.
06-06 15:01:15.730: I/info(4760): FMX: LocationSensorDemo: [Context Exception]: Error in context method 'DoFinalizeShader'.
06-06 15:01:17.307: W/linker(5097): /data/app/com.embarcadero.LocationSensorDemo-1/lib/arm/libProxyAndroidService.so: unused DT entry: type 0xf arg 0x8f21
06-06 15:01:17.307: W/linker(5097): /data/app/com.embarcadero.LocationSensorDemo-1/lib/arm/libProxyAndroidService.so: is missing DT_SONAME will use basename as a replacement: "libProxyAndroidService.so"
06-06 15:01:17.325: W/linker(5097): /data/app/com.embarcadero.LocationSensorDemo-1/lib/arm/libLocationService.so: unused DT entry: type 0xf arg 0x9f19
06-06 15:01:17.325: W/linker(5097): /data/app/com.embarcadero.LocationSensorDemo-1/lib/arm/libLocationService.so: is missing DT_SONAME will use basename as a replacement: "libLocationService.so"

 

Отредактировал MikeWuzHere

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 06.06.2017 в 14:59, M1shQa сказал:

Можете сделать сэмпл? Уже установил Rad Studio Tokio, сменил мобильник на LG, проблема не решается. Как только я тапаю на кнопку домой то gps данные перестают лететь в логи, а как только закрываю приложение то пропадает значок gps.

p.s. я уже было за голову схватился, но оказалось что gps все же шлет данные в свернутом виде. Проблема при закрытии самого приложения осталась. 

Прикладываю логи: 

 

Такая же проблема! А еще не понятно как вытащить адрес...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
13 часов назад, gutalin79 сказал:

Такая же проблема! А еще не понятно как вытащить адрес...

Для работы локатора в свернутом приложении, стоит работу с GPS вынести в сервис. Понятно, что это только для Android.

Вытащить адрес, видимо речь о почтовых адресах, нужно использовать API Google services, у них такое есть.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
6 часов назад, Pax Beach сказал:

Для работы локатора в свернутом приложении, стоит работу с GPS вынести в сервис. Понятно, что это только для Android.

Вытащить адрес, видимо речь о почтовых адресах, нужно использовать API Google services, у них такое есть.

 

      В System.Android.SensorsDD тоже что-то такое есть.

      Addr.AdminArea       := JStringToString(LAddress.getAdminArea);
      Addr.CountryName     := JStringToString(LAddress.getCountryName);
      Addr.CountryCode     := JStringToString(LAddress.getCountryCode);
........
      Addr.SubLocality     := JStringToString(LAddress.getSubLocality);
      Addr.SubThoroughfare := JStringToString(LAddress.getSubThoroughfare);
      Addr.Thoroughfare    := JStringToString(LAddress.getThoroughfare);

только я так и не вытащил город или улицу и т.д....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

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

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


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

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

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