arnaucube
arnaucube/openEventsPlatformAppPublic Self-hosted repository
openEventsPlatformApp/plugins/cordova-plugin-camera/src/android/FileHelper.java
plugins/cordova-plugin-camera/src/android/FileHelper.javaRaw
  1/*
  2       Licensed to the Apache Software Foundation (ASF) under one
  3       or more contributor license agreements.  See the NOTICE file
  4       distributed with this work for additional information
  5       regarding copyright ownership.  The ASF licenses this file
  6       to you under the Apache License, Version 2.0 (the
  7       "License"); you may not use this file except in compliance
  8       with the License.  You may obtain a copy of the License at
  9         http://www.apache.org/licenses/LICENSE-2.0
 10       Unless required by applicable law or agreed to in writing,
 11       software distributed under the License is distributed on an
 12       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 13       KIND, either express or implied.  See the License for the
 14       specific language governing permissions and limitations
 15       under the License.
 16 */
 17package org.apache.cordova.camera;
 18
 19import android.annotation.SuppressLint;
 20import android.content.ContentUris;
 21import android.content.Context;
 22import android.content.CursorLoader;
 23import android.database.Cursor;
 24import android.net.Uri;
 25import android.os.Build;
 26import android.os.Environment;
 27import android.provider.DocumentsContract;
 28import android.provider.MediaStore;
 29import android.webkit.MimeTypeMap;
 30
 31import org.apache.cordova.CordovaInterface;
 32import org.apache.cordova.LOG;
 33
 34import java.io.FileInputStream;
 35import java.io.IOException;
 36import java.io.InputStream;
 37import java.util.Locale;
 38
 39public class FileHelper {
 40    private static final String LOG_TAG = "FileUtils";
 41    private static final String _DATA = "_data";
 42
 43    /**
 44     * Returns the real path of the given URI string.
 45     * If the given URI string represents a content:// URI, the real path is retrieved from the media store.
 46     *
 47     * @param uriString the URI string of the audio/image/video
 48     * @param cordova the current application context
 49     * @return the full path to the file
 50     */
 51    @SuppressWarnings("deprecation")
 52    public static String getRealPath(Uri uri, CordovaInterface cordova) {
 53        String realPath = null;
 54
 55        if (Build.VERSION.SDK_INT < 11)
 56            realPath = FileHelper.getRealPathFromURI_BelowAPI11(cordova.getActivity(), uri);
 57
 58        // SDK >= 11
 59        else
 60            realPath = FileHelper.getRealPathFromURI_API11_And_Above(cordova.getActivity(), uri);
 61
 62        return realPath;
 63    }
 64
 65    /**
 66     * Returns the real path of the given URI.
 67     * If the given URI is a content:// URI, the real path is retrieved from the media store.
 68     *
 69     * @param uri the URI of the audio/image/video
 70     * @param cordova the current application context
 71     * @return the full path to the file
 72     */
 73    public static String getRealPath(String uriString, CordovaInterface cordova) {
 74        return FileHelper.getRealPath(Uri.parse(uriString), cordova);
 75    }
 76
 77    @SuppressLint("NewApi")
 78    public static String getRealPathFromURI_API11_And_Above(final Context context, final Uri uri) {
 79
 80        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
 81        // DocumentProvider
 82        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
 83
 84            // ExternalStorageProvider
 85            if (isExternalStorageDocument(uri)) {
 86                final String docId = DocumentsContract.getDocumentId(uri);
 87                final String[] split = docId.split(":");
 88                final String type = split[0];
 89
 90                if ("primary".equalsIgnoreCase(type)) {
 91                    return Environment.getExternalStorageDirectory() + "/" + split[1];
 92                }
 93
 94                // TODO handle non-primary volumes
 95            }
 96            // DownloadsProvider
 97            else if (isDownloadsDocument(uri)) {
 98
 99                final String id = DocumentsContract.getDocumentId(uri);
100                final Uri contentUri = ContentUris.withAppendedId(
101                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
102
103                return getDataColumn(context, contentUri, null, null);
104            }
105            // MediaProvider
106            else if (isMediaDocument(uri)) {
107                final String docId = DocumentsContract.getDocumentId(uri);
108                final String[] split = docId.split(":");
109                final String type = split[0];
110
111                Uri contentUri = null;
112                if ("image".equals(type)) {
113                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
114                } else if ("video".equals(type)) {
115                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
116                } else if ("audio".equals(type)) {
117                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
118                }
119
120                final String selection = "_id=?";
121                final String[] selectionArgs = new String[] {
122                        split[1]
123                };
124
125                return getDataColumn(context, contentUri, selection, selectionArgs);
126            }
127        }
128        // MediaStore (and general)
129        else if ("content".equalsIgnoreCase(uri.getScheme())) {
130
131            // Return the remote address
132            if (isGooglePhotosUri(uri))
133                return uri.getLastPathSegment();
134
135            return getDataColumn(context, uri, null, null);
136        }
137        // File
138        else if ("file".equalsIgnoreCase(uri.getScheme())) {
139            return uri.getPath();
140        }
141
142        return null;
143    }
144
145    public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri) {
146        String[] proj = { MediaStore.Images.Media.DATA };
147        String result = null;
148
149        try {
150            Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
151            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
152            cursor.moveToFirst();
153            result = cursor.getString(column_index);
154
155        } catch (Exception e) {
156            result = null;
157        }
158        return result;
159    }
160
161    /**
162     * Returns an input stream based on given URI string.
163     *
164     * @param uriString the URI string from which to obtain the input stream
165     * @param cordova the current application context
166     * @return an input stream into the data at the given URI or null if given an invalid URI string
167     * @throws IOException
168     */
169    public static InputStream getInputStreamFromUriString(String uriString, CordovaInterface cordova)
170            throws IOException {
171        InputStream returnValue = null;
172        if (uriString.startsWith("content")) {
173            Uri uri = Uri.parse(uriString);
174            returnValue = cordova.getActivity().getContentResolver().openInputStream(uri);
175        } else if (uriString.startsWith("file://")) {
176            int question = uriString.indexOf("?");
177            if (question > -1) {
178                uriString = uriString.substring(0, question);
179            }
180            if (uriString.startsWith("file:///android_asset/")) {
181                Uri uri = Uri.parse(uriString);
182                String relativePath = uri.getPath().substring(15);
183                returnValue = cordova.getActivity().getAssets().open(relativePath);
184            } else {
185                // might still be content so try that first
186                try {
187                    returnValue = cordova.getActivity().getContentResolver().openInputStream(Uri.parse(uriString));
188                } catch (Exception e) {
189                    returnValue = null;
190                }
191                if (returnValue == null) {
192                    returnValue = new FileInputStream(getRealPath(uriString, cordova));
193                }
194            }
195        } else {
196            returnValue = new FileInputStream(uriString);
197        }
198        return returnValue;
199    }
200
201    /**
202     * Removes the "file://" prefix from the given URI string, if applicable.
203     * If the given URI string doesn't have a "file://" prefix, it is returned unchanged.
204     *
205     * @param uriString the URI string to operate on
206     * @return a path without the "file://" prefix
207     */
208    public static String stripFileProtocol(String uriString) {
209        if (uriString.startsWith("file://")) {
210            uriString = uriString.substring(7);
211        }
212        return uriString;
213    }
214
215    public static String getMimeTypeForExtension(String path) {
216        String extension = path;
217        int lastDot = extension.lastIndexOf('.');
218        if (lastDot != -1) {
219            extension = extension.substring(lastDot + 1);
220        }
221        // Convert the URI string to lower case to ensure compatibility with MimeTypeMap (see CB-2185).
222        extension = extension.toLowerCase(Locale.getDefault());
223        if (extension.equals("3ga")) {
224            return "audio/3gpp";
225        }
226        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
227    }
228    
229    /**
230     * Returns the mime type of the data specified by the given URI string.
231     *
232     * @param uriString the URI string of the data
233     * @return the mime type of the specified data
234     */
235    public static String getMimeType(String uriString, CordovaInterface cordova) {
236        String mimeType = null;
237
238        Uri uri = Uri.parse(uriString);
239        if (uriString.startsWith("content://")) {
240            mimeType = cordova.getActivity().getContentResolver().getType(uri);
241        } else {
242            mimeType = getMimeTypeForExtension(uri.getPath());
243        }
244
245        return mimeType;
246    }
247
248    /**
249     * Get the value of the data column for this Uri. This is useful for
250     * MediaStore Uris, and other file-based ContentProviders.
251     *
252     * @param context The context.
253     * @param uri The Uri to query.
254     * @param selection (Optional) Filter used in the query.
255     * @param selectionArgs (Optional) Selection arguments used in the query.
256     * @return The value of the _data column, which is typically a file path.
257     * @author paulburke
258     */
259    public static String getDataColumn(Context context, Uri uri, String selection,
260                                       String[] selectionArgs) {
261
262        Cursor cursor = null;
263        final String column = "_data";
264        final String[] projection = {
265                column
266        };
267
268        try {
269            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
270                    null);
271            if (cursor != null && cursor.moveToFirst()) {
272
273                final int column_index = cursor.getColumnIndexOrThrow(column);
274                return cursor.getString(column_index);
275            }
276        } catch (Exception e) {
277            return null;
278        } finally {
279            if (cursor != null)
280                cursor.close();
281        }
282        return null;
283    }
284
285    /**
286     * @param uri The Uri to check.
287     * @return Whether the Uri authority is ExternalStorageProvider.
288     * @author paulburke
289     */
290    public static boolean isExternalStorageDocument(Uri uri) {
291        return "com.android.externalstorage.documents".equals(uri.getAuthority());
292    }
293
294    /**
295     * @param uri The Uri to check.
296     * @return Whether the Uri authority is DownloadsProvider.
297     * @author paulburke
298     */
299    public static boolean isDownloadsDocument(Uri uri) {
300        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
301    }
302
303    /**
304     * @param uri The Uri to check.
305     * @return Whether the Uri authority is MediaProvider.
306     * @author paulburke
307     */
308    public static boolean isMediaDocument(Uri uri) {
309        return "com.android.providers.media.documents".equals(uri.getAuthority());
310    }
311
312    /**
313     * @param uri The Uri to check.
314     * @return Whether the Uri authority is Google Photos.
315     */
316    public static boolean isGooglePhotosUri(Uri uri) {
317        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
318    }
319}