美文网首页
拍照,选择照片并进行裁剪,适配Android 7.0

拍照,选择照片并进行裁剪,适配Android 7.0

作者: 木小伍 | 来源:发表于2019-03-26 15:05 被阅读0次

实现步骤

1.在application节点下面添加provider
 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.wyw.farm.fileprovider"(本项目的包名为 com.wyw.farm)
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
2.新建与之对应的xml文件(res/xml/file_paths.xml)
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="baseApp"/>
<!--    <files-path> ,对应 Context.getFilesDir() 方法;
    <cache-path> ,对应 getCacheDir() 方法;
    <external-path>,对应 Environment.getExternalStorageDirectory() 方法,
    <external-files-path> ,对应 Context.getExternalFilesDir() 方法;
    <external-cache-path> ,对应 Context.getExternalCacheDir() 方法。 -->
</paths>
3.Activity /fragment代码如下,使用了butterknife,glide,easyPermissions第三方
package com.nanchang.farm.modules.personal;


import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.constraint.ConstraintLayout;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.nanchang.farm.AppConstants;
import com.nanchang.farm.R;
import com.nanchang.farm.base.BaseFragment;
import com.nanchang.farm.modules.login.LoginActiviy;
import com.nanchang.farm.utils.LogUtils;
import com.nanchang.farm.utils.getPhotoFromPhotoAlbum;
import com.nanchang.farm.views.CommonDailog;
import com.nanchang.farm.views.PhotoPopupWindow;
import com.nanchang.farm.views.TitleBar;

import java.io.ByteArrayOutputStream;
import java.io.File;

import butterknife.BindView;
import butterknife.OnClick;
import pub.devrel.easypermissions.EasyPermissions;

/**
 * @author: Five_伍
 * @create: 2019/2/19
 * @Describe:
 */
public class PersonalFragment extends BaseFragment<PersonalPresenter> implements PersonalContract.View {
    private static String AppDir =Environment.getExternalStorageDirectory() +  "/baseApp";
    private static String TAG = "PersonalFragment";
    private static final int REQUEST_IMAGE_GET = 0;
    private static final int REQUEST_IMAGE_CAPTURE = 1;
    private static final int REQUEST_SMALL_IMAGE_CUTTING = 2;
    private final int REQUST_STORE_CODE = 1001;
    private final int REQUST_CAMERA_CODE = 1002;

