1. H5 可以直接拍照 通过 WebChromeClient 来处理
// 辅助处理JavaScript、页喧解析渲染、页面标题、加载进度等等
mWebView.setWebChromeClient(commonWebChromeClient);
2. 重写 WebChromeClient 方法 onShowFileChooser 5.0 及以上和openFileChooser 4-5.0
获取参数 这两对象接收拍照完后的流
public ValueCallback<Uri> mUploadMessage; 5.0以下
public ValueCallback<Uri[]> uploadMessage; 5.0 及其以上
3. 拍照调用
Intent takeIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
//下面这句指定调用相机拍照后的照片存储的路径
takeIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (new File (mTempPhotoPath)));
startActivityForResult (takeIntent, REQUEST_SELECT_FILE);
4.拍照结果回调
拍照回传后的intent 数据为空
需要对 path 进行处理
5.0 及其以上
uploadMessage.onReceiveValue (new Uri[]{Uri.fromFile (new File (mTempPhotoPath))});
uploadMessage = null;
5.0以下:
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData ();
if (result == null) {
//多操作了一步
Uri[] ll = new Uri[]{Uri.fromFile (new File (mTempPhotoPath))};
if (ll != null && ll.length > 0) {
result = ll[0];
}
}
mUploadMessage.onReceiveValue (result);
mUploadMessage = null;
5.0及以下 获取Uri 的方法是否只有这一种??
File file = new File(PictureUtil.bitmapToPath(sourcePath));
Uri uri = Uri.fromFile(file);
其他方法:
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i,"Image Chooser"),FILE_CHOOSER_RESULT_CODE);
文件:Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/");
startActivityForResult(Intent.createChooser(i, "File Browser"), RESULTCODE);
??
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/");
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
相册 :Intent pickIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(pickIntent, CODE);
9 Intent.ACTION_CHOOSER
String: android.intent.action.CHOOSER显示一个activity选择器,允许用户在进程之前选择他们想要的,与之对应的是Intent.ACTION_GET_CONTENT.
10. Intent.ACTION_GET_CONTENT
String: android.intent.action.GET_CONTENT允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
Input: TypeOutput:URI
int requestCode = 1001;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); // "android.intent.action.GET_CONTENT"
intent.setType("image/*"); // 查看类型,如果是其他类型,比如视频则替换成 video/*,或 */*
Intent wrapperIntent = Intent.createChooser(intent, null);
startActivityForResult(wrapperIntent, requestCode);
//拍照 REQUEST_CODE_TAKE_PICTURE 为返回的标识
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //"android.media.action.IMAGE_CAPTURE";
intent.putExtra(MediaStore.EXTRA_OUTPUT, Mms.ScrapSpace.CONTENT_URI); // output,Uri.parse("content:/s/scrapSpace");
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
//添加音视频
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(contentType); //String VIDEO_UNSPECIFIED = "video/*";
Intent wrapperIntent = Intent.createChooser(intent, null);
((Activity) context).startActivityForResult(wrapperIntent, requestCode);
//拍摄视频
int durationLimit = getVideoCaptureDurationLimit(); //SystemProperties.getInt("ro.media.enc.lprof.duration", 60);
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO);
//录音
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContentType.AUDIO_AMR); //String AUDIO_AMR = "audior";
intent.setClassName("com.android.soundrecorder",
"com.android.soundrecorder.SoundRecorder");
((Activity) context).startActivityForResult(intent, requestCode);
Activity 或者Fragment
mPermissionHelper 为android 6.0权限 处理的类
public ValueCallback<Uri> mUploadMessage;
public ValueCallback<Uri[]> uploadMessage;
private String mTempPhotoPath;//拍照照片路径
onCreate(){//处理路径逻辑
initPhotoPath();
}
//添加权限判断 H5调用原生拍照
private void initPhotoPath() {
if (mPermissionHelper != null) {
Map<String, String> permissionMap1 = new HashMap<> ();
permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
if (mPermissionHelper.hasPermiss1 (getActivity (), permissionMap1)) {
if (Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ())) {//如果已经挂载
//sd卡已经挂载,可以进行读写操作了
mTempPhotoPath = Environment.getExternalStorageDirectory () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
} else {
//sd卡无挂载,使用内置存储卡
mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
}
} else {
//使用内置存储卡,可以进行读写操作了
mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + ".jpeg";
}
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_SELECT_FILE://H5调用原生拍照
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
onActivityResultAboveL (requestCode, resultCode, data);
} else {
onActivityResultDown (requestCode, resultCode, data);
}
break;
default:
break;
}
}
//android 5.0 及其以上 H5调用原生拍照
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
//如果没有接受者
if (uploadMessage == null) {//没有接受者
return;
}
//如果结果码为取消
if (resultCode == RESULT_CANCELED) {
cancelCallback ();
return;
}
switch (requestCode) {
case REQUEST_SELECT_FILE://拍照
uploadMessage.onReceiveValue (new Uri[]{Uri.fromFile (new File (mTempPhotoPath))});
uploadMessage = null;
break;
default:
Uri[] results = null;
if (intent != null) {
String dataString = intent.getDataString ();
ClipData clipData = intent.getClipData ();
if (clipData != null) {
results = new Uri[clipData.getItemCount ()];
for (int i = 0; i < clipData.getItemCount (); i++) {
ClipData.Item item = clipData.getItemAt (i);
results[i] = item.getUri ();
}
}
if (dataString != null) {
results = new Uri[]{Uri.parse (dataString)};
}
}
uploadMessage.onReceiveValue (results);
uploadMessage = null;
break;
}
}
//android 5.0 以下 H5调用原生拍照
private void onActivityResultDown(int requestCode, int resultCode, Intent intent) {
//如果没有接受者
if (null == mUploadMessage) {
return;
}
//如果结果码为取消
if (resultCode == RESULT_CANCELED) {
cancelCallback ();
return;
}
switch (requestCode) {
case REQUEST_SELECT_FILE://拍照
// Use MainActivity.RESULT_OK if you're implementing WebView inside Fragment
// Use RESULT_OK only if you're implementing WebView inside an Activity
Uri result = intent == null || resultCode != RESULT_OK ? null : intent.getData ();
if (result == null) {
Uri[] ll = new Uri[]{Uri.fromFile (new File (mTempPhotoPath))};
if (ll != null && ll.length > 0) {
result = ll[0];
}
}
mUploadMessage.onReceiveValue (result);
mUploadMessage = null;
break;
default:
Uri result1 = (intent == null ? null : intent.getData());
mUploadMessage.onReceiveValue(result1);
mUploadMessage=null;
break;
}
}
//添加权限判断 H5调用原生拍照
private void initPhotoPath() {
if (mPermissionHelper != null) {
Map<String, String> permissionMap1 = new HashMap<> ();
permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
if (mPermissionHelper.hasPermiss1 (getActivity (), permissionMap1)) {
if (Environment.MEDIA_MOUNTED.equals (Environment.getExternalStorageState ())) {//如果已经挂载
//sd卡已经挂载,可以进行读写操作了
mTempPhotoPath = Environment.getExternalStorageDirectory () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
} else {
//sd卡无挂载,使用内置存储卡
mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
}
} else {
//使用内置存储卡,可以进行读写操作了
mTempPhotoPath = this.getActivity ().getFilesDir () + File.separator + System.currentTimeMillis () / 1000 + "s.jpeg";
}
}
}
//H5 默认拍照处理 H5调用原生拍照
public void h5Capture() {
if (mPermissionHelper == null) {
mPermissionHelper = new PermissionHelper ();
}
Map<String, String> permissionMap1 = new HashMap<> ();
permissionMap1.put (Manifest.permission.CAMERA, AppOpsManager.OPSTR_CAMERA);
permissionMap1.put (Manifest.permission.WRITE_EXTERNAL_STORAGE, AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE);
mPermissionHelper.checkPermission (getActivity (), new OnPermissionListener () {
@Override
public void OnPermissonResult(boolean agreed) {
if (agreed) {
try {
Intent takeIntent = new Intent (MediaStore.ACTION_IMAGE_CAPTURE);
//下面这句指定调用相机拍照后的照片存储的路径
takeIntent.putExtra (MediaStore.EXTRA_OUTPUT, Uri.fromFile (new File (mTempPhotoPath)));
startActivityForResult (takeIntent, REQUEST_SELECT_FILE);
} catch (Exception e) {
MyToast.showShort ("禁止上传");
}
} else {
MyToast.showShort ("相机或存储权限被禁止,请在设置中开启拍照或存储权限");
}
}
}, permissionMap1);
}
/**
*
* H5调用原生拍照
*/
public void cancelCallback() {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue (null);
mUploadMessage = null;
}
if (uploadMessage != null) {
uploadMessage.onReceiveValue (null);
uploadMessage = null;
}
}
public class CommonWebChromeClient extends WebChromeClient {
private String LOG_TAG = "WebChromeClient";
// 使用者提供的Context
private WeakReference<WebviewFragment> mUserContext;
public CommonWebChromeClient(WebviewFragment context) {
mUserContext =new WeakReference (context) ;
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
try {
String[] acceptTypes=fileChooserParams.getAcceptTypes ();
String type="";
if(acceptTypes!=null&&acceptTypes.length>0){
type=acceptTypes[0];
}
if (mUserContext.get ().uploadMessage != null) {
mUserContext.get ().uploadMessage.onReceiveValue (null);
mUserContext.get ().uploadMessage = null;
}
mUserContext.get ().uploadMessage = filePathCallback;
//返回对实时媒体捕获值(例如照相机、麦克风)的首选项 True indicates capture is enabled, false disabled.
//默认拍照
//capture 可用与否
if(fileChooserParams.isCaptureEnabled ()){
if(type.contains ("image")){//拍照
mUserContext.get ().h5Capture ();
}else if(type.contains ("video")){
}else if(type.contains ("audio")){
}else {//默认拍照
mUserContext.get ().h5Capture ();
}
}else{//设备不可用,什么都不做 ---可以 处理为 相册
mUserContext.get ().uploadMessage.onReceiveValue (null);
mUserContext.get ().uploadMessage = null;
}
return true;
} catch (Exception e) {
e.printStackTrace ();
}
return super.onShowFileChooser (webView, filePathCallback, fileChooserParams);
}
//5.0 一下,3.0
public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType) {
try {
mUserContext.get ().mUploadMessage = uploadFile;
mUserContext.get ().h5Capture ();
} catch (Exception e) {
e.printStackTrace ();
}
}
//5.0 一下,4.0 以上处理逻辑 针对 Android版本 > 4.1.1
public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
try {
mUserContext.get ().mUploadMessage = uploadFile;
mUserContext.get ().h5Capture ();
} catch (Exception e) {
e.printStackTrace ();
}
}
}
网友评论