Opening a gpx file in Osmand, from another application

I have an Android app that basically stores a list of gpx files that are saved on the user's phone. When the user clicks on the file name in the application, he should ask the user to open the gpx file with any routing applications available on his phone. Now I'm testing by opening a file in Osmand. The problem is that Osmand opens, but then collapses.

The code that tries to open the file is as follows:

File gpxFile = new File(Path); Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_VIEW); Uri gpxUri = FileProvider.getUriForFile(view.getContext(), AUTHORITY, gpxFile); intent.setDataAndType(gpxUri, "application/gpx+xml"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); 

All gpx files look like this:

 <?xml version="1.0"?> <gpx creator="{CREATOR}" version="1.1" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"> <wpt lat="{LAT_1}" lon="{LON_1}"> <name>{WPT_NAME_1}</name> </wpt> ... <wpt lat="{LAT_N}" lon="{LON_N}"> <name>{WPT_NAME_N}</name> </wpt> <trk> <name>{TRACK_NAME}</name> <trkseg> <trkpt lat="{LAT_1}" lon="{LON_1}"></trkpt> ... <trkpt lat="{LAT_N}" lon="{LON_N}"></trkpt> </trkseg> </trk> </gpx> 

At first I thought it was something wrong with the gpx file format, but if I open Osmand manually and try to import the file using "Configure map" → "Gpx track", maps, including waypoints.

LE: This is the error I get when Osmand tries to start:

 08-16 17:28:00.524 5681-5762/? E/net.osmand: RenderingRuleProperty Rendering parse in strokeWidth_2 08-16 17:28:00.524 5681-5762/? E/net.osmand: RenderingRuleProperty Rendering parse in strokeWidth_2 08-16 17:28:01.259 5681-5681/? E/AndroidRuntime: FATAL EXCEPTION: main Process: net.osmand, PID: 5681 java.lang.RuntimeException: Unable to resume activity {net.osmand/net.osmand.plus.activities.MapActivity}: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{3ddadf4 5681:net.osmand/u0a203} (pid=5681, uid=10203) that is not exported from uid 10275 at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3788) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2991) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) Caused by: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{3ddadf4 5681:net.osmand/u0a203} (pid=5681, uid=10203) that is not exported from uid 10275 at android.os.Parcel.readException(Parcel.java:1693) at android.os.Parcel.readException(Parcel.java:1646) at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:4861) at android.app.ActivityThread.acquireProvider(ActivityThread.java:5958) at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2452) at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1521) at android.content.ContentResolver.query(ContentResolver.java:520) at android.content.ContentResolver.query(ContentResolver.java:478) at net.osmand.plus.helpers.GpxImportHelper.getNameFromContentUri(GpxImportHelper.java:108) at net.osmand.plus.helpers.GpxImportHelper.handleContentImport(GpxImportHelper.java:69) at net.osmand.plus.activities.MapActivity.onResume(MapActivity.java:617) at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1277) at android.app.Activity.performResume(Activity.java:7058) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3765) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3828) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2991) at android.app.ActivityThread.-wrap14(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 
+5
source share
1 answer

Osmand doesn't have permission to read this file from FileProvider? In other words, does it help to allow reading in intent before calling the startActivity function:

 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

(I don't know if Osmand needs write permissions. You can also try adding this: FLAG_GRANT_WRITE_URI_PERMISSION).

I also suggest carefully checking the FileProvider configuration in the pathpaths.xml file (in the xml resource directory). Maybe something like this:

 <paths> <files-path path="images/" name="myimages" /> </paths> 

eg. Is your file path attribute a pointer to the right directory? Are the required gpx files in this directory? ( https://developer.android.com/training/secure-file-sharing/setup-sharing.html )

Another thing to keep in mind is that the credential line in the provider item must be unique on the device. So, in this part of your AndroidManifest, make sure you replace "com.example.myapp.fileprovider" with something unique to your application:

 <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.myapp.fileprovider" android:grantUriPermissions="true" android:exported="false"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider> 

If this does not help, I can only offer a look at the logcat output from the device to see if Osmand is writing a stack trace for this failure.

--- EDIT 07/08/2017 ---

Just to put some details into the essence of this answer: as AM proved and described in the comments below, the actual fix was to explicitly provide the necessary permissions for several specific packages on the device, repeatedly calling context.grantUriPermission in a loop, something like this:

 //grant permisions for all apps that can handle given intent List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } 

This approach is described in more detail here: fooobar.com/questions/23855 / ...

The need to call grantUriPermission (instead of just relying on the intention .addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION)) seems to depend on the version of the Android platform installed on the device. This is described in the problem report here: https://issuetracker.google.com/issues/37005552

+1
source

Source: https://habr.com/ru/post/1270640/


All Articles