Android 相冊選擇照片或拍照獲取圖片系統6.0及7.0實現

6.0及6.0以上權限動態詢問

 private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 6;
 private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE2 = 7;

 //手機拍照
        camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(getApplicationContext(),
                        Manifest.permission.CAMERA)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ReviewActivity.this,
                            new String[]{Manifest.permission.CAMERA},
                            MY_PERMISSIONS_REQUEST_CALL_PHONE);
                } else {
                    photo();
                    dialog.dismiss();
                }
            }
        });



 //從相冊選擇圖片
        photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(getApplicationContext(),
                        Manifest.permission.WRITE_EXTERNAL_STORAGE)
                        != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(ReviewActivity.this,
                            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                            MY_PERMISSIONS_REQUEST_CALL_PHONE2);

                } else {
                    int selectedMode;
                    selectedMode = MultiImageSelectorActivity.MODE_MULTI;
                    int maxNum = 9 - drr.size();
                    Intent intent = new Intent(ReviewActivity.this,                             MultiImageSelectorActivity.class); 
                    // 是否顯示拍攝圖片
                    intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, false);
                    // 最大可選擇圖片數量
                    intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, maxNum);
                    // 選擇模式
                    intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, selectedMode);

                    startActivityForResult(intent, RESULT_LOAD_IMAGE);
                    dialog.dismiss();
                }

            }
        });


 /**
     * 拍照方法代碼
     */
    public void photo() {
        try {
            if (hasSdcard()) {
                String sdcardState = Environment.getExternalStorageState();
                String sdcardPathDir = Environment.getExternalStorageDirectory().getPath() + "/tempImage/";
                File file = null;

                if (Environment.MEDIA_MOUNTED.equals(sdcardState)) {
                    // 有sd卡,是否有myImage文件夾
                    File fileDir = new File(sdcardPathDir);
                    if (!fileDir.exists()) {
                        fileDir.mkdirs();
                    }
                    // 是否有headImg文件
                    file = new File(sdcardPathDir + System.currentTimeMillis() + ".JPEG");
                }
                if (file != null) {
                    path = file.getPath();
                    photoUri = Uri.fromFile(file);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        //通過FileProvider創建一個content類型的Uri
                        photoUri = FileProvider.getUriForFile(ReviewActivity.this, "com.zuihou.drunkenmonkey.fileprovider", file);
                    }
                    Intent openCameraIntent = new Intent();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        openCameraIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加這一句表示對目標應用臨時授權該Uri所代表的文件
                    }
                    openCameraIntent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
                    openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                    startActivityForResult(openCameraIntent, TAKE_PICTURE);
                }
            } else {
                ToastUtil.showToast(getApplicationContext(), "設備沒有SD卡!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 檢查設備是否存在SDCard的工具方法
     */
    public static boolean hasSdcard() {
        String state = Environment.getExternalStorageState();
        return state.equals(Environment.MEDIA_MOUNTED);
    }

這裏有一句代碼:

FileProvider.getUriForFile(ReviewActivity.this, "com.zuihou.drunkenmonkey.fileprovider", file);

在用Android 7.0版本時,調用相機拍照出現了異常 FileUriExposedException,就是在傳遞uri時出錯 Android 7.0後又修改了文件權限,可以使用FileProvider解決

在項目res目錄下創建xml文件夾

<?xml version="1.0" encoding="utf-8"?>
<paths>
<!--        xml文件是唯一設置分享的目錄 ,不能用代碼設置

         1.<files-path>        getFilesDir()  /data/data//files目錄
         2.<cache-path>        getCacheDir()  /data/data//cache目錄

         3.<external-path>     Environment.getExternalStorageDirectory()

         SDCard/Android/data/你的應用的包名/files/ 目錄
         4.<external-files-path>     Context#getExternalFilesDir(String) Context.getExternalFilesDir(null).
         5.<external-cache-path>      Context.getExternalCacheDir().
     -->

    <!--    path :代表設置的目錄下一級目錄 eg:<external-path path="images/"
                整個目錄爲Environment.getExternalStorageDirectory()+"/images/"
            name: 代表定義在Content中的字段 eg:name = "myimages" ,並且請求的內容的文件名爲default_image.jpg
                則 返回一個URI   content://com.example.myapp.fileprovider/myimages/default_image.jpg
    -->


    <!--當path 爲空時 5個全配置就可以解決-->


    <external-path
        name="camera_photos"
        path="" />
</paths>

在manifest.xml文件添加provider,相機,讀寫文件權限

  <provider
            android:name="android.support.v4.content.FileProvider"   //固定值
            android:authorities="com.zuihou.drunkenmonkey.fileprovider"  //前面爲項目的包名,fileprovider固定
            android:exported="false" //是否支持其它應用調用當前組件 ,要求爲flase
            android:grantUriPermissions="true">  
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS" //固定值
                android:resource="@xml/file_paths" /> //在res目錄下定義的filepaths.xml文件,名字可以自定義
        </provider>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

獲取權限後返回結果代碼

 @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                photo();
            } else {
                // Permission Denied
                ToastUtil.showToast(ReviewActivity.this, "Permission Denied");
            }
        }

        if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE2) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                int selectedMode;
                selectedMode = MultiImageSelectorActivity.MODE_MULTI;
                int maxNum = 9 - drr.size();
                Intent intent = new Intent(ReviewActivity.this, MultiImageSelectorActivity.class);
                // 是否顯示拍攝圖片
                intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, false);
                // 最大可選擇圖片數量
                intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, maxNum);
                // 選擇模式
                intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, selectedMode);

                startActivityForResult(intent, RESULT_LOAD_IMAGE);

                dialog.dismiss();
            } else {
                // Permission Denied
                ToastUtil.showToast(ReviewActivity.this, "Permission Denied");
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章