1.问题:
在项目中调用相机拍照和录像的时候,android4.x,Android5.x,Android6.x均没有问题,在Android7.x下面直接闪退
2.分析:
Android升级到7.0后对权限又做了一个更新即不允许出现以file://的形式调用隐式APP,需要用共享文件的形式:content:// URI
3.解决方案
下面是打开系统相机的方法,做了android各个版本的兼容:
- import android.app.Activity;
- import android.content.ContentValues;
- import android.content.Intent;
- import android.net.Uri;
- import android.os.Environment;
- import android.provider.MediaStore;
- import com.qhcloud.filetransfer.TransferApp;
- import java.io.File;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- /**
- * Function:相机工具类
- * 调用相机拍照
- * 调用相机录像并保存到目录
- * Created by xuzhuyun on 2017/3/2.
- */
- public class CameraUtil {
- public static File tempFile;
- public static final int PHOTO_REQUEST_CAREMA = 1;// 拍照
- public static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 2;// 拍摄视频
- /**
- * 打开相机拍照
- *
- * @param activity
- */
- public static void openCamera(Activity activity) {
- //獲取系統版本
- int currentapiVersion = android.os.Build.VERSION.SDK_INT;
- // 激活相机
- Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
- // 判断存储卡是否可以用,可用进行存储
- if (hasSdcard()) {
- SimpleDateFormat timeStampFormat = new SimpleDateFormat(
- "yyyy_MM_dd_HH_mm_ss");
- String filename = timeStampFormat.format(new Date());
- tempFile = new File(Environment.getExternalStorageDirectory(),
- filename + ".jpg");
- if (currentapiVersion < 24) {
- // 从文件中创建uri
- Uri uri = Uri.fromFile(tempFile);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
- } else {
- //兼容android7.0 使用共享文件的形式
- ContentValues contentValues = new ContentValues(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);
- }
- /**
- * 打开相机
- */
- public static void startToVideo(Activity activity) {
- //系統版本
- int currentapiVersion = android.os.Build.VERSION.SDK_INT;
- Uri fileUri = null;
- File file = null;
- Intent intent = new Intent(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 = new ContentValues(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是否被挂载
- */
- public static boolean hasSdcard() {
- return Environment.getExternalStorageState().equals(
- Environment.MEDIA_MOUNTED);
- }
- /**
- * 创建保存录制得到的视频文件
- *
- * @return
- * @throws IOException
- */
- public static File createMediaFile() throws IOException {
- if (hasSdcard()) {
- File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_MOVIES), "CameraVideos");
- if (!mediaStorageDir.exists()) {
- if (!mediaStorageDir.mkdirs()) {
- return null;
- }
- }
- // Create an image file name
- String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
- String imageFileName = "VID_" + timeStamp;
- String suffix = ".mp4";
- File mediaFile = new File(mediaStorageDir + File.separator + imageFileName + suffix);
- return mediaFile;
- }
- return null;
- }
- }