lbry-android/src/main/java/io/lbry/browser/reactmodules/GalleryModule.java
2019-08-15 06:08:53 +01:00

306 lines
11 KiB
Java

package io.lbry.browser.reactmodules;
import android.content.Context;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.Manifest;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import com.facebook.react.bridge.Arguments;
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.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import io.lbry.browser.MainActivity;
import io.lbry.browser.Utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
public class GalleryModule extends ReactContextBaseJavaModule {
private Context context;
public GalleryModule(ReactApplicationContext reactContext) {
super(reactContext);
this.context = reactContext;
}
@Override
public String getName() {
return "Gallery";
}
@ReactMethod
public void getVideos(Promise promise) {
WritableArray items = Arguments.createArray();
List<GalleryItem> videos = loadVideos();
for (int i = 0; i < videos.size(); i++) {
items.pushMap(videos.get(i).toMap());
}
promise.resolve(items);
}
@ReactMethod
public void getThumbnailPath(Promise promise) {
if (context != null) {
File cacheDir = context.getExternalCacheDir();
String thumbnailPath = String.format("%s/thumbnails", cacheDir.getAbsolutePath());
promise.resolve(thumbnailPath);
return;
}
promise.resolve(null);
}
@ReactMethod
public void getUploadsPath(Promise promise) {
if (context != null) {
String baseFolder = Utils.getExternalStorageDir(context);
String uploadsPath = String.format("%s/LBRY/Uploads", baseFolder);
File uploadsDir = new File(uploadsPath);
if (!uploadsDir.isDirectory()) {
uploadsDir.mkdirs();
}
promise.resolve(uploadsPath);
}
promise.reject("The content could not be saved to the device. Please check your storage permissions.");
}
@ReactMethod
public void createVideoThumbnail(String targetId, String filePath, Promise promise) {
(new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... param) {
String thumbnailPath = null;
if (context != null) {
Bitmap thumbnail = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MINI_KIND);
File cacheDir = context.getExternalCacheDir();
thumbnailPath = String.format("%s/thumbnails/%s.png", cacheDir.getAbsolutePath(), targetId);
File file = new File(thumbnailPath);
try (FileOutputStream os = new FileOutputStream(thumbnailPath)) {
thumbnail.compress(Bitmap.CompressFormat.PNG, 80, os);
os.close();
} catch (IOException ex) {
promise.reject("Could not create a thumbnail for the video");
return null;
}
}
return thumbnailPath;
}
public void onPostExecute(String thumbnailPath) {
if (thumbnailPath != null && thumbnailPath.trim().length() > 0) {
promise.resolve(thumbnailPath);
}
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ReactMethod
public void createImageThumbnail(String targetId, String filePath, Promise promise) {
(new AsyncTask<Void, Void, String>() {
protected String doInBackground(Void... param) {
String thumbnailPath = null;
FileOutputStream os = null;
try {
Bitmap source = BitmapFactory.decodeFile(filePath);
// MINI_KIND dimensions
Bitmap thumbnail = Bitmap.createScaledBitmap(source, 512, 384, false);
if (context != null) {
File cacheDir = context.getExternalCacheDir();
thumbnailPath = String.format("%s/thumbnails/%s.png", cacheDir.getAbsolutePath(), targetId);
os = new FileOutputStream(thumbnailPath);
if (thumbnail != null) {
thumbnail.compress(Bitmap.CompressFormat.PNG, 80, os);
}
os.close();
}
} catch (IOException ex) {
promise.reject("Could not create a thumbnail for the image");
return null;
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ex) {
// ignoe
}
}
}
return thumbnailPath;
}
public void onPostExecute(String thumbnailPath) {
if (thumbnailPath != null && thumbnailPath.trim().length() > 0) {
promise.resolve(thumbnailPath);
}
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private List<GalleryItem> loadVideos() {
String[] projection = {
MediaStore.MediaColumns._ID,
MediaStore.MediaColumns.DATA,
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE,
MediaStore.Video.Media.DURATION
};
List<String> ids = new ArrayList<String>();
List<GalleryItem> items = new ArrayList<GalleryItem>();
Cursor cursor = context.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, null, null,
String.format("%s DESC", MediaStore.MediaColumns.DATE_MODIFIED));
while (cursor.moveToNext()) {
int idColumn = cursor.getColumnIndex(MediaStore.MediaColumns._ID);
int nameColumn = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
int typeColumn = cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE);
int pathColumn = cursor.getColumnIndex(MediaStore.MediaColumns.DATA);
int durationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
String id = cursor.getString(idColumn);
GalleryItem item = new GalleryItem();
item.setId(id);
item.setName(cursor.getString(nameColumn));
item.setType(cursor.getString(typeColumn));
item.setFilePath(cursor.getString(pathColumn));
items.add(item);
ids.add(id);
}
checkThumbnails(ids);
return items;
}
private void checkThumbnails(final List<String> ids) {
(new AsyncTask<Void, Void, Void>() {
protected Void doInBackground(Void... param) {
if (context != null) {
ContentResolver resolver = context.getContentResolver();
for (int i = 0; i < ids.size(); i++) {
String id = ids.get(i);
File cacheDir = context.getExternalCacheDir();
File thumbnailsDir = new File(String.format("%s/thumbnails", cacheDir.getAbsolutePath()));
if (!thumbnailsDir.isDirectory()) {
thumbnailsDir.mkdirs();
}
String thumbnailPath = String.format("%s/%s.png", thumbnailsDir.getAbsolutePath(), id);
File file = new File(thumbnailPath);
if (!file.exists()) {
// save the thumbnail to the path
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap thumbnail = MediaStore.Video.Thumbnails.getThumbnail(
resolver, Long.parseLong(id), MediaStore.Video.Thumbnails.MINI_KIND, options);
if (thumbnail != null) {
try (FileOutputStream os = new FileOutputStream(thumbnailPath)) {
thumbnail.compress(Bitmap.CompressFormat.PNG, 80, os);
} catch (IOException ex) {
// skip
}
}
}
if (file.exists() && file.length() > 0 && GalleryModule.this.context != null) {
WritableMap params = Arguments.createMap();
params.putString("id", id);
((ReactApplicationContext) GalleryModule.this.context).getJSModule(
DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("onGalleryThumbnailChecked", params);
}
}
}
return null;
}
}).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
private static class GalleryItem {
private String id;
private int duration;
private String filePath;
private String name;
private String type;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public WritableMap toMap() {
WritableMap map = Arguments.createMap();
map.putString("id", id);
map.putString("name", name);
map.putString("filePath", filePath);
map.putString("type", type);
map.putInt("duration", duration);
return map;
}
}
@ReactMethod
public void canUseCamera(final Promise promise) {
promise.resolve(MainActivity.hasPermission(Manifest.permission.CAMERA, MainActivity.getActivity()));
}
}