Android7.0下调用相机闪退的解决方案

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;  
    }  
}  

以上是做了android7.0兼容处理的工具类,录像时保存到了指定目录。

你可能感兴趣的:(Android,android)