尝试使用FileProvider通过隐式意图共享MP3时获取FileNotFoundException

时间:2019-04-13 19:51:11

标签: java android filenotfoundexception android-fileprovider

我正在尝试使用getFilesDir()隐式意图将android内部文件(其根为ACTION_VIEW)中的MP3文件共享给另一个应用程序。 MP3文件最初存储在应用程序的/raw文件夹中,但是我将其复制到了应用程序的内部文件中。

我已使用file.exists()验证文件存在。但是,当我使用FileProvider构造文件的内容URI并将该内容URI用作隐式意图中的数据时,尝试启动隐式意图时会得到FileNotFoundException: open failed: ENOTDIR

我尝试更改FileProvider的权限,并且研究了Android's specifications for sharing a media file using intents,并确保我的隐式意图符合标准。

以下是发生错误时日志窗口的输出:

23349-23349/? D/MusicLifecycle: com.google.android.music.ui.playback.AudioPreviewActivity generated event: Activity created
23349-23349/? W/MediaPlayer: Couldn't open content://com.example.selfcareapplication.fileprovider/meditation-files/breathing-meditation.mp3: java.io.FileNotFoundException: open failed: ENOTDIR (Not a directory)
1844-2784/? W/ActivityManager: Permission Denial: opening provider android.support.v4.content.FileProvider from (null) (pid=1694, uid=1013) that is not exported from UID 10099
1694-2151/? E/MediaPlayerService: Couldn't open fd for content://com.example.selfcareapplication.fileprovider/meditation-files/breathing-meditation.mp3
23349-23349/? E/MediaPlayerNative: Unable to create media player
23349-23349/? D/AudioPreviewActivity: Failed to open file: java.io.IOException: setDataSource failed.: status=0x80000000

这是我获取文件,创建FileProvider并启动意图的代码:

Intent openMeditationFileIntent = new Intent(Intent.ACTION_VIEW);
File testFile = new File(this.getFilesDir(), "meditation-files\\breathing-meditation.mp3");

//check if file was written to internal memory. It prints "FILE WAS OUTPUT!"
if(testFile.exists()) {
     Log.d(LOG_TAG, "FILE WAS OUTPUT!");
} else {
     Log.d(LOG_TAG, "FILE WAS NOT OUTPUT!!!");
}

//create content URI using FileProvider and the testFile
Uri meditationFileContentUri = FileProvider.getUriForFile(this.getApplicationContext(), "com.example.selfcareapplication.fileprovider", testFile);
openMeditationFileIntent.setDataAndType(meditationFileContentUri, "audio/*"); 
openMeditationFileIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

//try to open implicit intent using content URI as its data: 
if(openMeditationFileIntent.resolveActivity(getPackageManager()) != null) {
     startActivity(openMeditationFileIntent);
} else {
     Log.d(LOG_TAG, "Could not resolve activity");
}

这是我的清单:

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.selfcareapplication.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

这是我的file_paths.xml文件:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="meditation-files" path="meditation-files/"/>
</paths>

编辑:

我能够使它正常工作! 根据@CommonsWare的建议,我将MIME Type更改为““ audio / mpeg”“,这是MP3的MIME类型。

我还删除了路径名中的连字符。这样做似乎会导致无法将MP3文件正确写入“ getFilesDir()+“ meditationPaths”“,因为在MP3路径上检查“ file.exists()”将返回false。将路径中的“ \”更改为“ /”可以解决此问题。

也就是说,当我稍后进行一些进一步的测试时,我发现'\'和'/'都允许MP3正确编写...因此,我不确定我是第一次出什么毛病。我只建议使用“ File.separator”来确保针对程序所运行的环境自动使用正确的分隔符。

这是获取文件,创建FileProvider并启动意图的最终代码:

Intent openMeditationFileIntent = new Intent(Intent.ACTION_VIEW);
File testFile = new File(this.getFilesDir(), "meditationFiles" + Path.separator + "breathingMeditation.mp3");

//check if file was written to internal memory. It prints "FILE WAS OUTPUT!"
if(testFile.exists()) {
     Log.d(LOG_TAG, "FILE WAS OUTPUT!");
} else {
     Log.d(LOG_TAG, "FILE WAS NOT OUTPUT!!!");
}

//create content URI using FileProvider and the testFile
Uri meditationFileContentUri = FileProvider.getUriForFile(this.getApplicationContext(), "com.example.selfcareapplication.fileprovider", testFile);
openMeditationFileIntent.setDataAndType(meditationFileContentUri, "audio/mpeg"); 
openMeditationFileIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

//try to open implicit intent using content URI as its data: 
if(openMeditationFileIntent.resolveActivity(getPackageManager()) != null) {
     startActivity(openMeditationFileIntent);
} else {
     Log.d(LOG_TAG, "Could not resolve activity");
}

我还必须更改file-paths.xml文件以反映文件夹名称中的更改:

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="meditationFiles" path ="meditationFiles"/>
</paths>

0 个答案:

没有答案