In Delphi 11.3, I'm trying to send a user in my Android app to the device's default mapping app (Google Maps, Waze,...) using an intent. The purpose of the intent is to request directions from the current location to another based on the Lat/Lng coordinates. It worked fine in previous Android & Delphi versions, but this code is not working in Android 13. From what I've read about permissions, it appears as though there are more restrictions beyond Andriod 11.
Anyway, when I click the Navigate button in my app, I keep getting the 'Receiver not found' message.
My AndroidManifest.xml shows these locations permissions:
android:targetSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
Here's my code for the Navigate button click event:
procedure TMainForm.NavigateBtnClick(Sender: TObject);
var
{$IFDEF ANDROID}
Intent: JIntent; //Declares the intent object
{$ENDIF}
LGoogleMapsURL: String;
begin
// Populate a string to send to Mapping app
LGoogleMapsURL:= 'google.navigation:q=37.422219,-122.08364&mode=d';
{$IFDEF MSWINDOWS}
WebBrowser1.Navigate(LGoogleMapsURL);
{$ENDIF}
{$IFDEF ANDROID}
Intent := TJIntent.Create;
Intent.setData(StrToJURI(LGoogleMapsURL));
Intent.setAction(TJIntent.JavaClass.ACTION_VIEW);
Intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString(LGoogleMapsURL));
if MainActivity.getPackageManager.queryIntentActivities(Intent, TJPackageManager.JavaClass.MATCH_DEFAULT_ONLY).size > 0 then
begin
MainActivity.startActivity(Intent);
end
else
ShowMessage('Receiver not found');
{$ENDIF}
end;
Is this no longer valid for use in Android 13 or is something missing?
In order to make your example work, I needed to:
Modify AndroidManifest.template.xml, to change the <queries>
tag to:
<queries>
<%queries-child-elements%>
<package android:name="com.google.android.apps.maps" />
</queries>
(see here)
..and alter the code:
URI := TJnet_Uri.JavaClass.parse(StringToJString('google.navigation:q=37.422219,-122.08364&mode=d'));
Intent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_VIEW, URI);
Intent.setPackage(StringToJString('com.google.android.apps.maps'));
if Intent.resolveActivity(TAndroidHelper.Context.getPackageManager) <> nil then
TAndroidHelper.Context.startActivity(Intent);
i.e. using queryIntentActivities
isn't really necessary, unless you actually want to see which activities can handle the intent. URI
is of type: Jnet_Uri
If you want to query other packages, presumably you will need to have corresponding entries for them in the <queries>
tag