    private String[] perms_store = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};

    private String[] perms_camera = {Manifest.permission.CAMERA,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};


    private File mTempFile = getmTempFile();//临时文件

    // 裁剪过后的uri
    private Uri corpUri;

    //照片的uri --未裁剪的
    private Uri takeUri;


    @BindView(R.id.titleBar)
    TitleBar titleBar;
    @BindView(R.id.rootView)
    ConstraintLayout parentView;
    @BindView(R.id.imageView)
    ImageView imageView;

    @Override
    protected void bindVP() {
        mPresenter = new PersonalPresenter();
        mPresenter.attachView(this);
    }

    @Override
    protected Integer getContentId() {
        return R.layout.fragment_personal;
    }

    @Override
    protected void initView() {
        titleBar.setLeftIcon(0);
    }

    @Override
    protected void initData() {

        LogUtils.LOG_D(getClass(), "个人中心初始化");
    }


    @OnClick({R.id.btn_selectPic, R.id.btn_takePic})
    public void onClick(View view) {

        switch (view.getId()) {
            case R.id.btn_selectPic: //选择照片
                if (EasyPermissions.hasPermissions(mActivity, perms_store)) {
                    goPhotoAlbum();
                } else {
                    EasyPermissions.requestPermissions(PersonalFragment.this,
                            PersonalFragment.this.getResources().getString(R.string.request_permisions),
                            REQUST_STORE_CODE,
                            perms_store);
                }
                break;

            case R.id.btn_takePic: //相机拍照
                if (EasyPermissions.hasPermissions(mActivity, perms_camera)) {
                    goCamera();
                } else {
                    EasyPermissions.requestPermissions(PersonalFragment.this,
                            PersonalFragment.this.getResources().getString(R.string.request_permisions),
                            REQUST_CAMERA_CODE,
                            perms_camera);
                }
                break;
        }
    }
    /**
     * 相机拍摄
     */
    private void goCamera() {

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            takeUri = FileProvider.getUriForFile(mActivity, "com.wyw.farm.fileprovider", getmTempFile());
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            takeUri = Uri.fromFile(getmTempFile());
        }
        intent.putExtra(MediaStore.EXTRA_OUTPUT, takeUri);
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
    /**
     * 相册选择
     */
    private void goPhotoAlbum() {
        mPhotoPopupWindow.dismiss();
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        // 判断系统中是否有处理该 Intent 的 Activity
        if (intent.resolveActivity(mActivity.getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_IMAGE_GET);
        } else {
            showToast("未找到图片查看器");
        }
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == Activity.RESULT_OK) {
            String photoPath = "";
            switch (requestCode) {
               case REQUEST_SMALL_IMAGE_CUTTING: // 裁剪
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        //需要拿到拍照时候的uri
                        corpUri = FileProvider.getUriForFile(getContext(), "com.wyw.farm.fileprovider", mTempFile);
                        photoPath = mTempFile.getPath();
                        Log.d(TAG, "7.0裁剪返回图片路径:" + photoPath);
                    } else {
                        photoPath = corpUri.getEncodedPath();
                        Log.d(TAG, "剪返回图片路径:" + photoPath);
                    }
                    Glide.with(mActivity).load(photoPath).into(imageView);
                    break;
                case REQUEST_IMAGE_GET://选择
                    photoPath = PhotoFromPhotoAlbum.getRealPathFromUri(mActivity, data.getData());
                    Log.i(TAG, "选择图片的路径是" + photoPath);
                    //  photoClip(data.getData());
                    Glide.with(mActivity).load(photoPath).into(imageView);
                    break;
                case REQUEST_IMAGE_CAPTURE: //拍照
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        //需要拿到拍照时候的uri
                        takeUri = FileProvider.getUriForFile(getContext(), "com.wyw.farm.fileprovider", mTempFile);
                        photoPath = mTempFile.getPath();
                        Log.d(TAG, "7.0拍照返回图片路径:" + photoPath);
                    } else {
                        photoPath = takeUri.getEncodedPath();
                        Log.d(TAG, "拍照返回图片路径:" + photoPath);
                    }
                    //   photoClip(takeUri);
                    Glide.with(mActivity).load(photoPath).into(imageView);
                    break;
            }
        }
    }
    /**
     * 照片裁剪
     *
     * @param uri 原的相片
     */
    private void photoClip(Uri uri) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        corpUri = Uri.fromFile(getmTempFile());
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setDataAndType(uri, "image/*");
        // aspectX aspectY 是宽高的比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        // 这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
        intent.putExtra("crop", "true");
        intent.putExtra("outputX", 200);
        intent.putExtra("outputY", 200);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, corpUri);
        intent.putExtra("return-data", false);
        startActivityForResult(intent, REQUEST_SMALL_IMAGE_CUTTING);
    }

    private File getmTempFile() {
        File filedir = new File(AppDir);
        if (!filedir.exists()) {
            filedir.mkdirs();
        }
        String path = filedir.getPath() + "/" + System.currentTimeMillis() + ".jpg";
        mTempFile = new File(path);
        return mTempFile;
    }

    /**
     * 压缩图片
     *
     * @param image
     * @return
     */
    public static byte[] compressImage(int maxSize, Bitmap image) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        int options = 90;
        byte[] bytes = baos.toByteArray().clone();
        Bitmap temp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        int size = bytes.length;
        while (size / 1024 > maxSize) {
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            temp.compress(Bitmap.CompressFormat.JPEG, options, bao);
            byte[] buf = bao.toByteArray().clone();
            size = buf.length;
            Bitmap bitmap = BitmapFactory.decodeByteArray(buf, 0, buf.length);
            options -= 5;
            if (options <= 0) options = 90;
            temp = bitmap;
            bytes = buf.clone();
        }
        return bytes;
    }
}
4.一个小工具类PhotoFromPhotoAlbum
package com.nanchang.farm.utils;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
/**
 * @ClassName: PhotoFromPhotoAlbum
 * @Author: Five_伍
 * @Date: 2019/3/25 14:17
 * @Description:
 */
public class PhotoFromPhotoAlbum {
    /**
     * 根据Uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    public static String getRealPathFromUri(Context context, Uri uri) {
        int sdkVersion = Build.VERSION.SDK_INT;
        if (sdkVersion >= 19) {
            return getRealPathFromUriAboveApi19(context, uri);
        } else {
            return getRealPathFromUriBelowAPI19(context, uri);
        }
    }
    /**
     * 适配api19以下(不包括api19),根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
        return getDataColumn(context, uri, null, null);
    }
    /**
     * 适配api19及以上,根据uri获取图片的绝对路径
     *
     * @param context 上下文对象
     * @param uri     图片的Uri
     * @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
     */
    @SuppressLint("NewApi")
    private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
        String filePath = null;
        if (DocumentsContract.isDocumentUri(context, uri)) {
            // 如果是document类型的 uri, 则通过document id来进行处理
            String documentId = DocumentsContract.getDocumentId(uri);
            if (isMediaDocument(uri)) {
                // 使用':'分割
                String id = documentId.split(":")[1];

                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = {id};
                filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
            } else if (isDownloadsDocument(uri)) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
                filePath = getDataColumn(context, contentUri, null, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            // 如果是 content 类型的 Uri
            filePath = getDataColumn(context, uri, null, null);
        } else if ("file".equals(uri.getScheme())) {
            // 如果是 file 类型的 Uri,直接获取图片对应的路径
            filePath = uri.getPath();
        }
        return filePath;
    }
    /**
     * 获取数据库表中的 _data 列,即返回Uri对应的文件路径
     *
     */
    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        String path = null;

        String[] projection = new String[]{MediaStore.Images.Media.DATA};
        Cursor cursor = null;
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
                path = cursor.getString(columnIndex);
            }
        } catch (Exception e) {
            if (cursor != null) {
                cursor.close();
            }
        }
        return path;
    }
    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is MediaProvider
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }
    /**
     * @param uri the Uri to check
     * @return Whether the Uri authority is DownloadsProvider
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }
}

以上就是完整代码。(时间匆忙,有时间再刨去冗余,精简一下)

相关文章

网友评论

      本文标题:拍照,选择照片并进行裁剪,适配Android 7.0

      本文链接:https://www.haomeiwen.com/subject/dgbgvqtx.html