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

Android 从另一个应用程序在Osmand中打开gpx文件,android,osmand,Android,Osmand,我有一个Android应用程序,它基本上存储了用户手机上保存的gpx文件列表。当用户单击应用程序中的文件名时,它应提示用户使用手机上可用的任何路由应用程序打开gpx文件。现在我正在测试在Osmand中打开文件。问题是,Osmand正在打开,但随后立即崩溃 尝试打开文件的代码如下: File gpxFile = new File(Path); Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_

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

尝试打开文件的代码如下:

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>

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

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
(我不知道Osmand是否也需要写权限。你也可以尝试添加:FLAG\u GRANT\u write\u URI\u PERMISSION)

我还建议仔细检查filepath.xml(在“xml”资源目录中)中的文件提供程序配置。可能是这样的:

<paths>
    <files-path path="images/" name="myimages" />
</paths>
//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);
}

e、 文件路径属性是否指向正确的目录?该目录中是否有所需的gpx文件?()

要记住的另一件事是provider元素中的authority字符串在设备上必须是唯一的。因此,在AndroidManifest的这一部分中,请确保已将“com.example.myapp.fileprovider”替换为应用程序特有的内容:

<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是否为此崩溃写入堆栈跟踪

---2017年8月17日编辑---

只是想在这个答案的主体中添加一些细节:正如A.M.在下面的评论中所证明和描述的那样,实际的修复方法是通过在循环中反复调用context.grantUriPermission,显式地向设备上的多个特定包授予必要的权限,类似这样:

<paths>
    <files-path path="images/" name="myimages" />
</paths>
//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);
}
//为所有能够处理给定意图的应用授予权限
List resinfo List=context.getPackageManager().queryInputActivities(intent,PackageManager.MATCH_DEFAULT_仅限);
对于(ResolveInfo ResolveInfo:ResInfo列表){
字符串packageName=resolveInfo.activityInfo.packageName;
grantUriPermission(packageName、uri、Intent.FLAG\u GRANT\u READ\u uri\u PERMISSION);
}
此方法在此处有详细说明:


调用grantUriPermission(而不仅仅是依赖intent.addFlags(intent.FLAG\u GRANT\u READ\u URI\u PERMISSION))的需要似乎取决于设备上安装的Android平台版本。这里的一份问题报告对此进行了描述:

谢谢您的回答,我已经检查了您的所有建议,似乎一切正常,但仍然不起作用。这些文件肯定会被保存,因为我的应用程序也会打开它们,并在地图上显示路线,而且效果很好。只有当我单击按钮在osmand中打开它们时,osmand才会崩溃。有趣。Osmand在LogCat崩溃时是否将任何内容记录到LogCat?感谢您提供的堆栈跟踪。通过调用context.grantUriPermission()来授予权限是否有帮助?他们在这个答案中详细说明了如何做到这一点:我在你的链接中使用了第二个选项,为所有能够处理意图的应用程序授予权限,现在它可以工作了。非常感谢你!嘿,太好了。很高兴听到你成功了。