简体   繁体   中英

Getting FileNotFoundException When Trying to Share MP3 File Using FileProvider

I'm trying to use a FileProvider to share an MP3 file stored in the raw folder of my app's internal storage and let a user use an audio-listening app of their choice to open the shared MP3 file.

However, with my code as written, I get a FileNotFoundException when I try to execute the intent with the content URI attached as data. This leads to everything else about the FileProvider system failing.

I created a MediaPlayer and had it open the MP3 file I want to share without a problem, so I know that the file exists and that my app is able to access it.

When debugging, I noticed that the content URI's path seems to get rid of the /files/ directory even though it's in the File that I use getUriFromFile on:

meditationFile: /data/user/0/com.example.selfcareapplication/files/raw/breathing_meditation.mp3

meditationFileContentUri: content://com.example.selfcareapplication.fileprovider/raw/breathing_meditation.mp3

Here is my code in my manifest file:

<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>

Here is the code where I try to use the FileProvider:

        Intent openMeditationFileIntent = new Intent(Intent.ACTION_VIEW);
        File meditationPath = new File(this.getFilesDir(), "raw");
        File meditationFile = new File(meditationPath, "breathing_meditation.mp3");

        Uri meditationFileContentUri = FileProvider.getUriForFile(this.getApplicationContext(), "com.example.selfcareapplication.fileprovider", meditationFile);
        openMeditationFileIntent.setData(meditationFileContentUri);
        openMeditationFileIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        if(openMeditationFileIntent.resolveActivity(getPackageManager()) != null) {
            startActivity(openMeditationFileIntent);
        } else {
            Log.d(LOG_TAG, "Could not resolve activity");
        }

Here is the log I get when I try to start the intent with the content URI attached:

2019-04-06 11:45:35.709 4972-4972/? D/MusicLifecycle: com.google.android.music.ui.playback.AudioPreviewActivity generated event: Activity created
2019-04-06 11:45:35.752 4972-4972/? W/MediaPlayer: Couldn't open content://com.example.selfcareapplication.fileprovider/raw/breathing_meditation.mp3: java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
2019-04-06 11:45:35.761 1844-2504/? W/ActivityManager: Permission Denial: opening provider android.support.v4.content.FileProvider from (null) (pid=1694, uid=1013) that is not exported from UID 10092
2019-04-06 11:45:35.766 1694-1776/? E/MediaPlayerService: Couldn't open fd for content://com.example.selfcareapplication.fileprovider/raw/breathing_meditation.mp3
2019-04-06 11:45:35.766 4972-4972/? E/MediaPlayerNative: Unable to create media player
2019-04-06 11:45:35.768 4972-4972/? D/AudioPreviewActivity: Failed to open file: java.io.IOException: setDataSource failed.: status=0x80000000
2019-04-06 11:45:35.810 1584-1626/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 376832
2019-04-06 11:45:35.818 1584-1626/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 376832
2019-04-06 11:45:35.820 1584-1626/? D/gralloc_ranchu: gralloc_alloc: Creating ashmem region of size 376832
2019-04-06 11:45:35.847 4972-4999/? D/EGL_emulation: eglMakeCurrent: 0xea7c5e60: ver 2 0 (tinfo 0xea7b1a10)
2019-04-06 11:45:35.901 4972-4972/? D/MusicLifecycle: com.google.android.music.ui.MusicUrlHandlerActivity generated event: Activity stopped
2019-04-06 11:45:35.931 4972-4972/? D/MusicLifecycle: com.google.android.music.ui.MusicUrlHandlerActivity generated event: Activity destroyed
2019-04-06 11:45:35.939 1684-2170/? D/gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
2019-04-06 11:45:35.941 1684-2170/? D/gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
2019-04-06 11:45:35.943 1684-2170/? D/gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
2019-04-06 11:45:35.944 1684-2170/? D/gralloc_ranchu: gralloc_unregister_buffer: exiting HostConnection (is buffer-handling thread)
2019-04-06 11:45:35.968 1844-3656/? I/MediaFocusControl: abandonAudioFocus() from uid/pid 10069/4972 clientId=android.media.AudioManager@32b5d4dcom.google.android.music.ui.playback.AudioPreviewActivity@6726002
2019-04-06 11:45:35.969 4972-4972/? D/MusicLifecycle: com.google.android.music.ui.playback.AudioPreviewActivity generated event: Activity destroyed
2019-04-06 11:45:36.091 1844-2247/? I/GnssLocationProvider: WakeLock acquired by sendMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@9a951f4)
2019-04-06 11:45:36.092 1844-1857/? I/GnssLocationProvider: WakeLock released by handleMessage(REPORT_SV_STATUS, 0, com.android.server.location.GnssLocationProvider$SvStatusInfo@9a951f4)
2019-04-06 11:45:36.175 4775-4775/? E/GoogleTagManager: Invalid macro: _gtm.loadEventEnabled
2019-04-06 11:45:36.319 1844-1857/? E/memtrack: Couldn't load memtrack module
2019-04-06 11:45:36.319 1844-1857/? W/android.os.Debug: failed to get memory consumption info: -1
2019-04-06 11:45:36.419 4775-5006/? E/GoogleTagManager: Invalid macro: _gtm.loadEventEnabled
2019-04-06 11:45:36.487 4775-4829/? I/MediaStoreImporter: Update: incremental Success: true Added music: 0 Updated music: 0 Deleted music: 0 Created playlists: 0 Updated playlists: 0 Deleted playlists: 0 Inserted playlist items: 0 Deleted playlist items: 0 Removed orphaned playlist items: 0 Total item count: 0
2019-04-06 11:45:36.491 4775-4775/? D/MusicLifecycle: com.google.android.music.download.EncapsulatedBroadcastReceiver$1 generated event: Broadcast received with context com.google.android.music.ui.PhoneMusicApplication@a0c548d and intent Intent { act=com.google.android.music.IMPORT_COMPLETE flg=0x10 }
2019-04-06 11:45:36.609 4775-5008/? E/GoogleTagManager: Invalid macro: _gtm.loadEventEnabled
2019-04-06 11:45:36.637 4775-5000/? E/GoogleTagManager: Unsupported Value Escaping: 3
2019-04-06 11:45:36.752 1844-1955/? E/TaskPersister: File error accessing recents directory (directory doesn't exist?).
2019-04-06 11:45:36.684 4775-5000/? E/GoogleTagManager: Unsupported Value Escaping: 3

I created /raw directory in /res and copied the .mp3 file there

That is on your development machine.

What exactly is the difference between creating a raw/ directory and creating a raw resource if you don't mind my asking?

The difference is that getFilesDir() is referring to locations on the Android device. The raw/ directory that you created is on your development machine.

Doesn't moving a file into the /res/raw folder turn it into a raw resource that you can reference with R.raw?

Yes. However, that is not what your code is doing. Your code is attempting to reference it using File . Raw resources are files on your development machine. They are not files on the device.

You need to copy the raw resource ( getResources().openRawResource() , etc.) to a file, which you can then share using FileProvider .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM