WebView支持拍照、录像、选择文件
最近因为业务需要webview支持用户录像,所以研究了一下
最重要的就是重写WebChromeClient中的几个方法
webView.setWebChromeClient(new WebChromeClient(getActivity()) {
@Override public void onReceivedTitle(WebView view, String title) {
if (TextUtils.isEmpty(getIntent().getStringExtra(WEB_TITLE))) {
if (!TextUtils.isEmpty(view.getTitle())) {
setTitle(view.getTitle());
}
}
}
//这个重新的方法是为了让js支持alert。不需要的可以去掉
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
// For Android > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
if (mUploadMessage != null) return;
mUploadMessage = uploadMsg;
if (createDefaultOpenableIntent() != null) {
startActivityForResult(createDefaultOpenableIntent(), FILE_REQUEST);
}
}
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
super.onShowFileChooser(webView, filePathCallback, fileChooserParams);
if (mFilePathCallback != null) return false;
mFilePathCallback = filePathCallback;
if (createDefaultOpenableIntent() != null) {
startActivityForResult(createCameraIntent(), FILE_REQUEST);
}
return true;
}
private Intent createDefaultOpenableIntent() {
// Create and return a chooser with the default OPENABLE
// actions including the camera, camcorder and sound
// recorder where available.
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
Intent chooser = createChooserIntent(createCameraIntent(), createCamcorderIntent(),
createSoundRecorderIntent());
chooser.putExtra(Intent.EXTRA_INTENT, i);
return chooser;
}
private Intent createChooserIntent(Intent... intents) {
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
chooser.putExtra(Intent.EXTRA_TITLE, "File Chooser");
return chooser;
}
private Intent createCameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mPictureUri = PickFileUtil.getCameraUri(getActivity());
if (mPictureUri == null) {
ToastUtil.showToast("请检查SD卡");
return null;
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPictureUri);
intent.putExtra("return-data", true);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
getActivity().grantUriPermission(getActivity().getPackageName(), mPictureUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
return intent;
}
private Intent createCamcorderIntent() {
return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
}
private Intent createSoundRecorderIntent() {
return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
}
});
上面就是需要重写的方法
接下来就是在onActivityResult方法中处理回调
@Override public void activityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FILE_REQUEST) {
Uri uri = (data != null && data.getData() != null) ? data.getData() : mPictureUri;
mPictureUri = null;
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(uri == null ? null : new Uri[] { uri });
mFilePathCallback = null;
}
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(uri);
mUploadMessage = null;
}
}
}
其中需要定义这几个成员变量
private ValueCallback<Uri[]> mFilePathCallback;
private ValueCallback<Uri> mUploadMessage;
private Uri mPictureUri;
特别需要注意的
- 因为onShowFileChooser这个方法只支持打开一下,原因http://teachcourse.cn/2224.html,
所以
mFilePathCallback.onReceiveValue(null);
mUploadMessage.onReceiveValue(null);
这两个方法特别重要,只有执行了之后,才能继续点击
- 如果是拍照的话,因为上面制定了返回的uri,所以onActivityResult中data会为null,需要从指定的uri中获取图片
mFilePathCallback.onReceiveValue(new Uri[] { mPictureUri });
mUploadMessage.onReceiveValue(mPictureUri);
下面是PickFileUtil内容
public class PickFileUtil {
private static String getCacheDir(Context context) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File baseFile = new File(Environment.getExternalStorageDirectory(), context.getPackageName());
if (baseFile.exists() || baseFile.mkdirs()) {
return baseFile.getAbsolutePath();
} else {
return context.getCacheDir().getAbsolutePath();
}
} else {
return context.getCacheDir().getAbsolutePath();
}
}
public static Uri getCameraUri(Context context) {
File pickDir = new File(getCacheDir(context), "pickDir");
File mediaFile;
if (pickDir.exists() || pickDir.mkdirs()) {
mediaFile = new File(pickDir.getPath(), "IMG_" + System.currentTimeMillis() + ".jpg");
} else {
mediaFile = new File(getCacheDir(context), "IMG_" + System.currentTimeMillis() + ".jpg");
}
if (!mediaFile.exists()) {
try {
mediaFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
if (Build.VERSION.SDK_INT >= 24) {
return FileProvider.getUriForFile(context, ImagePickUtil.getAuthorities(context), mediaFile);
} else {
return Uri.fromFile(mediaFile);
}
}
public static String getTempDir(Context context) {
File pickDir = new File(getCacheDir(context), ".tempDir");
if (pickDir.exists() || pickDir.mkdirs()) {
return pickDir.getPath();
} else {
return getCacheDir(context);
}
}
public static Uri getGalleyTempUri(Context context) {
File mediaFile = new File(getTempDir(context), "IMG_" + System.currentTimeMillis() + ".jpg");
return Uri.fromFile(mediaFile);
}
}
网友评论