android 8.0 调用相机 打开相册

  1. 添加依赖
//动态权限
    implementation 'pub.devrel:easypermissions:2.0.1'

  1. 添加权限
    
    
    
    

在清单文件中注册内容提供器, android:authorities 属性的值要和FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage)中第二个参数的值一样

        
            
        

创建@xml/file_paths




    

申请权限的代码:

        String[] perms={
                Manifest.permission.CAMERA,Manifest.permission.INTERNET,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        if (EasyPermissions.hasPermissions(this,perms)){
            init();
        }else{
            EasyPermissions.requestPermissions(this,getString(R.string.permission),RC_CEMERA_AND_LOCATION,perms);
        }

  1. 调用相机 拍照并保存到相册
    private void takePhoto() {
//        创建file对象,用于存储拍照后的对象
        File outputImage=new File(getExternalCacheDir(),"output_image.jpg");
        try{
            if (outputImage.exists())outputImage.delete();
            outputImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (Build.VERSION.SDK_INT>=24){
//            FileProvider是一种特殊的内容提供器,使用了和内容提供器类似的机制来保护数据,可以选择性的将封装过的Uri共享给外部,从而提高应用的安全性。
            mImageUri= FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage);
        }else{
            mImageUri=Uri.fromFile(outputImage);
        }
//        启动相机程序
        Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//        指定调用相机拍照后的照片存储的地址
        intent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri);
        startActivityForResult(intent,TAKE_PHOTO_RC);
    }

  1. 打开相册 显示选中的图片
    private void choosePhoto() {
        Intent intent=new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,CHOOSE_PHOTO);
    }

在onActivityResult()中处理:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case TAKE_PHOTO_RC:
                if (resultCode==RESULT_OK){
                    try {
                        Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageUri));
                        mImage.setImageBitmap(bitmap);
