从另一个应用程序打开Osmand中的gpx文件

时间:2017-08-07 06:58:40

标签: android osmand

我有一个Android应用程序,它基本上存储了保存在用户手机上的gpx文件列表。当用户点击应用程序中的文件名时,它应该提示用户打开gpx文件,其中包含手机上可用的任何路由应用程序。现在我正在测试在奥斯曼打开文件。问题是,奥斯曼德正在开放,但随后立即崩溃。

尝试打开文件的代码是:

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);

gpx文件看起来像这样:

<?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>

起初我认为gpx文件的格式有问题,但如果我手动打开Osmand并尝试使用“配置地图”导入文件 - &gt; “Gpx轨道”,轨道在地图上显示得很好,包括航点。

LE:这是我在奥斯曼试图开始时得到的错误:

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) 

1 个答案:

答案 0 :(得分:1)

Osmand是否缺少从FileProvider读取该文件的权限?换句话说,在调用startActivity之前,是否有助于在intent中授予读取权限:

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

(我不知道Osmand是否还需要写权限。您也可以尝试添加它:FLAG_GRANT_WRITE_URI_PERMISSION)。

我还建议您仔细检查filepaths.xml中的FileProvider配置(在&#39; xml&#39;资源目录中)。可能是这样的:

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

e.g。你的文件路径属性是否指向正确的目录?那个目录中是否有所需的gpx文件? (https://developer.android.com/training/secure-file-sharing/setup-sharing.html

要记住的另一件事是提供程序元素中的权限字符串在设备上必须是唯一的。因此,在AndroidManifest的这一部分中,请确保已替换&#34; com.example.myapp.fileprovider&#34;使用您的应用程序独有的东西:

<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>

如果这没有帮助,我只能建议观察设备的logcat输出,看看Osmand是否为此次崩溃写了堆栈跟踪。

---编辑08/17/2017 ---

只是将一些细节放到这个答案的正文中:作为A.M.在下面的评论中证明和描述,实际修复是通过在循环中重复调用context.grantUriPermission来明确地为设备上的多个特定包授予必要的权限,如下所示:

//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);
}

此处更详细地记录了这种方法:https://stackoverflow.com/a/18332000/3482621

调用grantUriPermission(而不是仅仅依赖于intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION))的需要似乎取决于设备上安装的Android平台版本。此处的问题报告中对此进行了描述:https://issuetracker.google.com/issues/37005552