Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java

Issue 489053003: Use content URI to upload photos taken by camera (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add thread check Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/remoting_android.gypi ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.ui.base; 5 package org.chromium.ui.base;
6 6
7 import android.annotation.TargetApi; 7 import android.annotation.TargetApi;
8 import android.app.Activity; 8 import android.app.Activity;
9 import android.content.ClipData; 9 import android.content.ClipData;
10 import android.content.ContentResolver; 10 import android.content.ContentResolver;
11 import android.content.Context;
11 import android.content.Intent; 12 import android.content.Intent;
12 import android.net.Uri; 13 import android.net.Uri;
13 import android.os.AsyncTask; 14 import android.os.AsyncTask;
14 import android.os.Build; 15 import android.os.Build;
15 import android.os.Environment;
16 import android.provider.MediaStore; 16 import android.provider.MediaStore;
17 import android.text.TextUtils; 17 import android.text.TextUtils;
18 import android.util.Log;
18 19
19 import org.chromium.base.CalledByNative; 20 import org.chromium.base.CalledByNative;
20 import org.chromium.base.ContentUriUtils; 21 import org.chromium.base.ContentUriUtils;
21 import org.chromium.base.JNINamespace; 22 import org.chromium.base.JNINamespace;
22 import org.chromium.ui.R; 23 import org.chromium.ui.R;
23 24
24 import java.io.File; 25 import java.io.File;
26 import java.io.IOException;
25 import java.util.ArrayList; 27 import java.util.ArrayList;
26 import java.util.Arrays; 28 import java.util.Arrays;
27 import java.util.List; 29 import java.util.List;
28 30
29 /** 31 /**
30 * A dialog that is triggered from a file input field that allows a user to sele ct a file based on 32 * A dialog that is triggered from a file input field that allows a user to sele ct a file based on
31 * a set of accepted file types. The path of the selected file is passed to the native dialog. 33 * a set of accepted file types. The path of the selected file is passed to the native dialog.
32 */ 34 */
33 @JNINamespace("ui") 35 @JNINamespace("ui")
34 class SelectFileDialog implements WindowAndroid.IntentCallback{ 36 class SelectFileDialog implements WindowAndroid.IntentCallback{
37 private static final String TAG = "SelectFileDialog";
35 private static final String IMAGE_TYPE = "image/"; 38 private static final String IMAGE_TYPE = "image/";
36 private static final String VIDEO_TYPE = "video/"; 39 private static final String VIDEO_TYPE = "video/";
37 private static final String AUDIO_TYPE = "audio/"; 40 private static final String AUDIO_TYPE = "audio/";
38 private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; 41 private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*";
39 private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; 42 private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*";
40 private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; 43 private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*";
41 private static final String ANY_TYPES = "*/*"; 44 private static final String ANY_TYPES = "*/*";
42 private static final String CAPTURE_IMAGE_DIRECTORY = "browser-photos"; 45 private static final String CAPTURE_IMAGE_DIRECTORY = "browser-photos";
46 // Keep this variable in sync with the value defined in file_paths.xml.
47 private static final String IMAGE_FILE_PATH = "images";
43 48
44 private final long mNativeSelectFileDialog; 49 private final long mNativeSelectFileDialog;
45 private List<String> mFileTypes; 50 private List<String> mFileTypes;
46 private boolean mCapture; 51 private boolean mCapture;
47 private Uri mCameraOutputUri; 52 private Uri mCameraOutputUri;
48 53
49 private SelectFileDialog(long nativeSelectFileDialog) { 54 private SelectFileDialog(long nativeSelectFileDialog) {
50 mNativeSelectFileDialog = nativeSelectFileDialog; 55 mNativeSelectFileDialog = nativeSelectFileDialog;
51 } 56 }
52 57
53 /** 58 /**
54 * Creates and starts an intent based on the passed fileTypes and capture va lue. 59 * Creates and starts an intent based on the passed fileTypes and capture va lue.
55 * @param fileTypes MIME types requested (i.e. "image/*") 60 * @param fileTypes MIME types requested (i.e. "image/*")
56 * @param capture The capture value as described in http://www.w3.org/TR/htm l-media-capture/ 61 * @param capture The capture value as described in http://www.w3.org/TR/htm l-media-capture/
57 * @param multiple Whether it should be possible to select multiple files. 62 * @param multiple Whether it should be possible to select multiple files.
58 * @param window The WindowAndroid that can show intents 63 * @param window The WindowAndroid that can show intents
59 */ 64 */
60 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 65 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
61 @CalledByNative 66 @CalledByNative
62 private void selectFile( 67 private void selectFile(
63 String[] fileTypes, boolean capture, boolean multiple, WindowAndroid window) { 68 String[] fileTypes, boolean capture, boolean multiple, WindowAndroid window) {
64 mFileTypes = new ArrayList<String>(Arrays.asList(fileTypes)); 69 mFileTypes = new ArrayList<String>(Arrays.asList(fileTypes));
65 mCapture = capture; 70 mCapture = capture;
66 71
67 Intent chooser = new Intent(Intent.ACTION_CHOOSER); 72 Intent chooser = new Intent(Intent.ACTION_CHOOSER);
68 Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 73 Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
69 mCameraOutputUri = Uri.fromFile(getFileForImageCapture()); 74 camera.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
75 Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
76 Context context = window.getApplicationContext();
77 try {
78 mCameraOutputUri = ContentUriUtils.getContentUriFromFile(
79 context, getFileForImageCapture(context));
80 } catch (IOException e) {
81 Log.e(TAG, "Cannot retrieve content uri from file", e);
82 }
83 if (mCameraOutputUri == null) {
84 onFileNotSelected();
85 return;
86 }
87
70 camera.putExtra(MediaStore.EXTRA_OUTPUT, mCameraOutputUri); 88 camera.putExtra(MediaStore.EXTRA_OUTPUT, mCameraOutputUri);
89 camera.setClipData(
90 ClipData.newUri(context.getContentResolver(), IMAGE_FILE_PATH, m CameraOutputUri));
71 Intent camcorder = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 91 Intent camcorder = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
72 Intent soundRecorder = new Intent( 92 Intent soundRecorder = new Intent(
73 MediaStore.Audio.Media.RECORD_SOUND_ACTION); 93 MediaStore.Audio.Media.RECORD_SOUND_ACTION);
74 94
75 // Quick check - if the |capture| parameter is set and |fileTypes| has t he appropriate MIME 95 // Quick check - if the |capture| parameter is set and |fileTypes| has t he appropriate MIME
76 // type, we should just launch the appropriate intent. Otherwise build u p a chooser based on 96 // type, we should just launch the appropriate intent. Otherwise build u p a chooser based on
77 // the accept type and then display that to the user. 97 // the accept type and then display that to the user.
78 if (captureCamera()) { 98 if (captureCamera()) {
79 if (window.showIntent(camera, this, R.string.low_memory_error)) retu rn; 99 if (window.showIntent(camera, this, R.string.low_memory_error)) retu rn;
80 } else if (captureCamcorder()) { 100 } else if (captureCamcorder()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 extraIntents.toArray(new Intent[] { })); 138 extraIntents.toArray(new Intent[] { }));
119 139
120 chooser.putExtra(Intent.EXTRA_INTENT, getContentIntent); 140 chooser.putExtra(Intent.EXTRA_INTENT, getContentIntent);
121 141
122 if (!window.showIntent(chooser, this, R.string.low_memory_error)) { 142 if (!window.showIntent(chooser, this, R.string.low_memory_error)) {
123 onFileNotSelected(); 143 onFileNotSelected();
124 } 144 }
125 } 145 }
126 146
127 /** 147 /**
128 * Get a file for the image capture in the CAPTURE_IMAGE_DIRECTORY directory . 148 * Get a file for the image capture in the IMAGE_FILE_PATH directory.
149 * @param context The application context.
129 */ 150 */
130 private File getFileForImageCapture() { 151 private File getFileForImageCapture(Context context) throws IOException {
131 File externalDataDir = Environment.getExternalStoragePublicDirectory( 152 final File path = new File(context.getFilesDir(), IMAGE_FILE_PATH);
132 Environment.DIRECTORY_DCIM); 153 if (!path.exists() && !path.mkdir()) {
133 File cameraDataDir = new File(externalDataDir.getAbsolutePath() + 154 throw new IOException("Folder cannot be created.");
134 File.separator + CAPTURE_IMAGE_DIRECTORY);
135 if (!cameraDataDir.exists() && !cameraDataDir.mkdirs()) {
136 cameraDataDir = externalDataDir;
137 } 155 }
138 File photoFile = new File(cameraDataDir.getAbsolutePath() + 156 File photoFile = File.createTempFile(
139 File.separator + System.currentTimeMillis() + ".jpg"); 157 String.valueOf(System.currentTimeMillis()), ".jpg", path);
140 return photoFile; 158 return photoFile;
141 } 159 }
142 160
143 /** 161 /**
144 * Callback method to handle the intent results and pass on the path to the native 162 * Callback method to handle the intent results and pass on the path to the native
145 * SelectFileDialog. 163 * SelectFileDialog.
146 * @param window The window that has access to the application activity. 164 * @param window The window that has access to the application activity.
147 * @param resultCode The result code whether the intent returned successfull y. 165 * @param resultCode The result code whether the intent returned successfull y.
148 * @param contentResolver The content resolver used to extract the path of t he selected file. 166 * @param contentResolver The content resolver used to extract the path of t he selected file.
149 * @param results The results of the requested intent. 167 * @param results The results of the requested intent.
150 */ 168 */
151 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 169 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
152 @Override 170 @Override
153 public void onIntentCompleted(WindowAndroid window, int resultCode, 171 public void onIntentCompleted(WindowAndroid window, int resultCode,
154 ContentResolver contentResolver, Intent results) { 172 ContentResolver contentResolver, Intent results) {
155 if (resultCode != Activity.RESULT_OK) { 173 if (resultCode != Activity.RESULT_OK) {
156 onFileNotSelected(); 174 onFileNotSelected();
157 return; 175 return;
158 } 176 }
159 177
160 if (results == null) { 178 if (results == null) {
161 // If we have a successful return but no data, then assume this is t he camera returning 179 // If we have a successful return but no data, then assume this is t he camera returning
162 // the photo that we requested. 180 // the photo that we requested.
163 nativeOnFileSelected(mNativeSelectFileDialog, mCameraOutputUri.getPa th(), ""); 181 nativeOnFileSelected(mNativeSelectFileDialog, mCameraOutputUri.toStr ing(),
182 mCameraOutputUri.getLastPathSegment());
164 183
165 // Broadcast to the media scanner that there's a new photo on the de vice so it will 184 // Broadcast to the media scanner that there's a new photo on the de vice so it will
166 // show up right away in the gallery (rather than waiting until the next time the media 185 // show up right away in the gallery (rather than waiting until the next time the media
167 // scanner runs). 186 // scanner runs).
168 window.sendBroadcast(new Intent( 187 window.sendBroadcast(new Intent(
169 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mCameraOutputUri)); 188 Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, mCameraOutputUri));
170 return; 189 return;
171 } 190 }
172 191
173 // Path for when EXTRA_ALLOW_MULTIPLE Intent extra has been defined. Eac h of the selected 192 // Path for when EXTRA_ALLOW_MULTIPLE Intent extra has been defined. Eac h of the selected
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 private static SelectFileDialog create(long nativeSelectFileDialog) { 318 private static SelectFileDialog create(long nativeSelectFileDialog) {
300 return new SelectFileDialog(nativeSelectFileDialog); 319 return new SelectFileDialog(nativeSelectFileDialog);
301 } 320 }
302 321
303 private native void nativeOnFileSelected(long nativeSelectFileDialogImpl, 322 private native void nativeOnFileSelected(long nativeSelectFileDialogImpl,
304 String filePath, String displayName); 323 String filePath, String displayName);
305 private native void nativeOnMultipleFilesSelected(long nativeSelectFileDialo gImpl, 324 private native void nativeOnMultipleFilesSelected(long nativeSelectFileDialo gImpl,
306 String[] filePathArray, String[] displayNameArray); 325 String[] filePathArray, String[] displayNameArray);
307 private native void nativeOnFileNotSelected(long nativeSelectFileDialogImpl) ; 326 private native void nativeOnFileNotSelected(long nativeSelectFileDialogImpl) ;
308 } 327 }
OLDNEW
« no previous file with comments | « remoting/remoting_android.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698