照片系列之android呼叫攝像頭拍照

鴿子叼走的橘子發表於2018-12-19

變數

    private static final int TAKE_PHOTO=1;
    private Button takePhotoBtn,chooseFromAlbumBtn;
    private ImageView showImg;
    private Uri imageUri;
    private String fileurl;

動態獲取呼叫攝像機許可權

android6.0之後拍照許可權屬於危險許可權,需要動態獲取,更多危險許可權:連結 Android 執行時許可權
注意:這個要先把拍照的許可權給了

//在這裡判斷許可權是否授權
 if (ContextCompat.checkSelfPermission(PictureAc.this, Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED){
     //如果沒有請求許可權在這裡請求
     ActivityCompat.requestPermissions(PictureAc.this,new String[]{Manifest.permission.CAMERA},1);
 }else{
     if (hasSdcard()) {
           openCamera();
     }else{
           Toast.makeText(PictureAc.this,"沒有SD卡",Toast.LENGTH_LONG).show();
     }
 }
//這裡接收動態獲取許可權時候的結果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case 1:
                if (grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                    if (hasSdcard()) {
                        openCamera();
                    }else{
                        Toast.makeText(PictureAc.this,"沒有SD卡",Toast.LENGTH_LONG).show();
                    }
                }else{
                    Toast.makeText(this,"您拒絕了該許可權的獲取",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

這裡首先判斷SD卡是否存在

public static boolean hasSdcard() {
     return Environment.getExternalStorageState().equals("mounted");
}

呼叫攝像頭

然後呼叫攝像頭

@SuppressLint("WrongConstant")
    public void openCamera() {
        int currentapiVersion = Build.VERSION.SDK_INT;
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        if (hasSdcard()) {
            String pacname = Environment.getExternalStorageDirectory() + "/Pictures/";
            File dirFile = new File(pacname);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }

            fileurl = pacname + "123.jpg";
            File filename = new File(this.fileurl);
            if (filename.exists()) {
                filename.delete();
            }

            if (currentapiVersion < 24) {
                imageUri = Uri.fromFile(new File(this.fileurl));
                intent.putExtra("output", imageUri);
            } else {
                intent.addFlags(1);
                imageUri = FileProvider.getUriForFile(this, "aiom.w3studio.apps.android.sdhr.myapplication.fileprovider", new File(this.fileurl));
                intent.putExtra("output", imageUri);
            }
        }

       startActivityForResult(intent, TAKE_PHOTO);
    }

在這裡面先建立圖片儲存路徑,注意要先把許可權給了

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在這裡要特別注意:要判斷路徑是否存在,不存在的時候先建立,因為不同手機是不一樣的,有的手機當路徑不存在的時候會自動建立,但是有的手機不會自動建立,為了相容,最好將路徑建立出來。

在Android7.0系統開始,使用真實本地路徑被認為是不安全的,會丟擲異常,用FileProvider來對資料進行封裝共享給外部,從而提供應用的安全性,第一個引數傳content物件,第二個引數可以是任意的唯一字串,引數三是file物件

拍照回撥

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case TAKE_PHOTO:
                if (resultCode==RESULT_OK){
                    Toast.makeText(PictureAc.this,"攝像頭呼叫成功!",Toast.LENGTH_LONG).show();

                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    //不會載入,只會獲取圖片的一個尺寸
                    //options裡面儲存了圖片的高度和寬度
                    //讀取檔案
                    BitmapFactory.decodeFile(fileurl ,options);
                    //改變圖片的大小
                    double ratio = Math.max(options.outWidth *1.0d/1024f,options.outHeight *1.0d/1024);
                    options.inSampleSize =(int) Math.ceil(ratio);
                    //設定後會載入圖片
                    options.inJustDecodeBounds = false;
                    //圖片壓縮完成
                    Bitmap bitmap=  BitmapFactory.decodeFile(fileurl ,options);
                    showImg.setImageBitmap(bitmap);

                }
                break;
            default:
                break;
        }
    }

這裡需要注意的是,直接放照片會有顯示不出來的現象,所以要壓縮一下圖片顯示,並且,在指定Uri的情況下data返回的會是空,所以這時候就不要使用data獲取值了

效果展示

在這裡插入圖片描述

相關文章