拍照功能

        现在的应用,很多时候都会用到拍照,例如上传个头像什么的,而现在安卓已经8都出来了,并且在7.0之后有一些权限都列为了危险权限,所以有些变动,做个记录

  首先写个CameraUtils的工具类,用于返回uri

public class CameraUtils {
    private static final String TAG = "CameraUtils";
    private static CameraUtils cu;
    private static Context mContext;
    private static Uri uri;

    public static CameraUtils getInstance(Context c){
        if (null == cu){
            synchronized (CameraUtils.class){
                if (null == cu){
                    cu = new CameraUtils(c);
                }
            }
        }
        return cu;
    }

    private CameraUtils(Context context){
        mContext = context;
    }

    /**
     * 拍照
     * @param authority 在manifest中的对应一致
     * @return
     */
    public  Uri takePhotos(String authority){
        if (TextUtils.isEmpty(authority)){
            Log.e(TAG, "takePhotos: authority is null");
            return null;
        }
        //创建file对象,用于存储拍照的图片 (应用关联缓存目录,6.0后,读取sd卡列为危险权限)
        File outputImg = new File(mContext.getExternalCacheDir(),"take_img.jpg");
        try {
            if (outputImg.exists()){
                outputImg.delete();
            }
            outputImg.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //7.0之后使用本地真实路径的uri被认为是不安全的,会报异常,所以用FileProvider这个内容提供器来做
        if (Build.VERSION.SDK_INT >= 24){
           uri = FileProvider.getUriForFile(mContext, authority, outputImg);
        }else{
            uri = Uri.fromFile(outputImg);
        }
      return uri;
    }
}

 然后记得要在manifest中注册,如下

<!--这里的authorities和takephotos的参数对应一致
        用meta-data他来指定uri的共享路径
        exported 是否支持其他应用调用控件-->
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.magic.myapplication.provider"
            android:grantUriPermissions="true"
            android:exported="false"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path"
                />
        </provider>

这里的resource中的这个xml文件是没有,所以需要我们自己创建

<?xml version="1.0" encoding="utf-8"?>
<!--external-path用来指定uri共享的.name随便填写 path表示共享路径,这里设置空表示整个sd进行共享-->
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_img" path=""/>
</paths>

用到了读写权限,在6.0后就可以不用写了,但是为了兼容低版的,所以记得添加权限

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

最后就是在Activity中使用了

 btn_take_pic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                uri = CameraUtils.getInstance(MainActivity.this).takePhotos("com.example.magic.myapplication.provider");
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT,uri);
                startActivityForResult(intent,1);
            }
});



 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 1:
                if (resultCode == RESULT_OK){
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
                        iv_showpic.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
        }
    }

 

当然有拍照就会有从本地相册选择图片

首先还是在CameraUtils的工具类中添加 如下:

  /**
     * 4.4版本以上 从相册获取照片
     * @param data
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    public Bitmap getImageOnKitKat(Intent data){
        String imagePath = null;
        Uri dataUri = data.getData();
        if (DocumentsContract.isDocumentUri(mContext,dataUri)){
            //如果是document类型的Uri,则通过document id处理
            String docId = DocumentsContract.getDocumentId(dataUri);
            if ("com.android.providers.media.documents".equals(dataUri.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(dataUri.getAuthority())){
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri,null);
            }
        }else if ("content".equalsIgnoreCase(dataUri.getScheme())){
            imagePath = getImagePath(dataUri,null);
        }else if("file".equalsIgnoreCase(dataUri.getScheme())){
            imagePath = dataUri.getPath();
        }
//根据路径来显示图片
        return displayImage(imagePath);
    }

    /**
     * 4.4之前从相册选图片
     */
    public Bitmap getImageBeforeKitKat(Intent data){
        Uri dataUri = data.getData();
        String imagePath = getImagePath(dataUri,null);
        return displayImage(imagePath);
    }

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

    private Bitmap displayImage(String path){
        Bitmap bitmap;
        if (null != path){
            bitmap = BitmapFactory.decodeFile(path);
        }else{
            return null;
        }
        return bitmap;
    }

在Activity中使用,这里加了权限的检查,因为在7.0后读取sd列为危险权限,否则会崩,如下

 btn_get_pic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
                    ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
                }else{
                    openAlbum();
                }
            }
        });
    }

    /**
     * 打开相册
     */
    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent,2);
    }

    @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){
                    openAlbum();
                }else{
                    MyToastUtils.show(MainActivity.this,"没有权限,请开启权限");
                }
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode){
            case 1:
                if (resultCode == RESULT_OK){
                    try {
                        Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
                        iv_showpic.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;

            case 2:
                if(resultCode == RESULT_OK){
                    Bitmap bitmap;
                    //4.4以上
                    if (Build.VERSION.SDK_INT >= 19){
                        bitmap = CameraUtils.getInstance(MainActivity.this).getImageOnKitKat(data);
                        Log.i(TAG, "1 onActivityResult: "+Build.VERSION.SDK_INT);
                    }else{
                        bitmap = CameraUtils.getInstance(MainActivity.this).getImageBeforeKitKat(data);
                        Log.i(TAG, "2 onActivityResult: "+Build.VERSION.SDK_INT);
                    }
                    iv_showpic.setImageBitmap(bitmap);
                }
                break;
        }
    }

 

转载于:https://my.oschina.net/fbf8866/blog/983413

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值