//                        保存到相册
                        ImgUtil.saveImageToGallery(this,bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PHOTO:
                if (resultCode==RESULT_OK){
                    if (Build.VERSION.SDK_INT>=19){
                        handleImageOn19(data);
                    }else{
                        handleImageBefore10(data);
                    }
                }
        }
    }

    private void handleImageBefore10(Intent intent) {
        Uri uri=intent.getData();
        String imagePath=getImagePath(uri,null);
        displayImage(imagePath);
    }

    @TargetApi(19)
    private void handleImageOn19(Intent intent) {
        String imagePath=null;
        Uri uri=intent.getData();
        if (DocumentsContract.isDocumentUri(this,uri)){
//            如果是document类型的uri,通过document id处理
            String docId=DocumentsContract.getDocumentId(uri);
            if (uri.getAuthority().equals("com.android.providers.media.documents")){
                String id=docId.split(":")[1];//解析出数字格式的id
                String selection=MediaStore.Images.Media._ID+"="+id;
                imagePath=getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
            }else if (uri.getAuthority().equals("com.android.providers.downloads.documents")){
                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类型的uri,直接获取图片路径
            imagePath=uri.getPath();
        }
        displayImage(imagePath);
    }

    private void displayImage(String imagePath) {
        if (imagePath!=null){
            Bitmap bitmap=BitmapFactory.decodeFile(imagePath);
            mImage.setImageBitmap(bitmap);
        }else{
            Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
        }
    }

    private String getImagePath(Uri uri, String selection) {
        String path=null;
//        通过Uri和selection来获取真实的图片路径
        Cursor cursor=getContentResolver().query(uri,null,selection,null,null);
        if (cursor!=null){
            if (cursor.moveToFirst()){
                path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

  1. 保存图片到相册
public class ImgUtil {

    public static void saveImageToGallery(Context context, Bitmap bitmap){
//        首先保存图片
        File appDir = new File(Environment.getExternalStorageDirectory(), "vgmap");
        if (!appDir.exists()){
            appDir.mkdirs();
        }
        String filename=System.currentTimeMillis()+".jpg";
        File file=new File(appDir,filename);
        try {
            FileOutputStream fileOutputStream=new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
//        其次把文件插入到系统图库
        try {
            MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),filename,null);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
//        最后通知图库更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.getAbsolutePath())));
    }
}

整个MainActivity的代码:

package com.example.anew;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.example.anew.utils.ImgUtil;
import pub.devrel.easypermissions.EasyPermissions;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private static final int TAKE_PHOTO_RC = 2;
    private static final int CHOOSE_PHOTO = 3;
    private Button mBtnTakephoto;
    private ImageView mImage;
    private Button mBtnChoosePhoto;

    private static final int RC_CEMERA_AND_LOCATION = 1;
    private static final String VERA_FILEPROVIDER = "VERA_FILEPROVIDER";
//    照片所在的uri地址
    private Uri mImageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnTakephoto = (Button) findViewById(R.id.btn_takephoto);
        mImage = (ImageView) findViewById(R.id.image);
        mBtnChoosePhoto = (Button) findViewById(R.id.btn_choose_photo);

        mBtnTakephoto.setOnClickListener(this);
        mBtnChoosePhoto.setOnClickListener(this);
        String[] perms={
                Manifest.permission.CAMERA,Manifest.permission.INTERNET,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE
        };
        if (EasyPermissions.hasPermissions(this,perms)){
            init();
        }else{
            EasyPermissions.requestPermissions(this,getString(R.string.permission),RC_CEMERA_AND_LOCATION,perms);
        }

    }

    private void init() {
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_takephoto:
                takePhoto();
                break;
            case R.id.btn_choose_photo:
                choosePhoto();
                break;
        }
    }

    private void choosePhoto() {
        Intent intent=new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,CHOOSE_PHOTO);
    }

    private void takePhoto() {
//        创建file对象,用于存储拍照后的对象
        File outputImage=new File(getExternalCacheDir(),"output_image.jpg");
        try{
            if (outputImage.exists())outputImage.delete();
            outputImage.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (Build.VERSION.SDK_INT>=24){
//            FileProvider是一种特殊的内容提供器,使用了和内容提供器类似的机制来保护数据,可以选择性的将封装过的Uri共享给外部,从而提高应用的安全性。
            mImageUri= FileProvider.getUriForFile(MainActivity.this,VERA_FILEPROVIDER,outputImage);
        }else{
            mImageUri=Uri.fromFile(outputImage);
        }
//        启动相机程序
        Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//        指定调用相机拍照后的照片存储的地址
        intent.putExtra(MediaStore.EXTRA_OUTPUT,mImageUri);
        startActivityForResult(intent,TAKE_PHOTO_RC);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode){
            case TAKE_PHOTO_RC:
                if (resultCode==RESULT_OK){
                    try {
                        Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(mImageUri));
                        mImage.setImageBitmap(bitmap);
//                        保存到相册
                        ImgUtil.saveImageToGallery(this,bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            case CHOOSE_PHOTO:
                if (resultCode==RESULT_OK){
                    if (Build.VERSION.SDK_INT>=19){
                        handleImageOn19(data);
                    }else{
                        handleImageBefore10(data);
                    }
                }
        }
    }

    private void handleImageBefore10(Intent intent) {
        Uri uri=intent.getData();
        String imagePath=getImagePath(uri,null);
        displayImage(imagePath);
    }

    @TargetApi(19)
    private void handleImageOn19(Intent intent) {
        String imagePath=null;
        Uri uri=intent.getData();
        if (DocumentsContract.isDocumentUri(this,uri)){
//            如果是document类型的uri,通过document id处理
            String docId=DocumentsContract.getDocumentId(uri);
            if (uri.getAuthority().equals("com.android.providers.media.documents")){
                String id=docId.split(":")[1];//解析出数字格式的id
                String selection=MediaStore.Images.Media._ID+"="+id;
                imagePath=getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,selection);
            }else if (uri.getAuthority().equals("com.android.providers.downloads.documents")){
                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类型的uri,直接获取图片路径
            imagePath=uri.getPath();
        }
        displayImage(imagePath);
    }

    private void displayImage(String imagePath) {
        if (imagePath!=null){
            Bitmap bitmap=BitmapFactory.decodeFile(imagePath);
            mImage.setImageBitmap(bitmap);
        }else{
            Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
        }
    }

    private String getImagePath(Uri uri, String selection) {
        String path=null;
//        通过Uri和selection来获取真实的图片路径
        Cursor cursor=getContentResolver().query(uri,null,selection,null,null);
        if (cursor!=null){
            if (cursor.moveToFirst()){
                path=cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }


}

你可能感兴趣的:(特效相机项目)