blob: d9b387fbf5456bd556837e11420b34bf985e0d25 [file] [log] [blame]
/*
* 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.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.webkit.ValueCallback;
import java.io.File;
import java.util.Vector;
/**
* Handle the file upload callbacks from WebView here
*/
public class UploadHandler {
/*
* The Object used to inform the WebView of the file to upload.
*/
private ValueCallback<Uri> mUploadMessage;
private String mCameraFilePath;
private Controller mController;
public UploadHandler(Controller controller) {
mController = controller;
}
String getFilePath() {
return mCameraFilePath;
}
void onResult(int resultCode, Intent intent) {
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) {
File cameraFile = new File(mCameraFilePath);
if (cameraFile.exists()) {
result = Uri.fromFile(cameraFile);
// Broadcast to the media scanner that we have a new photo
// so it will be added into the gallery for the user.
mController.getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
}
}
mUploadMessage.onReceiveValue(result);
}
void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
final String imageMimeType = "image/*";
final String videoMimeType = "video/*";
final String audioMimeType = "audio/*";
final String mediaSourceKey = "capture";
final String mediaSourceValueCamera = "camera";
final String mediaSourceValueFileSystem = "filesystem";
final String mediaSourceValueCamcorder = "camcorder";
final String mediaSourceValueMicrophone = "microphone";
// media source can be 'filesystem' or 'camera' or 'camcorder' or 'microphone'.
String mediaSource = "";
// We add the camera intent if there was no accept type (or '*/*' or 'image/*').
boolean addCameraIntent = true;
// We add the camcorder intent if there was no accept type (or '*/*' or 'video/*').
boolean addCamcorderIntent = true;
if (mUploadMessage != null) {
// Already a file picker operation in progress.
return;
}
mUploadMessage = uploadMsg;
// Parse the accept type.
String params[] = acceptType.split(";");
String mimeType = params[0];
for (String p : params) {
String[] keyValue = p.split("=");
if (keyValue.length == 2) {
// Process key=value parameters.
if (mediaSourceKey.equals(keyValue[0])) {
mediaSource = keyValue[1];
}
}
}
// This intent will display the standard OPENABLE file picker.
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
// Create an intent to add to the standard file picker that will
// capture an image from the camera. We'll combine this intent with
// the standard OPENABLE picker unless the web developer specifically
// requested the camera or gallery be opened by passing a parameter
// in the accept type.
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File externalDataDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM);
File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
File.separator + "browser-photos");
cameraDataDir.mkdirs();
mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
System.currentTimeMillis() + ".jpg";
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
Intent camcorderIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Intent soundRecIntent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
if (mimeType.equals(imageMimeType)) {
i.setType(imageMimeType);
addCamcorderIntent = false;
if (mediaSource.equals(mediaSourceValueCamera)) {
// Specified 'image/*' and requested the camera, so go ahead and launch the camera
// directly.
startActivity(cameraIntent);
return;
} else if (mediaSource.equals(mediaSourceValueFileSystem)) {
// Specified filesytem as the source, so don't want to consider the camera.
addCameraIntent = false;
}
} else if (mimeType.equals(videoMimeType)) {
i.setType(videoMimeType);
addCameraIntent = false;
// The camcorder saves it's own file and returns it to us in the intent, so
// we don't need to generate one here.
mCameraFilePath = null;
if (mediaSource.equals(mediaSourceValueCamcorder)) {
// Specified 'video/*' and requested the camcorder, so go ahead and launch the
// camcorder directly.
startActivity(camcorderIntent);
return;
} else if (mediaSource.equals(mediaSourceValueFileSystem)) {
// Specified filesystem as the source, so don't want to consider the camcorder.
addCamcorderIntent = false;
}
} else if (mimeType.equals(audioMimeType)) {
i.setType(audioMimeType);
addCameraIntent = false;
addCamcorderIntent = false;
if (mediaSource.equals(mediaSourceValueMicrophone)) {
// Specified 'audio/*' and requested microphone, so go ahead and launch the sound
// recorder.
startActivity(soundRecIntent);
return;
}
// On a default system, there is no single option to open an audio "gallery". Both the
// sound recorder and music browser respond to the OPENABLE/audio/* intent unlike the
// image/* and video/* OPENABLE intents where the image / video gallery are the only
// respondants (and so the user is not prompted by default).
} else {
i.setType("*/*");
}
// Combine the chooser and the extra choices (like camera or camcorder)
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, i);
Vector<Intent> extraInitialIntents = new Vector<Intent>(0);
if (addCameraIntent) {
extraInitialIntents.add(cameraIntent);
}
if (addCamcorderIntent) {
extraInitialIntents.add(camcorderIntent);
}
if (extraInitialIntents.size() > 0) {
Intent[] extraIntents = new Intent[extraInitialIntents.size()];
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS,
extraInitialIntents.toArray(extraIntents));
}
chooser.putExtra(Intent.EXTRA_TITLE,
mController.getActivity().getResources()
.getString(R.string.choose_upload));
startActivity(chooser);
}
private void startActivity(Intent intent) {
mController.getActivity().startActivityForResult(intent,
Controller.FILE_SELECTED);
}
}