2016-10-01
10:43 AM
由於 Android N 加入了 intent 開啟檔案的權限判斷
所有使用 file:// 開頭的 uri 將會出現 FileUriExposedException
必須改為使用 content:// 開頭的 uri
也就是會用到 FileProvider
以下將以點擊通知開啟外部檔案為範例說明須修改的部分
首先在 res/xml 內建立一個 file_paths.xml 的檔案(名稱自訂)
程式碼範例
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="folderName" path="."/>
</paths>
// external-path: 等同於 Environment.getExternalStorageDirectory()
// name="folderName": 任意名稱 點擊後顯示的路徑資料夾名稱
// path=".": 實際要分享權限的資料夾路徑 使用 "." 代表根目錄
建立完成後再到 AndroidManifest.xml 加入 porvider 節點
<application>
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="your.package.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
...
</application>
接著建立 Uri Intent
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
File file = new File(dir, filename);
// API 24 之前使用的方式 會出現 FileUriExposedException
// Uri.fromFile(file)
// API 24 使用的方式
Uri uri = FileProvider.getUriForFile(getActivity(), "your.package.name.fileprovider", file);
intent.setDataAndType(uri, MimeTypeMap.getSingleton().getMimeTypeFromExtension("html"));
int flags = PendingIntent.FLAG_UPDATE_CURRENT;
PendingIntent pIntent = PendingIntent.getActivity(getActivity(), REQEUST_CODE, intent, flags);
// 取得系統的通知服務
NotificationManagerCompat notificationManager = NotificationManagerCompat.from( getActivity() );
// 建立通知
final Notification notification = new NotificationCompat.Builder( getActivity() )
.setSmallIcon( R.drawable.ic_notification )
.setLargeIcon( BitmapFactory.decodeResource(getResources(), R.drawable.ic_notification_large) )
.setContentTitle( notificationTitle )
.setContentText( filename )
.setContentIntent(pIntent)
.setOngoing(false)
.setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
.setPriority(Notification.PRIORITY_MAX)
.build();
// 發送通知
notificationManager.notify(NID, notification);
各項資料連結
Android - FileProvider
No comments:
Post a Comment