在Android应用程序中访问声音资产时,如何区分文件URI和内容URI
我是一名Android初学者工程师。我们观察到多起与无法访问声音资产有关的崩溃,我想知道如何最好地访问私人声音文件。观察到的一些堆栈轨迹如下所示:在Android应用程序中访问声音资产时,如何区分文件URI和内容URI,android,crash,android-notifications,android-fileprovider,Android,Crash,Android Notifications,Android Fileprovider,我是一名Android初学者工程师。我们观察到多起与无法访问声音资产有关的崩溃,我想知道如何最好地访问私人声音文件。观察到的一些堆栈轨迹如下所示: Caused by android.os.FileUriExposedException: file:///storage/emulated/0/Download/Girl%20on%20fire.mp4 exposed beyond app through Notification.sound at android.os.Strict
Caused by android.os.FileUriExposedException: file:///storage/emulated/0/Download/Girl%20on%20fire.mp4 exposed beyond app through Notification.sound
at android.os.StrictMode.onFileUriExposed + 1799(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed + 2354(Uri.java:2354)
at android.app.NotificationManager.notifyAsUser + 303(NotificationManager.java:303)
at android.app.NotificationManager.notify + 287(NotificationManager.java:287)
at android.app.NotificationManager.notify + 271(NotificationManager.java:271)
及
在这两种情况下,应用程序在创建通知时无法访问声音文件。我已经阅读了以下关于设置文件提供程序的文章。我猜外部存储是指设备上的文件系统,但我不知道这是否正确
Caused by android.os.FileUriExposedException: file:///storage/emulated/0/Download/Girl%20on%20fire.mp4 exposed beyond app through Notification.sound
at android.os.StrictMode.onFileUriExposed + 1799(StrictMode.java:1799)
at android.net.Uri.checkFileUriExposed + 2354(Uri.java:2354)
at android.app.NotificationManager.notifyAsUser + 303(NotificationManager.java:303)
at android.app.NotificationManager.notify + 287(NotificationManager.java:287)
at android.app.NotificationManager.notify + 271(NotificationManager.java:271)
file://
开头的URI和content://
开头的URI。如果URI字符串以file://
开头,那么我可以使用第三个链接将其转换为内容URI。如果文件URI已经以内容开头://
,我需要做什么李>
这是我目前的逻辑:
NotificationCompat.Builder builder = getBuilder(); // Helper function to initialize the builder
String defaultRingTone = "android.resource://" + BuildConfig.APPLICATION_ID + "/" + R.raw.default;
SharedPreferences preferences = getSharedPreferences(); // Returns an instance of shared preference.
Uri soundUri = Uri.parse(sharedPreferences.getString(PREF_NOTIFICATIONS_TONE,
DEFAULT_TONE)); // PREF_NOTIFICATIONS_TONE points to the string based path.
context.grantUriPermission(context.getPackageName(), soundUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
builder.setSound(soundUri);
. . . . Use the NotificationManager to render the notification . . .
期望的行为
我希望通知以声音呈现,而不是崩溃。@commonware我已经设置了如下读取权限
context.grantUriPermission(context.getPackageName(),soundUri,Intent.FLAG\u GRANT\u read\u URI\u PERMISSION)代码>。这不正确吗?@commonware当我们需要将路径从文件://
转换为内容://
时,我们可以使用文件提供程序#getUriForFile
进行转换。当路径是内容://
路径时,我们还会这样做吗?“这不正确吗?”——这将授予应用程序阅读自己内容的权利。那不是你的问题。您的问题是,系统UI缺少读取您的内容的权限。“当路径是content://路径时,我们是否仍然这样做?”--否。但是,没有安全稳定的方法授予系统UI对任何安全的内容://
Uri
的权限,无论它是您自己的(例如,文件提供者
)还是来自第三方的(例如您的content://media/external/audio
1)@commonware我仍然需要实现FileProvider API,对吗?