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

TLocationSensor - километраж


Alex Bakulin

Вопрос

Опубликовано

Вопрос простой - есть какие-то встроенные методы, которые позволяют определять пройденное расстояние? Оно понятно, что можно искать расстояние между двумя точками, но вдруг уже до нас что-то придумали. 

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

  • 1
Опубликовано (изменено)
11 часов назад, Саша сказал:

есть ли возможность получать координаты с сенсора принудительно, а не ждать, пока сработает LocationChanged?

Конечно я же вам писал код 2 вариант, в таймере или потоке делаете

  provider := locationManager.getBestProvider(criteria, true);
  location := LocationManager.getLastKnownLocation(provider);

Конечно не хватает, вы либо устанавливаете всю библиотеку alcinoe, а она устанавливается просто копированием файлов, т.к. вам не нужны визуальные компоненты, либо открываете исходник и копируете код с некоторыми правками под fmx

Изменено пользователем OnePeople
  • 0
Опубликовано (изменено)
5 часов назад, OnePeople сказал:

Конечно я же вам писал код 2 вариант, в таймере или потоке делаете

  provider := locationManager.getBestProvider(criteria, true);
  location := LocationManager.getLastKnownLocation(provider);

Здесь несколько вопросов.

1. Достаточно ли второй вариант для пробы вставить в нажатие кнопки Click.

2. В конце второго варианта не хватает только одной строки end; ?

3. Что там в uses?

4. Да и пеерменные какого типа?

 

В инете пока ответы на эти вопросы не нахожу.

Изменено пользователем Саша
Дополнение 2
  • 1
Опубликовано
43 минуты назад, Саша сказал:

Здесь несколько вопросов.

1. Достаточно ли второй вариант для пробы вставить в нажатие кнопки Click.

2. В конце второго варианта не хватает только одной строки end; ?

3. Что там в uses?

4. Да и пеерменные какого типа?

1.Так попробуйте

2.

provider := locationManager.getBestProvider(criteria, true);
            location := LocationManager.getLastKnownLocation(provider);
            if location <> nil then
              begin
                dLatitude := location.getLatitude;
                dLongitude := location.getLongitude;
                dBearing := location.getBearing;

Это вообще отдельно можете хоть в кнопку вставить

3.Androidapi.JNI.Location

4.Вы вообще не хотите ни чего делать, это же глупый вопрос 

LocationManager := TJLocationManager.Wrap((LocationManagerNative as ILocalObject).GetObjectID);

Соответственно JLocationManager

 

criteria := TJCriteria.JavaClass.init;

Соответственно JCriteria

 

LocationManagerNative := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.LOCATION_SERVICE);

Соответственно JObject

5. Вообще Ctrl + space вам в помощь

  • 0
Опубликовано (изменено)
4 часа назад, OnePeople сказал:

Вообще Ctrl + space вам в помощь

Ctrl + space у меня не работает.

А в коде все равно куча ошибок. Катастрофа!

 

1.png

2.png

В строках 1622 и 1639 вот такая ошибка:

there is no overloaded that can be called with these arguments

нет никакого перегруженного, который можно было бы вызвать с этими аргументами
 

Изменено пользователем Саша
Дополнение
  • 0
Опубликовано
В 29.08.2023 в 06:45, OnePeople сказал:

Вообще бы не парились

Скачал Alcinoe-master. Компиляция шла дольше, чем обычно, что обнадеживало, но затем жалоба на невозможность открыть вот этот файл:

C:\Alcinoe-master\Demos\ALGeoPositionSensor\_Source\EXEC

Ну это ладно. Займусь этим позже.

  • 0
Опубликовано (изменено)
14 часов назад, OnePeople сказал:

1622 ну так правильно вы слушатель не создали

Спасибо! И дай Бог,Вам терпения. Похоже, осталось чуть-чуть.

Правильно ли я сделал?

