一、前言

好多APP都有上传图片的功能,无聊是调起相册还是拍照,都必须要在activity的onActivityResult回调方法处理,实现起来比较繁琐。至此对其进一步封装。使用起来更加简单。

二、直接上源码:

GitHub源码

1、首先创建一个PicOptions,作用是配置相关信息

public class PicOptions {    private boolean isCrop;//是否裁剪    private int cropWidth;//裁剪宽度    private int cropHeight;//裁剪高度    private String providerAuthority;//7.0以上访问sdcard需要用到    private File cacheFile;//缓存文件    private PicOptions(Builder builder) {        isCrop = builder.isCrop;        cropWidth = builder.cropWidth;        cropHeight = builder.cropHeight;        providerAuthority = builder.providerAuthority;        cacheFile = builder.cacheFile;    }    public boolean isCrop() {        return isCrop;    }    public int getCropWidth() {        return cropWidth;    }    public int getCropHeight() {        return cropHeight;    }    public String getProviderAuthority() {        return providerAuthority;    }    public File getCacheFile() {        return cacheFile;    }    public static Builder beginBuilder() {        return new Builder();    }    public static class Builder {        private boolean isCrop = false;        private int cropWidth = 0;        private int cropHeight = 0;        private String providerAuthority;        private File cacheFile;        public Builder setCrop(boolean crop) {            isCrop = crop;            return this;        }        public Builder setCropWidth(int cropWidth) {            this.cropWidth = cropWidth;            return this;        }        public Builder setCropHeight(int cropHeight) {            this.cropHeight = cropHeight;            return this;        }        public Builder setProviderAuthority(String providerAuthority) {            this.providerAuthority = providerAuthority;            return this;        }        public Builder setCacheFile(File cacheFile) {            this.cacheFile = cacheFile;            return this;        }        public PicOptions build() {            if (this.cacheFile == null) {                throw new IllegalArgumentException("cacheFile no found...");            }            return new PicOptions(this);        }    }}

2、回调接口PicListener

public interface PicListener {    void onTakePicSuccess(Uri uri);//成功    void onTakePicFail();//失败}

3、管理器PicManager

public class PicManager {    private final String TAG = "PicManager";    private final int REQUEST_CODE_CAMERA = 1009;//拍照    private final int REQUEST_CODE_PICTURE = 1008;//相册    private final int REQUEST_CODE_CUT_PIC = 1007;//裁剪    private final String REQUEST_TYPE = "requestType";    private PicOptions picOptions;    private PicListener listener;    public PicManager setPicOptions(PicOptions picOptions) {        this.picOptions = picOptions;        return this;    }    public PicManager setListener(PicListener listener) {        this.listener = listener;        return this;    }    public void takeCamera(Context context) {        startPicActivity(context, REQUEST_CODE_CAMERA);    }    public void takePhotoAlbum(Context context) {        startPicActivity(context, REQUEST_CODE_PICTURE);    }    private void startPicActivity(Context context, int type) {        Intent intent = new Intent(context, PicActivity.class);        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        intent.putExtra(REQUEST_TYPE, type);        context.startActivity(intent);    }    public void behavior(Activity activity, Intent intent, Bundle savedInstanceState) {        if (intent == null) {            YLogUtil.INSTANCE.eTag(TAG, "behavior intent is null");            onDestroy(activity);            return;        }        if (intent.getExtras() == null) {            YLogUtil.INSTANCE.eTag(TAG, "behavior extras is null");            onDestroy(activity);            return;        }        if (savedInstanceState == null) {            int requestType = intent.getExtras().getInt(REQUEST_TYPE);            if (requestType == REQUEST_CODE_CAMERA) {                executeCamera(activity);            } else if (requestType == REQUEST_CODE_PICTURE) {                executePhotoAlbum(activity);            }        }    }    private void executeCamera(Activity context) {        String providerAuthority = context.getPackageName() + ".FileProvider";        if (null != picOptions.getProviderAuthority() && !picOptions.getProviderAuthority().isEmpty()) {            providerAuthority = picOptions.getProviderAuthority();        }        Uri imageUri;        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);        // 判断版本大于等于7.0        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            try {                imageUri = FileProvider.getUriForFile(context, providerAuthority, picOptions.getCacheFile());            } catch (Exception e) {                e.printStackTrace();                imageUri = Uri.fromFile(picOptions.getCacheFile());            }            // 给目标应用一个临时授权            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);        } else {            imageUri = Uri.fromFile(picOptions.getCacheFile());        }        // 指定调用相机拍照后照片的储存路径        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);        context.startActivityForResult(intent, REQUEST_CODE_CAMERA);    }    private void executePhotoAlbum(Activity context) {        Intent intent = new Intent(Intent.ACTION_PICK, null);        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,                "image/*");        context.startActivityForResult(intent, REQUEST_CODE_PICTURE);    }    private void crop(Activity context, Uri uri) {        YLogUtil.INSTANCE.iFormatTag(TAG, "crop uri:%s", uri);        Intent intent = new Intent("com.android.camera.action.CROP");        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);        }        intent.setDataAndType(uri, "image/*");        // crop为true是设置在开启的intent中设置显示的view可以剪裁        intent.putExtra("crop", "true");        // aspectX aspectY 是宽高的比例        intent.putExtra("aspectX", 1);        intent.putExtra("aspectY", 1);        // outputX,outputY 是剪裁图片的宽高        intent.putExtra("outputX", picOptions.getCropWidth());        intent.putExtra("outputY", picOptions.getCropHeight());        intent.putExtra("return-data", false);        // intent.putExtra(MediaStore.EXTRA_OUTPUT,        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picOptions.getCacheFile()));        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());        intent.putExtra("noFaceDetection", true); // no face detection        context.startActivityForResult(intent, REQUEST_CODE_CUT_PIC);    }    public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {        if (listener == null || (requestCode != REQUEST_CODE_CAMERA && requestCode != REQUEST_CODE_PICTURE && requestCode != REQUEST_CODE_CUT_PIC)) {            YLogUtil.INSTANCE.eTag(TAG, "onActivityResult Unknown requestCode or listener is null");            onDestroy(activity);            return;        }        if (resultCode != android.app.Activity.RESULT_OK) {            YLogUtil.INSTANCE.eTag(TAG, "onActivityResult--cancel--resultCode", resultCode);            onDestroy(activity);            return;        }        switch (requestCode) {            case REQUEST_CODE_CAMERA:                YLogUtil.INSTANCE.iTag(TAG, "onActivityResult camera");                scanFile(activity, picOptions.getCacheFile().getAbsolutePath(), picOptions.isCrop());                break;            case REQUEST_CODE_PICTURE:                if (data == null || data.getData() == null) {                    YLogUtil.INSTANCE.eTag(TAG, "onActivityResult picture data is null ");                    listener.onTakePicFail();                    onDestroy(activity);                    return;                }                YLogUtil.INSTANCE.iTag(TAG, "onActivityResult picture");                if (picOptions.isCrop()) {                    crop(activity, data.getData());                } else {                    YLogUtil.INSTANCE.iFormatTag(TAG, "onActivityResult picture callback uri:%s", data.getData());                    listener.onTakePicSuccess(data.getData());                    onDestroy(activity);                }                break;            case REQUEST_CODE_CUT_PIC:                YLogUtil.INSTANCE.iTag(TAG, "onActivityResult crop");                scanFile(activity, picOptions.getCacheFile().getAbsolutePath(), false);                break;        }    }    private void scanFile(final Activity activity, String path, final boolean isCrop) {        MediaScannerConnection.scanFile(activity, new String[]{path}, new String[]{"image/jpeg"}, new MediaScannerConnection.OnScanCompletedListener() {            @Override            public void onScanCompleted(String path, final Uri uri) {                HandlerUtil.INSTANCE.runOnUiThread(new Runnable() {                    @Override                    public void run() {                        if (isCrop) {                            crop(activity, uri);                        } else {                            YLogUtil.INSTANCE.iFormatTag(TAG, "scanFile camera or crop callback uri:%s", uri);                            listener.onTakePicSuccess(uri);                            onDestroy(activity);                        }                    }                });            }        });    }    /**     * 摧毁本库的 PicActivity     */    private void onDestroy(Activity activity) {        if (activity != null) {            activity.finish();        }    }}

4、Pic

public class Pic {    private PicManager picManager;    private Pic() {        picManager = new PicManager();    }    public static synchronized Pic getInstance() {        return PicHolder.instance;    }    private static class PicHolder {        private static final Pic instance = new Pic();    }    public PicManager getPicManager() {        return picManager;    }}

5、真正调起拍照或相册的activity,PicActivity

public class PicActivity extends AppCompatActivity {    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        //不接受触摸屏事件        getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);        Pic.getInstance().getPicManager().behavior(this, getIntent(), savedInstanceState);    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        super.onActivityResult(requestCode, resultCode, data);        Pic.getInstance().getPicManager().onActivityResult(this, requestCode, resultCode, data);    }}

6、注册PicActivity到manifest

 

7、示例:

调起摄像头

Pic.getInstance().picManager.setPicOptions(getPicOptions()).setListener(listener).takeCamera(context)

调起相册

Pic.getInstance().picManager.setPicOptions(getPicOptions()).setListener(listener).takePhotoAlbum(context)

private PicOptions getPicOptions(){        File cacheFile = File(FileUtils.getSdcardPath(), TimeUtil.nowTimeStr + ".jpg");        return PicOptions.beginBuilder()                .setCacheFile(cacheFile)                .setCrop(checkBox.isChecked)                .setCropHeight(200)                .setCropWidth(200)                .build();    }

 

更多相关文章

  1. Android(安卓)studio使用相机拍照,保存并显示一坨屎一样的照片
  2. android上层得到底层数据的回调机制
  3. Android、H5 单独调起拍照与摄像
  4. Android自定义照相机实现 拍照 录像
  5. Android高仿微信相册选择器 多图片选择器、拍照
  6. android拍照获得图片及获得图片后剪切设置到ImageView
  7. android 拍照截取 部分照片(拍照截取行驶证)
  8. Android保存图片到系统相册并更新
  9. 【转】Android大图片裁剪终极解决方案 原理分析

随机推荐

  1. React Native For Android初探
  2. ubuntu14.04 64bit主机下面安装android的
  3. 关于Android的app权限申请问题
  4. Android Camera2 之 CameraDevice 详解
  5. android 通过贝塞尔曲线 实现爱心点赞功
  6. android 背景平铺[转]
  7. android 准妈妈孕周计算器 mama孕周计算
  8. android ICS 4.0.3 报 java.lang.Illegal
  9. Android 网络通信框架Volley简介(Google
  10. Android(安卓)播放SD卡上指定的一首歌(初