package com.wix.RNCameraKit.gallery; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.provider.MediaStore; import android.support.annotation.NonNull; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.wix.RNCameraKit.SaveImageTask; import com.wix.RNCameraKit.gallery.permission.StoragePermission; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; import java.util.HashMap; /** * Created by yedidyak on 29/06/2016. */ public class NativeGalleryModule extends ReactContextBaseJavaModule { public static final String[] ALBUMS_PROJECTION = new String[]{ MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_DISPLAY_NAME }; public static final String[] IMAGES_PROJECTION = new String[]{ MediaStore.Images.Media. _ID, MediaStore.Images.Media.SIZE, MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.TITLE, MediaStore.Images.Media.WIDTH, MediaStore.Images.Media.HEIGHT, MediaStore.Images.Media.DATA }; public static final String ALL_PHOTOS = "All Photos"; private Promise checkPermissionStatusPromise; private class Album { String name; String imageUri = null; int count = 1; public Album(String name, String uri) { this.name = name; this.imageUri = uri; } } private class AlbumList { HashMap albums = new HashMap<>(); public void addAlbum(String name, String uri) { if (!albums.containsKey(name)) { albums.put(name, new Album(name, uri)); } else { albums.get(name).count++; } } public Collection getAlbums() { return albums.values(); } } private final StoragePermission storagePermission; public NativeGalleryModule(ReactApplicationContext reactContext) { super(reactContext); storagePermission = new StoragePermission(); checkPermissionWhenActivityIsAvailable(); } private void checkPermissionWhenActivityIsAvailable() { getReactApplicationContext().addLifecycleEventListener(new LifecycleEventListener() { @Override public void onHostResume() { if (checkPermissionStatusPromise != null && getCurrentActivity() != null) { getCurrentActivity().runOnUiThread(new Runnable() { @Override public void run() { checkPermissionStatusPromise.resolve(storagePermission.checkAuthorizationStatus(getCurrentActivity())); checkPermissionStatusPromise = null; } }); } } @Override public void onHostPause() { } @Override public void onHostDestroy() { } }); } @Override public String getName() { return "NativeGalleryModule"; } @NonNull private WritableMap albumToMap(Album album) { WritableMap map = Arguments.createMap(); map.putInt("imagesCount", album.count); map.putString("albumName", album.name); map.putString("thumbUri", album.imageUri); return map; } @NonNull private AlbumList getAlbumListFromCursor(Cursor imagesCursor) { AlbumList albums = new AlbumList(); if (imagesCursor.moveToFirst()) { int bucketColumn = imagesCursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME); int uriColumn = imagesCursor.getColumnIndex(MediaStore.Images.Media.DATA); do { String name = imagesCursor.getString(bucketColumn); String uri = imagesCursor.getString(uriColumn); albums.addAlbum(name, uri); albums.addAlbum(ALL_PHOTOS, uri); } while (imagesCursor.moveToNext()); } imagesCursor.close(); return albums; } private Bitmap getThumbnail(int thumbId) { return MediaStore.Images.Thumbnails.getThumbnail( getReactApplicationContext().getContentResolver(), thumbId, MediaStore.Images.Thumbnails.MINI_KIND, null); } public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { storagePermission.onRequestPermissionsResult(requestCode, permissions, grantResults); } @ReactMethod public void checkDeviceStorageAuthorizationStatus(final Promise promise) { if (getCurrentActivity() == null) { checkPermissionStatusPromise = promise; } else { getCurrentActivity().runOnUiThread(new Runnable() { @Override public void run() { promise.resolve(storagePermission.checkAuthorizationStatus(getCurrentActivity())); } }); } } @ReactMethod public void requestDeviceStorageAuthorization(Promise promise) { storagePermission.requestAccess(getCurrentActivity(), promise); } @ReactMethod public void getAlbumsWithThumbnails(Promise promise) { Cursor imagesCursor = getReactApplicationContext().getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, ALBUMS_PROJECTION, null, null, null); AlbumList albums = getAlbumListFromCursor(imagesCursor); WritableArray arr = Arguments.createArray(); for (Album album : albums.getAlbums()) { arr.pushMap(albumToMap(album)); } WritableMap ret = Arguments.createMap(); ret.putArray("albums", arr); promise.resolve(ret); } @ReactMethod public void getImagesForUris(ReadableArray uris, Promise promise) { StringBuilder builder = new StringBuilder(); builder.append(MediaStore.Images.Media.DATA + " IN ("); for (int i=0; i