From 10bc57a2817b50746acd7e4412a3c459858dbfe6 Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Sun, 2 Sep 2018 12:03:39 -0700 Subject: [PATCH] update cordova-plugin-filepath to latest version --- package-lock.json | 8 +- package.json | 2 +- platforms/android/android.json | 2 +- .../hiddentao/cordova/filepath/FilePath.java | 866 +++++++++--------- .../android/platform_www/cordova_plugins.js | 2 +- 5 files changed, 442 insertions(+), 438 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d2569e..b2e1249 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2140,7 +2140,7 @@ }, "cordova-android": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-7.1.0.tgz", + "resolved": "http://registry.npmjs.org/cordova-android/-/cordova-android-7.1.0.tgz", "integrity": "sha1-HNNu57nRm61Q0+mEK3Mf5ZCSTdU=", "requires": { "android-versions": "1.3.0", @@ -2389,9 +2389,9 @@ "integrity": "sha1-+lnpe4zdkSYL4L7EYNuOxd6TSI8=" }, "cordova-plugin-filepath": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/cordova-plugin-filepath/-/cordova-plugin-filepath-1.3.0.tgz", - "integrity": "sha512-Dwd76FcVciSssAZ/FPfwfOlfHrmx7CAjYTNzCxeJ4NsMkCfTysCR3vHdX/03XExGi+74DImUB17uXsnyyOYnAQ==" + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/cordova-plugin-filepath/-/cordova-plugin-filepath-1.4.2.tgz", + "integrity": "sha512-6AKL6dIUkY+iOYesP+3/9LC1cxIilDIo0Hdu4tdDNM/ELIxrmxKywTqGy4x76Fv/LIl6l7g8R2tgCbBXTaBvMw==" }, "cordova-plugin-inappbrowser": { "version": "3.0.0", diff --git a/package.json b/package.json index 3fa04ae..6ea0a2f 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "cordova-plugin-file": "^6.0.1", "cordova-plugin-file-transfer": "^1.7.1", "cordova-plugin-filechooser": "^1.0.1", - "cordova-plugin-filepath": "^1.3.0", + "cordova-plugin-filepath": "^1.4.2", "cordova-plugin-inappbrowser": "^3.0.0", "cordova-plugin-share-content": "^1.0.0", "cordova-plugin-splashscreen": "^5.0.2", diff --git a/platforms/android/android.json b/platforms/android/android.json index cf38d64..949d248 100644 --- a/platforms/android/android.json +++ b/platforms/android/android.json @@ -434,6 +434,6 @@ "cordova-plugin-device": "2.0.2", "cordova-plugin-console": "1.1.0", "cordova-android-support-gradle-release": "1.4.4", - "cordova-plugin-filepath": "1.0.2" + "cordova-plugin-filepath": "1.4.2" } } \ No newline at end of file diff --git a/platforms/android/app/src/main/java/com/hiddentao/cordova/filepath/FilePath.java b/platforms/android/app/src/main/java/com/hiddentao/cordova/filepath/FilePath.java index 52bf946..4ad84b5 100644 --- a/platforms/android/app/src/main/java/com/hiddentao/cordova/filepath/FilePath.java +++ b/platforms/android/app/src/main/java/com/hiddentao/cordova/filepath/FilePath.java @@ -1,431 +1,435 @@ -package com.hiddentao.cordova.filepath; - - -import android.Manifest; -import android.content.ContentUris; -import android.content.Context; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.provider.OpenableColumns; -import android.util.Log; -import android.database.Cursor; -import android.os.Build; -import android.os.Environment; -import android.provider.DocumentsContract; -import android.provider.MediaStore; -import android.support.v4.app.ActivityCompat; - -import org.apache.cordova.CallbackContext; -import org.apache.cordova.CordovaInterface; -import org.apache.cordova.CordovaPlugin; -import org.apache.cordova.CordovaWebView; -import org.apache.cordova.PermissionHelper; -import org.json.JSONArray; -import org.json.JSONObject; -import org.json.JSONException; - -import java.io.FileOutputStream; -import java.io.InputStream; -import java.util.List; -import java.io.File; - -public class FilePath extends CordovaPlugin { - - private static final String TAG = "[FilePath plugin]: "; - - private static final int INVALID_ACTION_ERROR_CODE = -1; - - private static final int GET_PATH_ERROR_CODE = 0; - private static final String GET_PATH_ERROR_ID = null; - - private static final int GET_CLOUD_PATH_ERROR_CODE = 1; - private static final String GET_CLOUD_PATH_ERROR_ID = "cloud"; - - private static final int RC_READ_EXTERNAL_STORAGE = 5; - - private static CallbackContext callback; - private static String uriStr; - - public static final int READ_REQ_CODE = 0; - - public static final String READ = Manifest.permission.READ_EXTERNAL_STORAGE; - - protected void getReadPermission(int requestCode) { - PermissionHelper.requestPermission(this, requestCode, READ); - } - - public void initialize(CordovaInterface cordova, final CordovaWebView webView) { - super.initialize(cordova, webView); - } - - /** - * Executes the request and returns PluginResult. - * - * @param action The action to execute. - * @param args JSONArry of arguments for the plugin. - * @param callbackContext The callback context through which to return stuff to caller. - * @return A PluginResult object with a status and message. - */ - @Override - public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { - this.callback = callbackContext; - this.uriStr = args.getString(0); - - if (action.equals("resolveNativePath")) { - if (PermissionHelper.hasPermission(this, READ)) { - resolveNativePath(); - } - else { - getReadPermission(READ_REQ_CODE); - } - - return true; - } - else { - JSONObject resultObj = new JSONObject(); - - resultObj.put("code", INVALID_ACTION_ERROR_CODE); - resultObj.put("message", "Invalid action."); - - callbackContext.error(resultObj); - } - - return false; - } - - public void resolveNativePath() throws JSONException { - JSONObject resultObj = new JSONObject(); - /* content:///... */ - Uri pvUrl = Uri.parse(this.uriStr); - - Log.d(TAG, "URI: " + this.uriStr); - - Context appContext = this.cordova.getActivity().getApplicationContext(); - String filePath = getPath(appContext, pvUrl); - - //check result; send error/success callback - if (filePath == GET_PATH_ERROR_ID) { - resultObj.put("code", GET_PATH_ERROR_CODE); - resultObj.put("message", "Unable to resolve filesystem path."); - - this.callback.error(resultObj); - } - else if (filePath.equals(GET_CLOUD_PATH_ERROR_ID)) { - resultObj.put("code", GET_CLOUD_PATH_ERROR_CODE); - resultObj.put("message", "Files from cloud cannot be resolved to filesystem, download is required."); - - this.callback.error(resultObj); - } - else { - Log.d(TAG, "Filepath: " + filePath); - - this.callback.success("file://" + filePath); - } - } - - public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException { - for (int r:grantResults) { - if (r == PackageManager.PERMISSION_DENIED) { - JSONObject resultObj = new JSONObject(); - resultObj.put("code", 3); - resultObj.put("message", "Filesystem permission was denied."); - - this.callback.error(resultObj); - return; - } - } - - if (requestCode == READ_REQ_CODE) { - resolveNativePath(); - } - } - - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is ExternalStorageProvider. - */ - private static boolean isExternalStorageDocument(Uri uri) { - return "com.android.externalstorage.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is DownloadsProvider. - */ - private static boolean isDownloadsDocument(Uri uri) { - return "com.android.providers.downloads.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is MediaProvider. - */ - private static boolean isMediaDocument(Uri uri) { - return "com.android.providers.media.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is Google Photos. - */ - private static boolean isGooglePhotosUri(Uri uri) { - return ("com.google.android.apps.photos.content".equals(uri.getAuthority()) - || "com.google.android.apps.photos.contentprovider".equals(uri.getAuthority())); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is Google Drive. - */ - private static boolean isGoogleDriveUri(Uri uri) { - return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority()); - } - - /** - * Get the value of the data column for this Uri. This is useful for - * MediaStore Uris, and other file-based ContentProviders. - * - * @param context The context. - * @param uri The Uri to query. - * @param selection (Optional) Filter used in the query. - * @param selectionArgs (Optional) Selection arguments used in the query. - * @return The value of the _data column, which is typically a file path. - */ - private static String getDataColumn(Context context, Uri uri, String selection, - String[] selectionArgs) { - - Cursor cursor = null; - final String column = "_data"; - final String[] projection = { - column - }; - - try { - cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, - null); - if (cursor != null && cursor.moveToFirst()) { - final int column_index = cursor.getColumnIndexOrThrow(column); - return cursor.getString(column_index); - } - } finally { - if (cursor != null) - cursor.close(); - } - return null; - } - - /** - * Get content:// from segment list - * In the new Uri Authority of Google Photos, the last segment is not the content:// anymore - * So let's iterate through all segments and find the content uri! - * - * @param segments The list of segment - */ - private static String getContentFromSegments(List segments) { - String contentPath = ""; - - for(String item : segments) { - if (item.startsWith("content://")) { - contentPath = item; - break; - } - } - - return contentPath; - } - - /** - * Check if a file exists on device - * - * @param filePath The absolute file path - */ - private static boolean fileExists(String filePath) { - File file = new File(filePath); - - return file.exists(); - } - - /** - * Get full file path from external storage - * - * @param pathData The storage type and the relative path - */ - private static String getPathFromExtSD(String[] pathData) { - final String type = pathData[0]; - final String relativePath = "/" + pathData[1]; - String fullPath = ""; - - // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string - // something like "71F8-2C0A", some kind of unique id per storage - // don't know any API that can get the root path of that storage based on its id. - // - // so no "primary" type, but let the check here for other devices - if ("primary".equalsIgnoreCase(type)) { - fullPath = Environment.getExternalStorageDirectory() + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - } - - // Environment.isExternalStorageRemovable() is `true` for external and internal storage - // so we cannot relay on it. - // - // instead, for each possible path, check if file exists - // we'll start with secondary storage as this could be our (physically) removable sd card - fullPath = System.getenv("SECONDARY_STORAGE") + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - - fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath; - if (fileExists(fullPath)) { - return fullPath; - } - - return fullPath; - } - - /** - * Get a file path from a Uri. This will get the the path for Storage Access - * Framework Documents, as well as the _data field for the MediaStore and - * other file-based ContentProviders.
- *
- * Callers should check whether the path is local before assuming it - * represents a local file. - * - * @param context The context. - * @param uri The Uri to query. - */ - private static String getPath(final Context context, final Uri uri) { - - Log.d(TAG, "File - " + - "Authority: " + uri.getAuthority() + - ", Fragment: " + uri.getFragment() + - ", Port: " + uri.getPort() + - ", Query: " + uri.getQuery() + - ", Scheme: " + uri.getScheme() + - ", Host: " + uri.getHost() + - ", Segments: " + uri.getPathSegments().toString() - ); - - final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - - // DocumentProvider - if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { - // ExternalStorageProvider - if (isExternalStorageDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - String fullPath = getPathFromExtSD(split); - if (fullPath != "") { - return fullPath; - } - else { - return null; - } - } - // DownloadsProvider - else if (isDownloadsDocument(uri)) { - - final String id = DocumentsContract.getDocumentId(uri); - final Uri contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); - - return getDataColumn(context, contentUri, null, null); - } - // MediaProvider - else if (isMediaDocument(uri)) { - 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] - }; - - return getDataColumn(context, contentUri, selection, selectionArgs); - } - else if(isGoogleDriveUri(uri)){ - return getDriveFilePath(uri,context); - } - } - // MediaStore (and general) - else if ("content".equalsIgnoreCase(uri.getScheme())) { - - // Return the remote address - if (isGooglePhotosUri(uri)) { - String contentPath = getContentFromSegments(uri.getPathSegments()); - if (contentPath != "") { - return getPath(context, Uri.parse(contentPath)); - } - else { - return null; - } - } - - if(isGoogleDriveUri(uri)){ - return getDriveFilePath(uri,context); - } - - return getDataColumn(context, uri, null, null); - } - // File - else if ("file".equalsIgnoreCase(uri.getScheme())) { - return uri.getPath(); - } - - return null; - } - - private static String getDriveFilePath(Uri uri,Context context){ - Uri returnUri =uri; - Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); - /* - * Get the column indexes of the data in the Cursor, - * * move to the first row in the Cursor, get the data, - * * and display it. - * */ - int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); - returnCursor.moveToFirst(); - String name = (returnCursor.getString(nameIndex)); - String size = (Long.toString(returnCursor.getLong(sizeIndex))); - File file = new File(context.getCacheDir(),name); - try { - InputStream inputStream = context.getContentResolver().openInputStream(uri); - FileOutputStream outputStream = new FileOutputStream(file); - int read = 0; - int maxBufferSize = 1 * 1024 * 1024; - int bytesAvailable = inputStream.available(); - - //int bufferSize = 1024; - int bufferSize = Math.min(bytesAvailable, maxBufferSize); - - final byte[] buffers = new byte[bufferSize]; - while ((read = inputStream.read(buffers)) != -1) { - outputStream.write(buffers, 0, read); - } - Log.e("File Size","Size " + file.length()); - inputStream.close(); - outputStream.close(); - Log.e("File Path","Path " + file.getPath()); - Log.e("File Size","Size " + file.length()); - }catch (Exception e){ - Log.e("Exception",e.getMessage()); - } - return file.getPath(); - } -} +package com.hiddentao.cordova.filepath; + + +import android.Manifest; +import android.content.ContentUris; +import android.content.Context; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.provider.OpenableColumns; +import android.util.Log; +import android.database.Cursor; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; +import android.support.v4.app.ActivityCompat; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaInterface; +import org.apache.cordova.CordovaPlugin; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.PermissionHelper; +import org.json.JSONArray; +import org.json.JSONObject; +import org.json.JSONException; + +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.List; +import java.io.File; + +public class FilePath extends CordovaPlugin { + + private static final String TAG = "[FilePath plugin]: "; + + private static final int INVALID_ACTION_ERROR_CODE = -1; + + private static final int GET_PATH_ERROR_CODE = 0; + private static final String GET_PATH_ERROR_ID = null; + + private static final int GET_CLOUD_PATH_ERROR_CODE = 1; + private static final String GET_CLOUD_PATH_ERROR_ID = "cloud"; + + private static final int RC_READ_EXTERNAL_STORAGE = 5; + + private static CallbackContext callback; + private static String uriStr; + + public static final int READ_REQ_CODE = 0; + + public static final String READ = Manifest.permission.READ_EXTERNAL_STORAGE; + + protected void getReadPermission(int requestCode) { + PermissionHelper.requestPermission(this, requestCode, READ); + } + + public void initialize(CordovaInterface cordova, final CordovaWebView webView) { + super.initialize(cordova, webView); + } + + /** + * Executes the request and returns PluginResult. + * + * @param action The action to execute. + * @param args JSONArry of arguments for the plugin. + * @param callbackContext The callback context through which to return stuff to caller. + * @return A PluginResult object with a status and message. + */ + @Override + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + this.callback = callbackContext; + this.uriStr = args.getString(0); + + if (action.equals("resolveNativePath")) { + if (PermissionHelper.hasPermission(this, READ)) { + resolveNativePath(); + } + else { + getReadPermission(READ_REQ_CODE); + } + + return true; + } + else { + JSONObject resultObj = new JSONObject(); + + resultObj.put("code", INVALID_ACTION_ERROR_CODE); + resultObj.put("message", "Invalid action."); + + callbackContext.error(resultObj); + } + + return false; + } + + public void resolveNativePath() throws JSONException { + JSONObject resultObj = new JSONObject(); + /* content:///... */ + Uri pvUrl = Uri.parse(this.uriStr); + + Log.d(TAG, "URI: " + this.uriStr); + + Context appContext = this.cordova.getActivity().getApplicationContext(); + String filePath = getPath(appContext, pvUrl); + + //check result; send error/success callback + if (filePath == GET_PATH_ERROR_ID) { + resultObj.put("code", GET_PATH_ERROR_CODE); + resultObj.put("message", "Unable to resolve filesystem path."); + + this.callback.error(resultObj); + } + else if (filePath.equals(GET_CLOUD_PATH_ERROR_ID)) { + resultObj.put("code", GET_CLOUD_PATH_ERROR_CODE); + resultObj.put("message", "Files from cloud cannot be resolved to filesystem, download is required."); + + this.callback.error(resultObj); + } + else { + Log.d(TAG, "Filepath: " + filePath); + + this.callback.success("file://" + filePath); + } + } + + public void onRequestPermissionResult(int requestCode, String[] permissions, int[] grantResults) throws JSONException { + for (int r:grantResults) { + if (r == PackageManager.PERMISSION_DENIED) { + JSONObject resultObj = new JSONObject(); + resultObj.put("code", 3); + resultObj.put("message", "Filesystem permission was denied."); + + this.callback.error(resultObj); + return; + } + } + + if (requestCode == READ_REQ_CODE) { + resolveNativePath(); + } + } + + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + private static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + private static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + private static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + private static boolean isGooglePhotosUri(Uri uri) { + return ("com.google.android.apps.photos.content".equals(uri.getAuthority()) + || "com.google.android.apps.photos.contentprovider".equals(uri.getAuthority())); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Drive. + */ + private static boolean isGoogleDriveUri(Uri uri) { + return "com.google.android.apps.docs.storage".equals(uri.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(uri.getAuthority()); + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + private static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + /** + * Get content:// from segment list + * In the new Uri Authority of Google Photos, the last segment is not the content:// anymore + * So let's iterate through all segments and find the content uri! + * + * @param segments The list of segment + */ + private static String getContentFromSegments(List segments) { + String contentPath = ""; + + for(String item : segments) { + if (item.startsWith("content://")) { + contentPath = item; + break; + } + } + + return contentPath; + } + + /** + * Check if a file exists on device + * + * @param filePath The absolute file path + */ + private static boolean fileExists(String filePath) { + File file = new File(filePath); + + return file.exists(); + } + + /** + * Get full file path from external storage + * + * @param pathData The storage type and the relative path + */ + private static String getPathFromExtSD(String[] pathData) { + final String type = pathData[0]; + final String relativePath = "/" + pathData[1]; + String fullPath = ""; + + // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string + // something like "71F8-2C0A", some kind of unique id per storage + // don't know any API that can get the root path of that storage based on its id. + // + // so no "primary" type, but let the check here for other devices + if ("primary".equalsIgnoreCase(type)) { + fullPath = Environment.getExternalStorageDirectory() + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + } + + // Environment.isExternalStorageRemovable() is `true` for external and internal storage + // so we cannot relay on it. + // + // instead, for each possible path, check if file exists + // we'll start with secondary storage as this could be our (physically) removable sd card + fullPath = System.getenv("SECONDARY_STORAGE") + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + + fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath; + if (fileExists(fullPath)) { + return fullPath; + } + + return fullPath; + } + + /** + * Get a file path from a Uri. This will get the the path for Storage Access + * Framework Documents, as well as the _data field for the MediaStore and + * other file-based ContentProviders.
+ *
+ * Callers should check whether the path is local before assuming it + * represents a local file. + * + * @param context The context. + * @param uri The Uri to query. + */ + private static String getPath(final Context context, final Uri uri) { + + Log.d(TAG, "File - " + + "Authority: " + uri.getAuthority() + + ", Fragment: " + uri.getFragment() + + ", Port: " + uri.getPort() + + ", Query: " + uri.getQuery() + + ", Scheme: " + uri.getScheme() + + ", Host: " + uri.getHost() + + ", Segments: " + uri.getPathSegments().toString() + ); + + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + + // DocumentProvider + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + String fullPath = getPathFromExtSD(split); + if (fullPath != "") { + return fullPath; + } + else { + return null; + } + } + // DownloadsProvider + else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + try { + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } catch(NumberFormatException e) { + //In Android 8 and Android P the id is not a number + return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", ""); + } + } + // MediaProvider + else if (isMediaDocument(uri)) { + 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] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + else if(isGoogleDriveUri(uri)){ + return getDriveFilePath(uri,context); + } + } + // MediaStore (and general) + else if ("content".equalsIgnoreCase(uri.getScheme())) { + + // Return the remote address + if (isGooglePhotosUri(uri)) { + String contentPath = getContentFromSegments(uri.getPathSegments()); + if (contentPath != "") { + return getPath(context, Uri.parse(contentPath)); + } + else { + return null; + } + } + + if(isGoogleDriveUri(uri)){ + return getDriveFilePath(uri,context); + } + + return getDataColumn(context, uri, null, null); + } + // File + else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + private static String getDriveFilePath(Uri uri,Context context){ + Uri returnUri =uri; + Cursor returnCursor = context.getContentResolver().query(returnUri, null, null, null, null); + /* + * Get the column indexes of the data in the Cursor, + * * move to the first row in the Cursor, get the data, + * * and display it. + * */ + int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); + returnCursor.moveToFirst(); + String name = (returnCursor.getString(nameIndex)); + String size = (Long.toString(returnCursor.getLong(sizeIndex))); + File file = new File(context.getCacheDir(),name); + try { + InputStream inputStream = context.getContentResolver().openInputStream(uri); + FileOutputStream outputStream = new FileOutputStream(file); + int read = 0; + int maxBufferSize = 1 * 1024 * 1024; + int bytesAvailable = inputStream.available(); + + //int bufferSize = 1024; + int bufferSize = Math.min(bytesAvailable, maxBufferSize); + + final byte[] buffers = new byte[bufferSize]; + while ((read = inputStream.read(buffers)) != -1) { + outputStream.write(buffers, 0, read); + } + Log.e("File Size","Size " + file.length()); + inputStream.close(); + outputStream.close(); + Log.e("File Path","Path " + file.getPath()); + Log.e("File Size","Size " + file.length()); + }catch (Exception e){ + Log.e("Exception",e.getMessage()); + } + return file.getPath(); + } +} diff --git a/platforms/android/platform_www/cordova_plugins.js b/platforms/android/platform_www/cordova_plugins.js index 255dcc7..751029a 100644 --- a/platforms/android/platform_www/cordova_plugins.js +++ b/platforms/android/platform_www/cordova_plugins.js @@ -280,7 +280,7 @@ module.exports.metadata = "cordova-plugin-device": "2.0.2", "cordova-plugin-console": "1.1.0", "cordova-android-support-gradle-release": "1.4.4", - "cordova-plugin-filepath": "1.0.2" + "cordova-plugin-filepath": "1.4.2" }; // BOTTOM OF METADATA }); \ No newline at end of file