2017-08-07 107 views
5

我有一个基本上存储在用户手机上保存的gpx文件列表的Android应用程序。当用户点击应用程序中的文件名时,它应该提示用户使用他手机上的任何路由应用程序打开gpx文件。现在我正在用Osmand打开文件进行测试。问题是,奥斯曼德正在开放,但随后立即崩溃。从另一个应用程序在Osmand中打开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并尝试使用“配置地图” - >“Gpx轨道”导入文件,则轨道在地图上显示得很好,包括航点。

LE:这是我的错误时Osmand试图启动:

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

不Osmand缺乏读取来自FileProvider该文件的权限?换句话说,它帮助呼叫给startActivity之前授予的意图读取权限:

intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

(我不知道是否Osmand也需要写权限您可以尝试补充说,还有:FLAG_GRANT_WRITE_URI_PERMISSION) 。

我还建议仔细检查FilePaths.xml中的FileProvider配置(在'xml'资源目录中)。可能是这样的:

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

例如您的文件路径属性是否指向正确的目录?该目录中的所需gpx文件是? (https://developer.android.com/training/secure-file-sharing/setup-sharing.html

要记住的另一件事是提供者元素中的权限字符串在设备上必须是唯一的。所以,在你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日---

只是把一些细节到这个答案的身体:为上午证明和描述在下面的意见,实际的修复是在循环中调用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

+0

感谢您的回答,我已检查了所有建议,并且所有内容似乎都是按顺序排列的,但仍然无法正常工作。这些文件是绝对保存的,因为我的应用程序也打开它们并在地图上显示路线,而且这种方式工作得很好。只有当我点击按钮在osmand中打开它们,然后osmand崩溃。 –

+0

有趣。当它崩溃时,Osmand会记录LogCat的任何内容吗? –

+0

我添加了Osmand试图打开时收到的错误 –

相关问题