第一行代碼筆記 獲取拍照照片和相冊選取照片

示例:

public class GetPicActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView showImg;
    private Uri imageUri;
    public static final int TAKE_PHOTO = 1;
    public static final int CHOOSE_PHOTO = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_get_pic);
        initView();
    }

    private void initView() {
        findViewById(R.id.getPicFromCamera).setOnClickListener(this);
        findViewById(R.id.getPicFromAblum).setOnClickListener(this);

        showImg = ((ImageView) findViewById(R.id.showImg));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.getPicFromCamera:
                getPicFromCamra();
                break;
            case R.id.getPicFromAblum:
                getPicFromAblum();
                break;
        }
    }

    private void getPicFromCamra() {
//        創建file對象,用於存儲拍照後的圖片,通過getExternalCacheDir放在應用關聯緩存目錄
//        具體路徑是/sdcard/Android/data/<packeageName>/cache,android6.0讀寫sd卡爲
//        危險權限,需要運行時權限,而放應用關聯緩存不要
        File outPutImage = new File(getExternalCacheDir(), "output_img.jpg");

        try {
            if (outPutImage.exists()) {
                outPutImage.delete();
            }
            outPutImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (Build.VERSION.SDK_INT >= 24) {
//         android7.0直接使用本地真實路徑uri是不安全的,通過FileProvider是一種特殊的內容提供器
//         可以選擇性的將封裝過的uri提供給外部,提高安全性。參數1:context對象。參數二:可以是任意的字符串,
//          參數三:剛剛創建的file對象。注意這裏用到了內容提供者
            imageUri = FileProvider.getUriForFile(GetPicActivity.this, "com.lvyequeen.test.day04.getpic", outPutImage);
        } else {
//            獲取的是這張圖片的真是路徑
            imageUri = Uri.fromFile(outPutImage);
        }

//        用意圖打開相機
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
//        指定圖片輸出地址
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//        隱示意圖啓動
        startActivityForResult(intent, TAKE_PHOTO);

    }


    /**
     * 通過相冊獲取圖片
     */
    private void getPicFromAblum() {
//        判斷授予sd卡讀寫權限
        if (ContextCompat.checkSelfPermission(GetPicActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(GetPicActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            openAblum();
        }
    }

    /**
     * 打開相冊
     */
    private void openAblum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent, CHOOSE_PHOTO);

    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case TAKE_PHOTO:
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                        showImg.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                    break;
                case CHOOSE_PHOTO:
                    if (Build.VERSION.SDK_INT >= 19) {
//                        4.4及以上系統,選取相冊中的圖片不再返回圖片真實的uri
                        handleImageOnKitKat(data);
                    } else {
                        handleImagebeforeKitKat(data);
                    }
                    break;
            }
        }
    }


    @TargetApi(Build.VERSION_CODES.KITKAT)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
//        如果uri是document類型,就通過讀取document id進行處理
        if (DocumentsContract.isDocumentUri(this, uri)) {
            String docId = DocumentsContract.getDocumentId(uri);
//            如果Uri的Authority是media格式的話,document id還需要進行解析,然後通過字符串
//            分割方式取出後半部分才能得到真正的數字id
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads,documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads.public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
//            如果是content類型的uri,則使用普通方式處理
            imagePath = getImagePath(uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
//            如果是file類型,直接獲取圖片路徑
            imagePath = uri.getPath();
        }
        displayImage(imagePath);
    }


    private void handleImagebeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);

    }


    /**
     * 獲取圖片真實路徑
     *
     * @param uri
     * @param selection
     * @return
     */
    private String getImagePath(Uri uri, String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (null != cursor) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    /**
     * 根據圖片路徑顯示圖片
     *
     * @param imagePath
     */
    private void displayImage(String imagePath) {
        if (null != imagePath) {
            Bitmap b = BitmapFactory.decodeFile(imagePath);
            showImg.setImageBitmap(b);
        } else {
            Toast.makeText(this, "獲取圖片失敗", Toast.LENGTH_LONG).show();
        }
    }


    /**
     * 處理權限的
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openAblum();
                } else {
                    Toast.makeText(this, "沒有權限啦~~", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }


}


注意事項:拍照上傳的時候用到了內容提供者要去清單文件中註冊,寫在application裏面的

<!--這裏註冊拍照那個內容提供者android:name爲固定值
android:authorities和FileProvider.getUriForFile
第二個參數值一樣 。meta-data指定uri共享路徑,創建@xml/file_paths文件
-->
<provider
    android:authorities="com.lvyequeen.test.day04.getpic"
    android:name="android.support.v4.content.FileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"
        />
</provider>

在res文件夾下面創建一個xml文件夾,再在此文件夾下創建的file_path.xml

<?xml version="1.0" encoding="utf-8"?>

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--external-path用來指定uri共享的 name隨意填寫,path標示恭喜那個的具體路徑,
    設置爲空則表示將整個sd卡進行共享。也可以寫定一個路徑
    -->
    <external-path
        name="my_images"
        path="" />

</paths>





發佈了44 篇原創文章 · 獲贊 8 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章