package com.rngrp; import java.io.InputStream; import java.io.IOException; import java.io.FileNotFoundException; import java.io.OutputStream; import java.io.FileOutputStream; import java.io.File; import java.util.Date; import java.util.Random; import android.content.ContentUris; import android.content.Context; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.database.Cursor; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.Arguments; public class GRP extends ReactContextBaseJavaModule { public GRP(ReactApplicationContext reactContext) { super(reactContext); } @Override public String getName() { return "GRP"; } private WritableMap makeErrorPayload(Exception ex) { WritableMap error = Arguments.createMap(); error.putString("message", ex.getMessage()); return error; } @ReactMethod public void getRealPathFromURI(String uriString, Callback callback) { Uri uri = Uri.parse(uriString); try { Context context = getReactApplicationContext(); final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { if (isMediaDocument(uri)) { // http://www.banbaise.com/archives/745 final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; Uri contentUri = null; if ("image".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; } else if ("video".equals(type)) { contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; } else if ("audio".equals(type)) { contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; } final String selection = "_id=?"; final String[] selectionArgs = new String[] { split[1] }; callback.invoke(null, getDataColumn(context, contentUri, selection, selectionArgs)); } else if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); if (id.startsWith("raw:")) { callback.invoke(null, id.replaceFirst("raw:", "")); } else { String[] contentUriPrefixesToTry = new String[]{ "content://downloads/public_downloads", "content://downloads/my_downloads", "content://downloads/all_downloads" }; String path = null; for (String contentUriPrefix : contentUriPrefixesToTry) { Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id)); try { path = getDataColumn(context, contentUri, null, null); if (path != null) { break; } } catch (Exception e) {} } if (path == null) { long millis = System.currentTimeMillis(); String datetime = new Date().toString(); datetime = datetime.replace(" ", ""); datetime = datetime.replace(":", ""); final String displayName = random() + "_" + datetime + "_" + millis; path = writeFile(context, uri, displayName.replace(".", "")); } callback.invoke(null, path); } } else if (isExternalStorageDocument(uri)) { final String docId = DocumentsContract.getDocumentId(uri); final String[] split = docId.split(":"); final String type = split[0]; if ("primary".equalsIgnoreCase(type)) { callback.invoke(null, Environment.getExternalStorageDirectory() + "/" + split[1]); } else { String[] proj = {MediaStore.Images.Media.DATA}; Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(column_index); cursor.close(); callback.invoke(null, path); } } } else if ("content".equalsIgnoreCase(uri.getScheme())) { callback.invoke(null,getDataColumn(context, uri, null, null)); } else if ("file".equalsIgnoreCase(uri.getScheme())) { callback.invoke(null, uri.getPath()); } } catch (Exception ex) { ex.printStackTrace(); callback.invoke(makeErrorPayload(ex)); } } public static String random() { Random generator = new Random(); StringBuilder randomStringBuilder = new StringBuilder(); int randomLength = generator.nextInt(10); char tempChar; for (int i = 0; i < randomLength; i++){ tempChar = (char) (generator.nextInt(96) + 32); randomStringBuilder.append(tempChar); } return randomStringBuilder.toString(); } public static boolean isMediaDocument(Uri uri) { return "com.android.providers.media.documents".equals(uri.getAuthority()); } public static boolean isDownloadsDocument(Uri uri) { return "com.android.providers.downloads.documents".equals(uri.getAuthority()); } public static boolean isExternalStorageDocument(Uri uri) { return "com.android.externalstorage.documents".equals(uri.getAuthority()); } public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { // https://github.com/hiddentao/cordova-plugin-filepath/pull/6 Cursor cursor = null; final String[] projection = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME}; try { /* get `_data` */ cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); /* bingo! */ final String filepath = cursor.getString(column_index); return filepath; } } catch (Exception e) { if (cursor != null) { final int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME); final String displayName = cursor.getString(column_index); return writeFile(context, uri, displayName); } } finally { if (cursor != null) cursor.close(); } return null; } public static String writeFile(Context context, Uri uri, String displayName) { InputStream input = null; try { input = context.getContentResolver().openInputStream(uri); /* save stream to temp file */ try { File file = new File(context.getCacheDir(), displayName); OutputStream output = new FileOutputStream(file); try { byte[] buffer = new byte[4 * 1024]; // or other buffer size int read; while ((read = input.read(buffer)) != -1) { output.write(buffer, 0, read); } output.flush(); final String outputPath = file.getAbsolutePath(); return outputPath; } finally { output.close(); } } catch (Exception e1a) { // } finally { try { input.close(); } catch (IOException e1b) { // } } } catch (FileNotFoundException e2) { // } finally { if (input != null) { try { input.close(); } catch (IOException e3) { // } } } return null; } }