1. 程式人生 > >Android 7 呼叫系統相機

Android 7 呼叫系統相機

前言:

Android M相比6.0以前的需要許可權,其他的跟之前的沒區別:

if ((ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)||
        (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
    //如果沒有授權,則請求授權
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } else {
// create Intent to take a picture and return control to the calling application
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image
File file = new File(Environment.getExternalStorageDirectory().getPath(), "camera.png"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name // start the image capture Intent startActivityForResult(intent, 1);
而7.0開始,為了安全,需要使用FileProvider了,就不能用上面那行紅色程式碼了:
if ((ContextCompat
.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)|| (ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) { //如果沒有授權,則請求授權 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } else { //有授權,直接開啟攝像頭 //6.0 camera /*Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); File file = new File("/mnt/sdcard", "camera.png"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); // set the image file name startActivityForResult(intent, 1);*/ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager())!=null){ File photoFile = null; try { photoFile = createImageFile();//建立臨時圖片檔案,方法在下面 } catch (IOException e) { e.printStackTrace(); } if (photoFile != null) { //FileProvider 是一個特殊的 ContentProvider 的子類, //它使用 content:// Uri 代替了 file:/// Uri. ,更便利而且安全的為另一個app分享檔案 Uri photoURI = FileProvider.getUriForFile(this, "com.sat.android.fileprovider", photoFile); intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(intent, 1); } } }
createImageFile():
String mCurrentPhotoPath;
private File createImageFile() throws IOException {
    // Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
//.getExternalFilesDir()方法可以獲取到 SDCard/Android/data/你的應用的包名/files/ 目錄,一般放一些長時間儲存的資料
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
/*File storageDir = new File(Environment.getExternalStorageDirectory(), "images");
    if (!storageDir.exists()) storageDir.mkdirs();*/
Log.d("TAH",storageDir.toString());
//建立臨時檔案,檔案字首不能少於三個字元,字尾如果為空預設未".tmp"
File image = File.createTempFile(
            imageFileName,  /* 字首 */
".jpg",         /* 字尾 */
storageDir      /* 資料夾 */
);
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
然後需要在manifest檔案中配置:
<provider
android:authorities="com.sat.android.fileprovider" //與FileProvider.getUriForFile第二個引數相同
android:name="android.support.v4.content.FileProvider"
android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"/></provider> 新建/res/xml/file_paths:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.sat.a10_6_/files/Pictures" />
</paths>
注意:path的值要與
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
的值一樣,省略前面的"/storage/emulatored/0/",不然會奔潰,我也不知道為什麼,再研究研究。。。