拍照和选择相册(兼容高版本)

来源:互联网 发布:淘宝安能物流被禁用 编辑:程序博客网 时间:2024/05/22 02:08

拍照

打开相机准备工作

 申请权限,需要下面两个权限:     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>     <uses-permission android:name="android.permission.CAMERA"/> 在Android 6.0系统下,可以选择在清单文件中静态注册,在Android 6.0以上需要代码中动态申请,关于代 码中动态申请,可以参照: http://blog.csdn.net/thanksforandroid/article/details/75105002

打开相机

File tempFile = new File(MineStudentFragment.this.getContext().getExternalCacheDir()       , PHOTO_FILE_NAME);/**生成一个文件,放在内置SD卡上,PHOTO_FILE_NAME是自己取的名字。*/                    if (Build.VERSION.SDK_INT >= 24) {                        uriP = FileProvider.getUriForFile(MineStudentFragment.this.getContext()                                , "mooc.zhihuiyuyi.com.mooc.provider"                                , tempFile);                    } else {                        uriP = Uri.fromFile(tempFile);                    }/**http://blog.csdn.net/thanksforandroid/article/details/76512616*/                    if (uriP != null) {  ForOpenCamera(uriP, REQUEST_PERMISSION_GALLERY_FIRST,Manifest.permission.WRITE_EXTERNAL_STORAGE);                    } else {                    ToastUtils.showShort(MineStudentFragment.this.getContext(), "未找到可用文件路径");                    }/**下面这个if - else 是为了给6.0网上系统动态申请写SD卡权限,ForOpenCamera()方法是自己写的*/

ForOpenCamera()方法