После класса TForm добавил вот что.

  TMyLocatioListner = class(TJavaLocal, JLocationListener)
  private
    [weak]
    FParent: TForm1;
  public
    constructor Create(AParent: TForm1);
    Destructor Destroy; Override;
    procedure onFlushComplete(requestCode: integer); cdecl;
    procedure onLocationChanged(Location: Jlocation); overload; cdecl;
    procedure onLocationChanged(Location: JList); overload; cdecl;
    procedure onProviderDisabled(Provider: JString); cdecl;
    procedure onProviderEnabled(Provider: JString); cdecl;
    procedure onStatusChanged(Provider: JString; status: integer;
      extras: JBundle); cdecl;
  end;

var LocationListner:TMyLocatioListner;  // это создание слушателя?

После этого число ошибок уменьшилось, но они еще остались.


 

2023-09-05_19-53-41.png

 

Да. И какого типа переменные:  dLatitude, dLongitude, dBearing?
У меня они double.

Изменено пользователем Саша
Корректировка сообщения
  • 1
Опубликовано

Объект создается при вызове его конструктора
Object := TMyObject.Create;

var Object : TMyObject; -- это всего лишь описание переменной, ничего более

это ничем не отличается от разных других языков, где object = new Object;

переменная Location должна иметь тот же тип, что возвращает метод LocationManager.GetLastKnownLocation()

соответственно, в описании этого типа можно посмотреть, какой тип имеют его методы  GetLatitude, GetLongitude, GetBearing

  • 0
Опубликовано

Огромно спасибо откликнувшимся в решении данной проблемы!!!

Да! Есть еще асы на этом форуме!

Неоценимую помощь OnePeople. Последних штрих добавил krapotkin, с которым я общаюсь в другой ветке (и скоро возобновлю общение).

LocationListener работает!

Надеюсь, что и в Android13 ои будет работать.

 

 

  • 0
Опубликовано

 

Вставил  в поток по совету OnPeople

provider := locationManager.getBestProvider(criteria, true);

location := LocationManager.getLastKnownLocation(provider);

и т. д.

Работает. Координаты передаются. В верхнем правом углу телефона появляется значок GPS. Если свернуть приложение, а затем развернуть, то через несколько секунд этот значок гаснет, но координаты продолжают определятся.

Пришлось закомментировать эту строку, dBearing := location.getBearing , так как иногда возникает ошибка деления на 0. Похоже, что там возращается NaN. Попробую ее облачить в конструкцию try except  end.

  • 0
Опубликовано

Моя задумка постепенно воплощается в жизнь.

В личку пришлю исходники всем ответившим. Только обещайте, что не будете смеяться с имен переменных.

Программа еще должна передавать некоторые сигнальные файлы на FTP. Это работало отлично, пока я не добавил в манифест:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
после этого связь с интернетом пропала.

Связь восстановилась после добавления в манифест строки:
<uses-permission android:name="android.permission.INTERNET" />


Есть ли такая возможность включать/включать доступ в интернет независимо от пользователя?
То есть цикл в потоке на четном проходе включает доступ в интернет и передает файлы на FTP, а на нечетном выключает.
На нечетном проходе получает только координаты.

  • 1
Опубликовано

пользоваться интернетом на телефоне и включать/выключать на телефоне доступ к конкретному адаптеру - сильно разные задачи

скорее всего, второй вариант система вообще не даст

  • 0
Опубликовано (изменено)
7 часов назад, krapotkin сказал:

пользоваться интернетом на телефоне и включать/выключать на телефоне доступ к конкретному адаптеру - сильно разные задачи

скорее всего, второй вариант система вообще не даст

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

GPS+Test_v1.6.5.apk

Изменено пользователем Саша
  • 0
Опубликовано

Здравствуйте!
Почти два года работает моя рограмма для получения GPS - координат. (Сейчас я её оформлю в спойлер и прикреплю)

Помогите, пожалуйста, добавить в эту программу вывод в TLabel направления на Северный полюс, не используя компонент Delphi TOrientationSensor, который работает как всегда непредсказуемо. Здесь сделано красиво, хотелось, чтобы и с компасом была такая красота.

