1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.browser;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.webkit.WebChromeClient.FileChooserParams;
import android.webkit.ValueCallback;
import android.widget.Toast;
import java.io.File;
/**
* Handle the file upload. This does not support selecting multiple files yet.
*/
public class UploadHandler {
private final static String IMAGE_MIME_TYPE = "image/*";
private final static String VIDEO_MIME_TYPE = "video/*";
private final static String AUDIO_MIME_TYPE = "audio/*";
private final static String FILE_PROVIDER_AUTHORITY = "com.android.browser-classic.file";
/*
* The Object used to inform the WebView of the file to upload.
*/
private ValueCallback<Uri[]> mUploadMessage;
private boolean mHandled;
private Controller mController;
private FileChooserParams mParams;
private Uri mCapturedMedia;
public UploadHandler(Controller controller) {
mController = controller;
}
boolean handled() {
return mHandled;
}
void onResult(int resultCode, Intent intent) {
Uri[] uris;
// As the media capture is always supported, we can't use
// FileChooserParams.parseResult().
uris = parseResult(resultCode, intent);
mUploadMessage.onReceiveValue(uris);
mHandled = true;
}
void openFileChooser(ValueCallback<Uri[]> callback, FileChooserParams fileChooserParams) {
if (mUploadMessage != null) {
// Already a file picker operation in progress.
return;
}
mUploadMessage = callback;
mParams = fileChooserParams;
Intent[] captureIntents = createCaptureIntent();
assert(captureIntents != null && captureIntents.length > 0);
Intent intent = null;
// Go to the media capture directly if capture is specified, this is the
// preferred way.
if (fileChooserParams.isCaptureEnabled() && captureIntents.length == 1) {
intent = captureIntents[0];
} else {
intent = new Intent(Intent.ACTION_CHOOSER);
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, captureIntents);
intent.putExtra(Intent.EXTRA_INTENT, fileChooserParams.createIntent());
}
startActivity(intent);
}
private Uri[] parseResult(int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_CANCELED) {
return null;
}
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
: intent.getData();
// As we ask the camera to save the result of the user taking
// a picture, the camera application does not return anything other
// than RESULT_OK. So we need to check whether the file we expected
// was written to disk in the in the case that we
// did not get an intent returned but did get a RESULT_OK. If it was,
// we assume that this result has came back from the camera.
if (result == null && intent == null && resultCode == Activity.RESULT_OK
&& mCapturedMedia != null) {
result = mCapturedMedia;
}
Uri[] uris = null;
if (result != null) {
uris = new Uri[1];
uris[0] = result;
}
return uris;
}
private void startActivity(Intent intent) {
try {
mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED);
} catch (ActivityNotFoundException e) {
// No installed app was able to handle the intent that
// we sent, so file upload is effectively disabled.
Toast.makeText(mController.getActivity(), R.string.uploads_disabled,
Toast.LENGTH_LONG).show();
}
}
private Intent[] createCaptureIntent() {
String mimeType = "*/*";
String[] acceptTypes = mParams.getAcceptTypes();
if ( acceptTypes != null && acceptTypes.length > 0) {
mimeType = acceptTypes[0];
}
Intent[] intents;
if (mimeType.equals(IMAGE_MIME_TYPE)) {
intents = new Intent[1];
intents[0] = createCameraIntent(createTempFileContentUri(".jpg"));
} else if (mimeType.equals(VIDEO_MIME_TYPE)) {
intents = new Intent[1];
intents[0] = createCamcorderIntent();
} else if (mimeType.equals(AUDIO_MIME_TYPE)) {
intents = new Intent[1];
intents[0] = createSoundRecorderIntent();
} else {
intents = new Intent[3];
intents[0] = createCameraIntent(createTempFileContentUri(".jpg"));
intents[1] = createCamcorderIntent();
intents[2] = createSoundRecorderIntent();
}
return intents;
}
private Uri createTempFileContentUri(String suffix) {
try {
File mediaPath = new File(mController.getActivity().getFilesDir(), "captured_media");
if (!mediaPath.exists() && !mediaPath.mkdir()) {
throw new RuntimeException("Folder cannot be created.");
}
File mediaFile = File.createTempFile(
String.valueOf(System.currentTimeMillis()), suffix, mediaPath);
return FileProvider.getUriForFile(mController.getActivity(),
FILE_PROVIDER_AUTHORITY, mediaFile);
} catch (java.io.IOException e) {
throw new RuntimeException(e);
}
}
private Intent createCameraIntent(Uri contentUri) {
if (contentUri == null) throw new IllegalArgumentException();
mCapturedMedia = contentUri;
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION |
Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedMedia);
intent.setClipData(ClipData.newUri(mController.getActivity().getContentResolver(),
FILE_PROVIDER_AUTHORITY, mCapturedMedia));
return intent;
}
private Intent createCamcorderIntent() {
return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
}
private Intent createSoundRecorderIntent() {
return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
}
}
|