private void ForOpenCamera(Uri uriP, int permissionCode, String permission) {        if (Build.VERSION.SDK_INT >= 23) {            if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) {                MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode);//没有就去申请,这里是因为当时是在Fragment中使用的,                return;            } else {                startCamera(uriP);            }        } else {            startCamera(uriP);        }    }    /**参数说明,这里传进来一个Uri,是为了有权限时候直接去调用startCamera,permissionCode是权限    申请码,方便动态申请权限之后,在权限回调中判断,permission,是你要申请的权限*/

假设用户没有权限,那么就回去申请,申请结果的回调如下:

 @Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {    switch(requestCode){            case REQUEST_PERMISSION_GALLERY_FIRST:             /**这里之展示了一种case*/                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                    //表示给了权限了                    startCamera(uriP);                 } else {                    //表示没有权限,不能下一步ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把数据访问禁止了,你将不能享受服务。修改权限可以去设置中修改!");                }                break;        }    }

接下来看看startCamera()方法

public void startCamera(Uri uriP) {        // 激活相机        mIntent1 = new Intent("android.media.action.IMAGE_CAPTURE");        mIntent1.putExtra(MediaStore.EXTRA_OUTPUT, uriP);        requestPermissions(mIntent1,                REQUEST_PERMISSION_CAREMA,                Manifest.permission.CAMERA,                PHOTO_REQUEST_CAREMA);    }    /**在这里获取打开相机的intent,然后调用自定义的requestPermissions()这个自定义方法*/

requestPermissions()方法:

private void requestPermissions(Intent intent, int permissionCode,                                String permission, int requestCode) {if (Build.VERSION.SDK_INT >= 23) {            if (ContextCompat.checkSelfPermission(getContext(), permission) != PackageManager.PERMISSION_GRANTED) {                MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode);                return;            } else {                startActivityForResult(intent, requestCode);            }        } else {            startActivityForResult(intent, requestCode);        }    }/***也是检查有没有打开相机权限,如果没有的话,就去申请,有的话,就去打开相机了,requestCode是为了得到相机的返回值*/

假设用户也没有打开相机权限,那么权限回调如下,这里也只取关于相机权限部分:

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {        switch (requestCode) {            case REQUEST_PERMISSION_CAREMA:            /**这里只截取了一部分*/                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                    startActivityForResult(mIntent1, PHOTO_REQUEST_CAREMA);                } else { ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把相机权限禁止了,您将不能享受服务。修改权限可以去设置中修改!");                }                break;           }}

正常走到现在,用户会进行拍照,当结果返回的时候:

@Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);   /**这里为了理解,只展示相机结果的回调*/       if (requestCode == PHOTO_REQUEST_CAREMA) {            tempFile = new File(MineStudentFragment.this.getContext().getExternalCacheDir()                    , PHOTO_FILE_NAME);            if (Build.VERSION.SDK_INT >= 24) {                if (getImageContentUri(MineStudentFragment.this.getContext(), tempFile) != null) {      crop(getImageContentUri(MineStudentFragment.this.getContext(), tempFile));                } else {       ToastUtils.showShort(MineStudentFragment.this.getContext(), "拍照失败,稍后重试!");                }            } else {                if (Uri.fromFile(tempFile) != null) {                    crop(Uri.fromFile(tempFile));                } else {                    ToastUtils.showShort(MineStudentFragment.this.getContext(), "拍照失败,稍后重试!");                }            }}/**这里加了这么多层的嵌套,是为了避免空指针。下一步进行剪切,调用自定义的crop方法,它需要传一个Uri路径,但是这里又存在问题,在Android 7.0网上版本,所需要的路径,不能直接同过Uri.fromFile来获得,所以这里又多了一个判断*/

看看图片剪切的方法:

private void crop(Uri uri) {        // 裁剪图片意图        Intent intent = new Intent("com.android.camera.action.CROP");        intent.setDataAndType(uri, "image/*");        intent.putExtra("crop", "true");        // 裁剪框的比例,1:1        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        // 裁剪后输出图片的尺寸大小        intent.putExtra("outputX", 250);        intent.putExtra("outputY", 250);        intent.putExtra("outputFormat", "JPEG");// 图片格式        intent.putExtra("noFaceDetection", true);// 取消人脸识别        intent.putExtra("return-data", true);        // 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT        startActivityForResult(intent, PHOTO_REQUEST_CUT);    }

这里也是有一个startActivityForResult,接下来看看裁剪图片的返回结果的处理

public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);       if (requestCode == PHOTO_REQUEST_CUT) {            // 返回剪切后的数据,这里为了展示,也只是保留一部分需要的一部分            if (data != null && data.getParcelableExtra("data") != null) {                mStream = new ByteArrayOutputStream();                mBitmap = data.getParcelableExtra("data");                mBitmap.compress(Bitmap.CompressFormat.PNG, 100, mStream);                /**图片可以应用了*/                /**接下来就是上传到服务器*/                File files = creatFile(mBitmap);//变成文件                putNET_Photo(files);            } else {                ToastUtils.showShort(MineStudentFragment.this.getContext(), "未知的错误发生了");            }        }    }

createFile()方法是将Bitmap转换成文件的方法,这里多说一下,其实到这里拍照已经结束了

 private File creatFile(Bitmap bitmap) {        File cache = new File(getActivity().getCacheDir() + File.separator + CACHE_DIR);        BufferedOutputStream bos = null;        File file = null;        if (!cache.exists()) {            cache.mkdirs();        }        try {            file = new File(cache, USER_ICON_NAME);            bos = new BufferedOutputStream(new FileOutputStream(file));            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);            bos.flush();            bos.close();        } catch (IOException e) {            e.printStackTrace();        }        return file;    }

相册

准备工作

需要权限如下:

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

打开系统相册

mIntent2 = new Intent(Intent.ACTION_PICK);                mIntent2.setType("image/*");                requestPermissions(mIntent2,                        REQUEST_PERMISSION_GALLERY,                        Manifest.permission.WRITE_EXTERNAL_STORAGE,                        PHOTO_REQUEST_GALLERY);

针对于7.0以上,所以还是有动态获取权限,requestPermissions方法,

  private void requestPermissions(Intent intent, int permissionCode,                                    String permission, int requestCode) { if (Build.VERSION.SDK_INT >= 23) {if(ContextCompat.checkSelfPermission(getContext(), permission)!= PackageManager.PERMISSION_GRANTED) {      MineStudentFragment.this.requestPermissions(new String[]{permission}, permissionCode);                return;            } else {                startActivityForResult(intent, requestCode);            }        } else {            startActivityForResult(intent, requestCode);        }    }    /**此方法和上述相机哪里申请第二个权限的时候一样,不需要重写,只需要调用即可*/

权限申请结果

 @Override    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {        switch (requestCode) {            case REQUEST_PERMISSION_GALLERY:                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                    startActivityForResult(mIntent2, PHOTO_REQUEST_GALLERY);                 } else {                    ToastUtils.showLong(MineStudentFragment.this.getContext(), "您把数据访问禁止了,你将不能享受服务。修改权限可以去设置中修改!");                }                break;           }    }/**这里直截取了一部分。*/

用户选完相片之后,看看对于结果的处理:

 @Override    public void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        if (requestCode == PHOTO_REQUEST_GALLERY) {            // 从相册返回的数据            if (data != null && data.getData() != null) {                // 获取图片的全路径                Uri uri_1 = data.getData();                LogUtils.d("MineStudentFragment", "得到图片的全路径是:" + uri_1.toString());                crop(uri_1);            } else {                ToastUtils.showShort(MineStudentFragment.this.getContext(), "选择相册失败,稍后重试!");            }        }     }/**接下来就是调用crop方法,然后的处理就是和前面拍照一样了*/

说明:

前面的权限结果回调方法还有Activity结果的回调方法,其实是在一块的,这里为了好理解,而分开了,这里也涉及到了权限动态申请还有FileProvider,这些 可以参考博客,
http://blog.csdn.net/thanksforandroid/article/details/75105002
http://blog.csdn.net/thanksforandroid/article/details/76512616

阅读全文
0 0
原创粉丝点击