Вот текст программы. А проект во вложении.

Спойлер

unit Sfera;

interface

uses
  System.SysUtils,
  AndroidApi.JNI.Provider,
  AndroidApi.JNI.GraphicsContentViewText,
  AndroidApi.JNI.Os,
  AndroidApi.JNIBridge,
  AndroidApi.JNI.JavaTypes,
  AndroidApi.JNI.Location,
  FMX.Forms,
  FMX.StdCtrls,
  AndroidApi.Helpers, System.Classes, FMX.Types, FMX.Controls,
  FMX.Controls.Presentation;

type
  TForm1 = class(TForm)
    Label11: TLabel;
    Label12: TLabel;
    Button7: TButton;
    Bt_OnOffGPS: TButton;
    Bt_Exit: TButton;
    Lb_StatGPS: TLabel;

    procedure Bt_ExitClick(Sender: TObject);
    procedure Bt_OnOffGPSClick(Sender: TObject);

    procedure android4_startlocation;
    procedure android4_OnOffGPS;
    procedure Button7Click(Sender: TObject);
    { Private declarations }
  public
    { Public declarations }
  end;

  TMyLocatioListner = class(TJavaLocal, JLocationListener)
  private
    [weak]
    FParent: TForm1;
  public
    constructor Create(AParent: TForm1);
    Destructor Destroy; Override;
    procedure onFlushComplete(requestCode: integer); cdecl;
    procedure onLocationChanged(Location: Jlocation); overload; cdecl;
    procedure onLocationChanged(Location: JList); overload; cdecl;
    procedure onProviderDisabled(Provider: JString); cdecl;
    procedure onProviderEnabled(Provider: JString); cdecl;
    procedure onStatusChanged(Provider: JString; status: integer;
      extras: JBundle); cdecl;
  end;

var
  Form1: TForm1;

  LocationListner: TMyLocatioListner;

  Provider: JString;

  Location: Jlocation;

var
  LocationManager: JLocationManager;
  LocationManagerNative: JObject;
  criteria: JCriteria;
  Intent: JIntent;
  dLatitude, dLongitude, dBearing: double;

var
  flag_startlocation: boolean;

implementation

{$R *.fmx}

procedure TForm1.android4_OnOffGPS;
begin
  Form1.Lb_StatGPS.Text := ' ';
  if not flag_startlocation then android4_startlocation
  else flag_startlocation := false;
  if flag_startlocation then Form1.Lb_StatGPS.Text := 'GPS On'
  else Form1.Lb_StatGPS.Text := 'GPS Off';
end;

procedure TForm1.Bt_OnOffGPSClick(Sender: TObject);
begin
  android4_OnOffGPS;
end;

procedure TForm1.android4_startlocation; // android
var
  i: integer;
begin
  if flag_startlocation then begin
    exit;
  end;
  try
    LocationListner := TMyLocatioListner.Create(Self);
    LocationManagerNative := TAndroidHelper.Context.getSystemService
      (TJContext.JavaClass.LOCATION_SERVICE);
    if LocationManagerNative <> nil then
      LocationManager := TJLocationManager.Wrap
        ((LocationManagerNative as ILocalObject).GetObjectID);
    if LocationManager <> nil then
      LocationManager.requestLocationUpdates
        (TJLocationManager.JavaClass.GPS_PROVIDER, 0, 0, LocationListner,
        TJLooper.JavaClass.getMainLooper);
  except
    i := 0;
  end;

  if LocationManager <> nil then begin
    criteria := TJCriteria.JavaClass.init;
    criteria.setSpeedAccuracy(TJCriteria.JavaClass.ACCURACY_HIGH);
    criteria.setAccuracy(TJCriteria.JavaClass.ACCURACY_FINE);
    criteria.setAltitudeRequired(true);
    criteria.setBearingRequired(true);
    criteria.setSpeedRequired(true);
    if LocationManager.isProviderEnabled
      (TJLocationManager.JavaClass.GPS_PROVIDER) = false then begin
      Intent := TJIntent.Create;
      Intent := TJIntent.JavaClass.init
        (TJSettings.JavaClass.ACTION_LOCATION_SOURCE_SETTINGS);
      TAndroidHelper.Activity.startActivity(Intent);
    end;
  end;
  flag_startlocation := true;
