有时候我们需要在H5中调用Android的相机与相册,前段时间项目中用到了,鼓捣了一波。
老样子,拷贝代码就好使!
首先整个工具类,先访问一下相机权限:
public class Authority {
private static final int MY_PERMISSION_REQUEST_CODE = 10000;
//申请的权限,字符串模式
public static final String CALL_PHONE = Manifest.permission.CALL_PHONE;//打电话权限
public static final String CAMERA = Manifest.permission.CAMERA;//相机摄像头权限
public static final String READ_EXTERNAL_STORAGE = Manifest.permission.READ_EXTERNAL_STORAGE;//读取内存卡权限
public static final String WRITE_EXTERNAL_STORAGE = Manifest.permission.WRITE_EXTERNAL_STORAGE;//写入内存卡权限
//申请的权限,数组模式
public static final String[] CALL_PHONE_ARR = {Manifest.permission.CALL_PHONE};//打电话权限
public static final String[] CAMERA_ARR = {Manifest.permission.CAMERA};//相机摄像头权限
public static final String[] READ_EXTERNAL_STORAGE_ARR = {Manifest.permission.READ_EXTERNAL_STORAGE};//读取内存卡权限
public static final String[] WRITE_EXTERNAL_STORAGE_ARR = {Manifest.permission.WRITE_EXTERNAL_STORAGE};//写入内存卡权限
//权限数组
public static final String[] str = {
Manifest.permission.CALL_PHONE,//打电话
Manifest.permission.CAMERA, //相机
// Manifest.permission.ACCESS_NETWORK_STATE,//网络
// Manifest.permission.ACCESS_WIFI_STATE,//wifi
// Manifest.permission.CHANGE_WIFI_STATE,//wifi
// Manifest.permission.INTERNET,//网络
Manifest.permission.READ_EXTERNAL_STORAGE,//获取sd
Manifest.permission.WRITE_EXTERNAL_STORAGE//写入sd
};
//申请权限,多项申请(Activity)
public static void CallMobile(Activity mContext) {
ActivityCompat.requestPermissions(
mContext,
str,
MY_PERMISSION_REQUEST_CODE//回调的标识
);
}
//申请权限,单项权限,(Activity)
public static void CallMobileArr(Activity mContext, String[] str) {
ActivityCompat.requestPermissions(
mContext,
str,
MY_PERMISSION_REQUEST_CODE//回调的标识
);
}
//申请权限(fragment)
// requestPermissions(Authority.CAMERA_ARR, 10000);这种模式,不可以显示申请权限弹框.如果禁止所申请的权限,可以显示自定义弹框
//下面这种模式:可以显示申请权限弹框.如果禁止所申请的权限,并且“下次不会再次提醒”已勾选,不会显示弹框
@TargetApi(Build.VERSION_CODES.M)
public static void CallMobileFragment(Activity mContext, String[] str) {
mContext.requestPermissions(str, MY_PERMISSION_REQUEST_CODE);
}
//判断权限是否申请通过
public static boolean lacksPermission(Context mContexts, String permission) {
return ContextCompat.checkSelfPermission(mContexts, permission) ==
PackageManager.PERMISSION_DENIED;
}
/**
* @param s 提示语
* @param applicationContext 上下文
* @param type 类型,是否关闭页面 1关闭,0不关闭
*/
public static void openAppDetails(String s, final Activity applicationContext, final int type) {
final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(applicationContext);
builder.setMessage(s);
builder.setCancelable(false);
builder.setPositiveButton("去手动授权", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("package:" + applicationContext.getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
applicationContext.startActivity(intent);
if (type == 1) {
applicationContext.finish();
}
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (type == 1) {
applicationContext.finish();
}
}
});
builder.show();
}
//设置popu背景色
public static void setBackgroundAlpha(float bgAlpha, Activity mContext) {
WindowManager.LayoutParams lp = mContext.getWindow()
.getAttributes();
lp.alpha = bgAlpha;
mContext.getWindow().setAttributes(lp);
}
}
然后是Activity部分,申请相机权限:
Authority.CallMobileArr(LiangFangActivity.this, new String[]{Manifest.permission.CAMERA});
相机权限的回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 10000) {
int isClose = 0;
for (int i = 0; i < permissions.length; i++) {
if (permissions[i].equals(Manifest.permission.CAMERA) || permissions[i].equals(Manifest.permission.READ_EXTERNAL_STORAGE) || permissions[i].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
if (grantResults[i] == -1) {
isClose = 1;
final android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(LiangFangActivity.this);
builder.setMessage("摄像头权限和存储权限为必要的权限。\n由于您拒绝了,这导致您无法正常使用该应用。");
builder.setCancelable(false);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
LiangFangActivity.this.finish();
}
});
builder.show();
}
}
}
}
}
下面正文部分
写了个方法,在onCreat方法里调用即可
private void setCheckImg() {
mLiangFangWebView.setWebChromeClient(new WebChromeClient() {
// For Android < 3.0
public void openFileChooser(ValueCallback<Uri> valueCallback) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 3.0
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
//For Android >= 4.1
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
uploadMessage = valueCallback;
openImageChooserActivity();
}
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
openImageChooserActivity();
return true;
}
});
}
然后选择弹出了一个选择框,相机还是相册
private void openImageChooserActivity() {
AlertDialog dialog = new AlertDialog.Builder(this)
.setMessage("请选择")
.setPositiveButton("相机", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
time = Calendar.getInstance().getTimeInMillis();
// file = new File(Environment.getExternalStorageDirectory().getPath()+"/", time + ".jpg");
pathTakePhoto = Environment.getExternalStorageDirectory().getPath()
+ "/mbossclient/camera/temp/"
+ (System.currentTimeMillis() + ".jpg");
File vFile = new File(pathTakePhoto);
if (!vFile.exists()) {
File vDirPath = vFile.getParentFile();
vDirPath.mkdirs();
Log.e("alshdkash", "onClick: " + vFile.getPath());
} else {
if (vFile.exists()) {
vFile.delete();
}
}
//App是一个继承Application的类,此处是需要获取一个全局的上下文即可
photoURI = FileProvider.getUriForFile(LiangFangActivity.this, App.context.getApplicationContext().getPackageName() + ".provider", vFile);
// uriTakePhoto = Uri.fromFile(vFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE1);
}
}).setNegativeButton("相册", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
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);
}
}).create();
dialog.show();
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
cancelFilePathCallback();
}
});
}
如果不选择的话,调用此方法。需要一个返回值,没有返回值会导致无法再次调起相机相册,需要重新进入
private void cancelFilePathCallback() {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
} else if (uploadMessageAboveL != null) {
uploadMessageAboveL.onReceiveValue(null);
uploadMessageAboveL = null;
}
}
然后是相机,相册的回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == uploadMessage && null == uploadMessageAboveL) {
return;
}
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(result);
uploadMessage = null;
}
} else if (requestCode == FILE_CHOOSER_RESULT_CODE1) {
if (uploadMessageAboveL != null) {
Uri[] results2 = {photoURI};
uploadMessageAboveL.onReceiveValue(results2);
uploadMessageAboveL = null;
// onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(photoURI);
uploadMessage = null;
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
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)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}