2017-08-07 156 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試圖打開時收到的錯誤 –

相關問題