Search code examples
androidandroid-gallerycooliris

Image in getExternalFilesDir()


I have some images stored in getExternalFilesDir() and i am trying to show those images in the android gallery (cooliris). Right now i have been doing this:

Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(imgPath,"image/*");
startActivity(intent);

But nothing happens. I have changed the setDataAndType to this:

intent.setDataAndType(Uri.fromFile(new File(imgPath)),"image/*");

This way it works, but it takes 5-10 seconds for the gallery to go from a black screen to showing my image.

Anyway to solve this or any better approach?


Solution

  • By implementing a file content provider you will be able to avoid this 5-10 second delay

    import java.io.File;
    import java.io.FileNotFoundException;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.ParcelFileDescriptor;
    
    public class FileContentProvider extends ContentProvider {
        private static final String AUTHORITY = "content://com.yourprojectinfo.fileprovider";
    
        public static Uri constructUri(String url) {
            Uri uri = Uri.parse(url);
            return uri.isAbsolute() ? uri : Uri.parse(AUTHORITY + url);
        }
    
        public static Uri constructUri(File file) {
            Uri uri = Uri.parse(file.getAbsolutePath());
            return uri.isAbsolute() ? uri : Uri.parse(AUTHORITY
                    + file.getAbsolutePath());
        }
    
        @Override
        public ParcelFileDescriptor openFile(Uri uri, String mode)
                throws FileNotFoundException {
            File file = new File(uri.getPath());
            ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file,
                    ParcelFileDescriptor.MODE_READ_ONLY);
            return parcel;
        }
    
        @Override
        public boolean onCreate() {
            return true;
        }
    
        @Override
        public int delete(Uri uri, String s, String[] as) {
            throw new UnsupportedOperationException(
                    "Not supported by this provider");
        }
    
        @Override
        public String getType(Uri uri) {
            return "image/jpeg";
        }
    
        @Override
        public Uri insert(Uri uri, ContentValues contentvalues) {
            throw new UnsupportedOperationException(
                    "Not supported by this provider");
        }
    
        @Override
        public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
            throw new UnsupportedOperationException(
                    "Not supported by this provider");
        }
    
        @Override
        public int update(Uri uri, ContentValues contentvalues, String s,
                String[] as) {
            throw new UnsupportedOperationException(
                    "Not supported by this provider");
        }
    
    }
    

    Then you can call

    Uri uri = FileContentProvider.constructUri(file);
    Intent intent = new Intent();
    intent.setAction(android.content.Intent.ACTION_VIEW);
    intent.setDataAndType(uri,"image/*");
    startActivity(intent);
    

    This is a strange workaround but I think it has something to do with how android opens images using a URI. Their openFile(Uri uri, String mode) method is wrong / broken / can't resolve the URI properly.. I'm not really 100% sure though but I found this workaround to be effective.

    don't forget to register to provider in the manifest