end;

procedure TForm1.Bt_ExitClick(Sender: TObject);
begin
  Form1.Close;
end;

procedure TForm1.Button7Click(Sender: TObject);
begin
  if flag_startlocation then
  begin
    Provider := LocationManager.getBestProvider(criteria, true);
    Location := LocationManager.getLastKnownLocation(Provider);
    dLatitude := Location.getLatitude;
    dLongitude := Location.getLongitude;
    Label11.Text := floattostrf(dLatitude, fffixed, 9, 6);
    Label12.Text := floattostrf(dLongitude, fffixed, 9, 6);
  end;
end;

constructor TMyLocatioListner.Create(AParent: TForm1);
begin
  inherited Create;
  FParent := AParent;
end;

destructor TMyLocatioListner.Destroy;
begin
  //
  inherited;
end;

procedure TMyLocatioListner.onFlushComplete(requestCode: integer);
begin
  //
end;

procedure TMyLocatioListner.onLocationChanged(Location: JList);
begin
  //
end;

procedure TMyLocatioListner.onLocationChanged(Location: Jlocation);
begin
  //
end;

procedure TMyLocatioListner.onProviderDisabled(Provider: JString);
begin
  //
end;

procedure TMyLocatioListner.onProviderEnabled(Provider: JString);
begin
  //
end;

procedure TMyLocatioListner.onStatusChanged(Provider: JString; status: integer;
  extras: JBundle);
begin
  //
end;

end.

 

SFERA8.ZIP

  • 0
Опубликовано (изменено)

Метод onLocationChanged в моей программе пустой:
 

Спойлер

procedure TMyLocatioListner.onLocationChanged(Location: Jlocation);
begin
  //
end;

 

Координаты я получаю по Click:
 

Спойлер

procedure TForm1.Button7Click(Sender: TObject);
begin
  if flag_startlocation then
  begin
    Provider := LocationManager.getBestProvider(criteria, true);
    Location := LocationManager.getLastKnownLocation(Provider);
    dLatitude := Location.getLatitude;
    dLongitude := Location.getLongitude;
    Label11.Text := floattostrf(dLatitude, fffixed, 9, 6);
    Label12.Text := floattostrf(dLongitude, fffixed, 9, 6);
  end;
end;


Все это работает красиво.

Хотелось чтобы по этому же щелчку получать и направление на СП. Как это сделать - не хватает знаний.
Слушатель в моем проекте (SFERA8.ZIP, выложил вчера) слушает сенсор размещения. А как сделать слушатель компаса - не знаю.
Я использую вот такой класс TJavaLocal, но как я понимаю - он для координат.

Изменено пользователем Саша
  • 0
Опубликовано

Ну так разницы ни какой onLocationChanged срабатывает при изменении локации, а у вас просто одиночный запрос локации. Для написания компаса вам нужно просто описать 2 слушателя по аналогии с LocationListener

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);

        sensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME);

    }

Все очень просто

  • 0
Опубликовано

Делаю так:

procedure TfmMain.Button1Click(Sender: TObject);
begin
  accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
  magnetometer = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
  sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
  sensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_GAME);
end;
 

Выходит ошибка.

если закомментировать accelerometer, то ошибка такототипа будет в следующей строке.

 

2025-06-23_01-11-19.png.51d2f5ad346f00570bdd8b5e68158738.png

 

 

 

  • 0
Опубликовано
В 23.06.2025 в 05:18, Саша сказал:

Выходит ошибка.

если закомментировать accelerometer, то ошибка такототипа будет в следующей строке.

Ну так понятно это же код java, смотрите pas, я не проверял некогда

 

Android.SensorListener.rar

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить на вопрос...

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

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

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

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

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

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