5
5
import android .util .Log ;
6
6
import android .annotation .TargetApi ;
7
7
import android .app .Activity ;
8
+ import android .content .Context ;
8
9
import android .os .Build ;
9
10
import android .view .KeyEvent ;
10
11
import android .view .View ;
17
18
import android .webkit .WebView ;
18
19
import android .webkit .WebViewClient ;
19
20
import android .widget .FrameLayout ;
21
+ import android .provider .MediaStore ;
22
+ import android .support .v4 .content .FileProvider ;
20
23
24
+ import java .util .List ;
25
+ import java .util .ArrayList ;
21
26
import java .util .HashMap ;
22
27
import java .util .Map ;
28
+ import java .io .File ;
29
+ import java .util .Date ;
30
+ import java .io .IOException ;
31
+ import java .text .SimpleDateFormat ;
23
32
24
33
import io .flutter .plugin .common .MethodCall ;
25
34
import io .flutter .plugin .common .MethodChannel ;
@@ -35,6 +44,7 @@ class WebviewManager {
35
44
private ValueCallback <Uri > mUploadMessage ;
36
45
private ValueCallback <Uri []> mUploadMessageArray ;
37
46
private final static int FILECHOOSER_RESULTCODE =1 ;
47
+ private Uri fileUri ;
38
48
39
49
@ TargetApi (7 )
40
50
class ResultHandler {
@@ -47,6 +57,8 @@ public boolean handleResult(int requestCode, int resultCode, Intent intent){
47
57
String dataString = intent .getDataString ();
48
58
if (dataString != null ){
49
59
results = new Uri []{ Uri .parse (dataString ) };
60
+ }else if (fileUri != null ){
61
+ results = new Uri []{ fileUri };
50
62
}
51
63
}
52
64
if (mUploadMessageArray != null ){
@@ -76,10 +88,12 @@ public boolean handleResult(int requestCode, int resultCode, Intent intent){
76
88
WebView webView ;
77
89
Activity activity ;
78
90
ResultHandler resultHandler ;
91
+ Context context ;
79
92
80
- WebviewManager (final Activity activity ) {
93
+ WebviewManager (final Activity activity , final Context context ) {
81
94
this .webView = new ObservableWebView (activity );
82
95
this .activity = activity ;
96
+ this .context = context ;
83
97
this .resultHandler = new ResultHandler ();
84
98
WebViewClient webViewClient = new BrowserClient ();
85
99
webView .setOnKeyListener (new View .OnKeyListener () {
@@ -158,11 +172,29 @@ public boolean onShowFileChooser(
158
172
}
159
173
mUploadMessageArray = filePathCallback ;
160
174
161
- Intent contentSelectionIntent = new Intent (Intent .ACTION_GET_CONTENT );
162
- contentSelectionIntent .addCategory (Intent .CATEGORY_OPENABLE );
163
- contentSelectionIntent .setType ("*/*" );
164
- Intent [] intentArray ;
165
- intentArray = new Intent [0 ];
175
+ final String [] acceptTypes = getSafeAcceptedTypes (fileChooserParams );
176
+ List <Intent > intentList = new ArrayList <Intent >();
177
+ if (acceptsImages (acceptTypes )) {
178
+ Intent takePhotoIntent = new Intent (MediaStore .ACTION_IMAGE_CAPTURE );
179
+ fileUri = getOutputFilename (MediaStore .ACTION_IMAGE_CAPTURE );
180
+ takePhotoIntent .putExtra (MediaStore .EXTRA_OUTPUT , fileUri );
181
+ intentList .add (takePhotoIntent );
182
+ }
183
+ if (acceptsVideo (acceptTypes )) {
184
+ Intent takeVideoIntent = new Intent (MediaStore .ACTION_VIDEO_CAPTURE );
185
+ fileUri = getOutputFilename (MediaStore .ACTION_VIDEO_CAPTURE );
186
+ takeVideoIntent .putExtra (MediaStore .EXTRA_OUTPUT , fileUri );
187
+ intentList .add (takeVideoIntent );
188
+ }
189
+ Intent contentSelectionIntent ;
190
+ if (Build .VERSION .SDK_INT >= 21 ) {
191
+ contentSelectionIntent = fileChooserParams .createIntent ();
192
+ } else {
193
+ contentSelectionIntent = new Intent (Intent .ACTION_GET_CONTENT );
194
+ contentSelectionIntent .addCategory (Intent .CATEGORY_OPENABLE );
195
+ contentSelectionIntent .setType ("*/*" );
196
+ }
197
+ Intent [] intentArray = intentList .toArray (new Intent [intentList .size ()]);
166
198
167
199
Intent chooserIntent = new Intent (Intent .ACTION_CHOOSER );
168
200
chooserIntent .putExtra (Intent .EXTRA_INTENT , contentSelectionIntent );
@@ -174,6 +206,73 @@ public boolean onShowFileChooser(
174
206
});
175
207
}
176
208
209
+ private Uri getOutputFilename (String intentType ) {
210
+ String prefix = "" ;
211
+ String suffix = "" ;
212
+
213
+ if (intentType == MediaStore .ACTION_IMAGE_CAPTURE ) {
214
+ prefix = "image-" ;
215
+ suffix = ".jpg" ;
216
+ } else if (intentType == MediaStore .ACTION_VIDEO_CAPTURE ) {
217
+ prefix = "video-" ;
218
+ suffix = ".mp4" ;
219
+ }
220
+
221
+ String packageName = context .getPackageName ();
222
+ File capturedFile = null ;
223
+ try {
224
+ capturedFile = createCapturedFile (prefix , suffix );
225
+ } catch (IOException e ) {
226
+ Log .e ("CREATE FILE" , "Error occurred while creating the File" , e );
227
+ e .printStackTrace ();
228
+ }
229
+ return FileProvider .getUriForFile (context , packageName + ".fileprovider" , capturedFile );
230
+ }
231
+
232
+ private File createCapturedFile (String prefix , String suffix ) throws IOException {
233
+ String timeStamp = new SimpleDateFormat ("yyyyMMdd_HHmmss" ).format (new Date ());
234
+ String imageFileName = prefix + "_" + timeStamp ;
235
+ File storageDir = context .getExternalFilesDir (null );
236
+ return File .createTempFile (imageFileName , suffix , storageDir );
237
+ }
238
+
239
+ private Boolean acceptsImages (String [] types ) {
240
+ return isArrayEmpty (types ) || arrayContainsString (types , "image" );
241
+ }
242
+
243
+ private Boolean acceptsVideo (String [] types ) {
244
+ return isArrayEmpty (types ) || arrayContainsString (types , "video" );
245
+ }
246
+
247
+ private Boolean arrayContainsString (String [] array , String pattern ) {
248
+ for (String content : array ) {
249
+ if (content .contains (pattern )) {
250
+ return true ;
251
+ }
252
+ }
253
+ return false ;
254
+ }
255
+
256
+ private Boolean isArrayEmpty (String [] arr ) {
257
+ // when our array returned from getAcceptTypes() has no values set from the
258
+ // webview
259
+ // i.e. <input type="file" />, without any "accept" attr
260
+ // will be an array with one empty string element, afaik
261
+ return arr .length == 0 || (arr .length == 1 && arr [0 ].length () == 0 );
262
+ }
263
+
264
+ private String [] getSafeAcceptedTypes (WebChromeClient .FileChooserParams params ) {
265
+
266
+ // the getAcceptTypes() is available only in api 21+
267
+ // for lower level, we ignore it
268
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
269
+ return params .getAcceptTypes ();
270
+ }
271
+
272
+ final String [] EMPTY = {};
273
+ return EMPTY ;
274
+ }
275
+
177
276
private void clearCookies () {
178
277
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
179
278
CookieManager .getInstance ().removeAllCookies (new ValueCallback <Boolean >() {
0 commit comments