Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open image in gallery with Android Nougat

I want to open a saved image in gallery on Android Nougat but what I get is a black gallery page with message "Can't load the photo".

That's my code:

Manifest

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        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 xmlns:android="http://schemas.android.com/apk/res/android">
 <external-path name="external_files" path="."/>
</paths>

Path generated in DrawView

public static boolean save(Bitmap bitmap){
    Date now = new Date();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy'_'HH:mm");

    File folder = new File(Environment.getExternalStorageDirectory() +
            File.separator + "Crash");
    if (!folder.exists()) {
        folder.mkdirs();
    }

    FileOutputStream fos = null;
    try {
        lastImagePath = new File(Environment.getExternalStorageDirectory().toString() + "/Crash/" + simpleDateFormat.format(now) + ".jpg");
        fos = new FileOutputStream(lastImagePath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);

        fos.flush();
        fos.close();
        fos = null;
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }

    finally {
        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {}
        }
    }
}

Open Image Listener

    private class OpenImageListener implements View.OnClickListener{

    @Override
    public void onClick(View v) {
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.N){
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.parse("file://" + DrawView.getLastImagePath().getAbsolutePath()), "image/*");
            startActivity(intent);
        } else {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);
            Uri photoUri = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", DrawView.getLastImagePath());
            intent.setData(photoUri);
            startActivity(intent);
        }
    }
}

Maybe I generate a wrong path for the image, but with old version it works (I tried on Marshmallow and works great).

Can someone help me? Thanks.

like image 963
Vito L. Avatar asked Mar 09 '17 18:03

Vito L.


1 Answers

In your else block in onClick(), after calling setData() on your Intent to set the Uri, call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on the Intent.

As it stands, the other app has no rights to work with the content identified by the Uri. Adding FLAG_GRANT_READ_URI_PERMISSION does this.

This is covered in the FileProvider documentation, along with modern books on Android app development.

like image 109
CommonsWare Avatar answered Oct 14 '22 10:10

CommonsWare