Saving photos and videos using Android FileProvider to the gallery

杀马特。学长 韩版系。学妹 提交于 2021-02-19 06:54:06

问题


My application (using SDK less than 24) can take photos and video using the camera. The photos and videos can be viewed in the gallery outside the app. SDK 24 and above requires FileProvider to create the uri for saving the photo or video to the gallery.

Prior to SDK 24 I would use a uri and an intent to take a photo:

private void openCameraForResult(int requestCode){
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    picturesDirectoryPhotoFileName = nextFileName();
    File photoFile = makePicturesPhotoFile();
    Uri uri = Uri.fromFile(photoFile);
    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, requestCode);
}

private File makePicturesPhotoFile() {
    File photoGallery = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File media = new File(photoGallery, picturesDirectoryPhotoFileName);

    return media;
}

Using SDK 24 and higher an exception occurs:

Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/126cfd69-59c6-4534-9b2e-4af9753d3643.jpg exposed beyond app through ClipData.Item.getUri()

I want to achieve the same (without the exception) using FileProvider. The implementation below can take a photo but the it does not appear in the gallery. I want to know what I am doing wrong.

AndroidManifest.xml:

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="Pictures" path="Pictures"/>
    <external-path name="Movies" path="Movies"/>
</paths>

Take a photo:

private void openCameraForResult(int requestCode){
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    picturesDirectoryPhotoFileName = nextFileName();
    File photoFile = makePicturesPhotoFile();
    getDependencyService().getLogger().debug(photoFile.getAbsolutePath());
    Uri uri = fileProviderUri.makeUriUsingSdkVersion(photoFile);
    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
    startActivityForResult(intent, requestCode);
}

Make Uri

private static final String AUTHORITY_FORMAT = "%s.fileprovider";

public  Uri makeUriUsingSdkVersion(File file) {
    Uri uri;

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
        uri = Uri.fromFile(file);
    } else {
        String packageName = getApplicationContext().getPackageName();
        String authority = String.format(Locale.getDefault(), AUTHORITY_FORMAT, packageName);
        uri = getUriForFile(getApplicationContext(), authority, file);
    }

    return uri;
}

回答1:


The photo appears in the gallery on a GT-I9300 Galaxy S3 so I know the code works on that device. On a Galaxy 7 the photo does not appear in the gallery until the phone is switched on and off.

After many days of research, the answer is to update the gallery using a media scan on the file. Creating a photo in the PICTURES directory is not enough. Here is a class that scans a single file:

import android.app.Activity;
import android.media.MediaScannerConnection;
import android.net.Uri;

import java.io.File;

class Gallery implements IGallery {

    private Activity activity;

    public Gallery(Activity activity) {
        this.activity = activity;
    }

    @Override
    public void scanFile(File file) {
        if(activity == null || file == null) {
            return;
        }

        MediaScannerConnection.scanFile(activity,
                new String[] { file.getAbsolutePath() }, null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    public void onScanCompleted(String path, Uri uri) {
                    }
                });
    }

}


来源:https://stackoverflow.com/questions/43247674/saving-photos-and-videos-using-android-fileprovider-to-the-gallery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!