4

I was wandering if you can enable the GPS service in a Firemonkey project? The locationsensor doesn't enable it. It can only get GPS coordinates if GPS is enabled or you have a network location.

In some other Android apps it asks if you want to enable the GPS, and if you agree it will enable GPS for that app. I also want to do this.

I already know how to check if GPS service is enabled for Android, but not how to enable it itself.

Code below is how to check if GPS is enabled:

uses
  Androidapi.JNI.Location,
  Androidapi.JNIBridge,
  FMX.Helpers.Android,
  Androidapi.JNI.GraphicsContentViewText;

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  locationManager : JLocationManager;
begin
  locationManager := TJLocationManager.Wrap( ((SharedActivity.getSystemService(TJContext.JavaClass.LOCATION_SERVICE)) as ILocalObject).GetObjectID);

  if locationManager.isProviderEnabled(TJLocationManager.JavaClass.GPS_PROVIDER) then
   ;   //do something   

  if locationManager.isProviderEnabled(TJLocationManager.JavaClass.NETWORK_PROVIDER) then 
   ;   //do something  else
end;

I've tried to do the same if you would program it in Java. Like this link: https://stackoverflow.com/a/5305835/2728408

procedure TForm1.Button1Click(Sender: TObject);
{$IFDEF ANDROID}
var
  Intent: JIntent;
{$ENDIF}
begin
{$IFDEF ANDROID}
  Intent := TJIntent.Create;
  Intent.addCategory(TJIntent.JavaClass.CATEGORY_ALTERNATIVE);
  Intent.setData(TJnet_Uri.JavaClass.parse(StringToJString('3')));
  Intent.setClassName(StringToJString('com.android.settings'), StringToJString('com.android.settings.widget.SettingsAppWidgetProvider'));
  try
    //For Delphi 10 Seattle
    TAndroidHelper.Activity.sendBroadcast(Intent);
    //For older versions of Delphi
    //SharedActivity.sendBroadcast(Intent);
  except
    on e: exception do
    begin
      ShowMessage('Error: ' + e.Message);
    end;
  end;
{$ENDIF}
end;

I don't get any error but my GPS also doesn't get turned on.

UPDATE: It seems to be disabled to enable GPS for Android 4.0 and higher.

Community
  • 1
  • 1
Remi
  • 1,289
  • 1
  • 18
  • 52
  • Indeed, they do filter this ability to only be able to require user input to proceed. Surely there must be a hack around it though. – Jerry Dodge Apr 05 '16 at 09:13

2 Answers2

7

You can't enable GPS, but you can ask user to do it:

procedure TForm1.GPSSettings;
{$IFDEF ANDROID}
var
  Intent: JIntent;
{$ENDIF}
begin
{$IFDEF ANDROID}
  Intent := TJIntent.Create;
  Intent :=     TJIntent.JavaClass.init(TJSettings.JavaClass.ACTION_LOCATION_SOURCE_SETTINGS);
  TAndroidHelper.Activity.startActivity(Intent);
{$ENDIF}
end;
Rusland
  • 159
  • 2
  • 13
  • This doesn't work for me on Delphi 10.3.3 Rio Community Edition, because `TJSettings.JavaClass.ACTION_LOCATION_SOURCE_SETTINGS` is marked in red. Which `uses` do I need for this to work? – qGold Dec 22 '20 at 16:02
  • I found it. I need `Androidapi.JNI.Provider` in my `uses` – qGold Dec 22 '20 at 16:10
2

The Location Sensor The location sensor is wrapped by the TLocationSensor component.

TLocationSensor fires an OnLocationChanged event when the device detects movement. You can adjust the sensitivity of TLocationSensor using the Distance and Accuracy properties.

The Distance property specifies the minimum distance (in meters) by which the device must move in order to make the location sensor relocate the device and return new location information. For example, if you set Distance to "10", TLocationSensor fires an OnLocationChanged event when you move "10 meters". The Accuracy property represents the level of precision (in meters) by which the sensor locates the device geographically, relative to the geographical point at which the device is actually located. Tip: You should specify the lowest accuracy that works for your application; the higher the accuracy, the more time and power that the sensor requires to determine the location. The recommended values: Distance=0; Accuracy=0. Read Location Information (Latitude, Longitude) from the LocationSensor Component The TLocationSensor component needs to be activated for use. You can turn on/off TLocationSensor based on your input, such as a TSwitch component, or other Application events.

Place a TLocationSensor component from the Tool Palette. On the Form Designer, select the TSwitch component. In the Object Inspector, in the Events tab double-click OnSwitch event. Add the following code to the OnSwitch event handler:

Delphi:

procedure TForm1.Switch1Switch(Sender: TObject);
begin
  LocationSensor1.Active := Switch1.IsChecked;
end;

C++:

void __fastcall TForm1::Switch1Switch(TObject *Sender)
{
        LocationSensor1->Active = Switch1->IsChecked;
}

As discussed earlier, TLocationSensor fires an OnLocationChanged event when you move the mobile device. You can show the current location (Latitude and Longitude) using parameters with an event handler.

On the Form Designer, select the TLocationSensor. In the Object Inspector, in the Events tab double-click OnLocationChange event. Add the following code to the OnLocationChange event handler: Delphi:

procedure TForm1.LocationSensor1LocationChanged(Sender: TObject;
  const OldLocation, NewLocation: TLocationCoord2D);
var
  LDecSeparator: String;
begin
  LDecSeparator := FormatSettings.DecimalSeparator;
  FormatSettings.DecimalSeparator := '.';
  // Show current location
  ListBoxItemLatitude.ItemData.Detail  := Format('%2.6f', [NewLocation.Latitude]);
  ListBoxItemLongitude.ItemData.Detail := Format('%2.6f', [NewLocation.Longitude]);
end;

C++:

void __fastcall TForm1::LocationSensor1LocationChanged(TObject *Sender, const TLocationCoord2D &OldLocation,
                  const TLocationCoord2D &NewLocation)
{
        char LDecSeparator = FormatSettings.DecimalSeparator;
        FormatSettings.DecimalSeparator = '.';
        // Show current location
        ListBoxItemLatitude->ItemData->Detail = ListBoxItemLatitude->ItemData->Detail.sprintf(L"%2.6f", NewLocation.Latitude);
        ListBoxItemLongitude->ItemData->Detail = ListBoxItemLongitude->ItemData->Detail.sprintf(L"%2.6f", NewLocation.Longitude);
}