原文地址 : 相机启动适配 感谢大神的代码,非常好用!
1.现象
在项目中调用相机拍照和录像的时候,android4.x,Android5.x,Android6.x均没有问题,在Android7.x下面直接闪退
2.原因分析
android升级到7.0后对权限又做了一个更新即不允许出现以file://的形式调用隐式APP,需要用共享文件的形式:content:// URI
3.解决方案
下面是打开系统相机的方法,做了android各个版本的兼容:
importandroid.app.Activity;
importandroid.content.ContentValues;
importandroid.content.Intent;
importandroid.net.Uri;
importandroid.os.Environment;
importandroid.provider.MediaStore;
importcom.qhcloud.filetransfer.TransferApp;
importjava.io.File;
importjava.io.IOException;
importjava.text.SimpleDateFormat;
importjava.util.Date;
/**
* Function:相机工具类
* 调用相机拍照
* 调用相机录像并保存到目录
* Created by xuzhuyun on 2017/3/2.
*/
publicclassCameraUtil {
publicstaticFile tempFile;
publicstaticfinalintPHOTO_REQUEST_CAREMA =1;// 拍照
publicstaticfinalintCAPTURE_VIDEO_ACTIVITY_REQUEST_CODE =2;// 拍摄视频
/**
* 打开相机拍照
*
* @param activity
*/
publicstaticvoidopenCamera(Activity activity) {
//獲取系統版本
intcurrentapiVersion = android.os.Build.VERSION.SDK_INT;
// 激活相机
Intent intent =newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
// 判断存储卡是否可以用,可用进行存储
if(hasSdcard()) {
SimpleDateFormat timeStampFormat =newSimpleDateFormat(
"yyyy_MM_dd_HH_mm_ss");
String filename = timeStampFormat.format(newDate());
tempFile =newFile(Environment.getExternalStorageDirectory(),
filename +".jpg");
if(currentapiVersion <24) {
// 从文件中创建uri
Uri uri = Uri.fromFile(tempFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}else{
//兼容android7.0 使用共享文件的形式
ContentValues contentValues =newContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());
Uri uri = TransferApp.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
}
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CAREMA
activity.startActivityForResult(intent, PHOTO_REQUEST_CAREMA);
}
/**
* 打开相机录像
*/
publicstaticvoidstartToVideo(Activity activity) {
//獲取系統版本
intcurrentapiVersion = android.os.Build.VERSION.SDK_INT;
Uri fileUri =null;
File file =null;
Intent intent =newIntent(MediaStore.ACTION_VIDEO_CAPTURE);
try{
file = createMediaFile();
if(file.exists()) {
fileUri = Uri.fromFile(file);// create a file to save the video
}
}catch(IOException e) {
e.printStackTrace();
}
if(currentapiVersion <24) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);// set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY,1);// set the video image quality to high
}else{
//兼容android7.0
ContentValues contentValues =newContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
Uri uri = activity.getApplication().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
// start the Video Capture Intent
activity.startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
/*
* 判断sdcard是否被挂载
*/
publicstaticbooleanhasSdcard() {
returnEnvironment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
/**
* 创建保存录制得到的视频文件
*
* @return
* @throws IOException
*/
publicstaticFile createMediaFile()throwsIOException {
if(hasSdcard()) {
File mediaStorageDir =newFile(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES),"CameraVideos");
if(!mediaStorageDir.exists()) {
if(!mediaStorageDir.mkdirs()) {
returnnull;
}
}
// Create an image file name
String timeStamp =newSimpleDateFormat("yyyyMMdd_HHmmss").format(newDate());
String imageFileName ="VID_"+ timeStamp;
String suffix =".mp4";
File mediaFile =newFile(mediaStorageDir + File.separator + imageFileName + suffix);
returnmediaFile;
}
returnnull;
}
}