欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

仿微信修改头像,自定义相册、自定义裁剪

程序员文章站 2022-05-30 22:12:05
...

最近因为项目需求需要自定义修改头像时的相册,另外调用系统裁剪经常出现无法裁剪图片的错误,所以裁剪也决定自定义,参照了这两篇文章:

https://blog.csdn.net/lvshaorong/article/details/51263648?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/luo115600/article/details/78459192

上效果图:
仿微信修改头像,自定义相册、自定义裁剪
文末附上我项目中用到的源码。
一、自定义图库:
主布局:
album_photos_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true" >
    <LinearLayout
        android:id="@+id/album_layout_title"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:paddingLeft="10dp"
        android:background="@color/colorAccent"
        android:orientation="horizontal"
        android:gravity="left|center_vertical">
        <ImageView
            android:id="@+id/album_cancel_and_back"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:src="@drawable/arrow_left"/>
        <LinearLayout
            android:id="@+id/show_album_list"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal"
            android:background="@drawable/album_select_bar_style"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="5dp"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:gravity="center">
            <TextView
                android:id="@+id/album_folder_name"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_marginRight="5dp"
                android:gravity="center"
                android:text="@string/all_photos"
                android:textSize="@dimen/primaty_text_size"/>
            <ImageView
                android:id="@+id/album_folder_name_icon"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:src="@drawable/arrow_up"/>
        </LinearLayout>
    </LinearLayout>

    <GridView
        android:id="@+id/album_photos_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:horizontalSpacing="5dp"
        android:verticalSpacing="5dp"
        android:numColumns="3"
        android:stretchMode="columnWidth"
        android:layout_below="@+id/album_layout_title" />

    <RelativeLayout
        android:id="@+id/album_folder_list_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#aa000000"
        android:layout_below="@+id/album_layout_title"
        android:layout_marginTop="-100dp"
        android:visibility="gone">
        <ListView
            android:id="@+id/album_folder_list_item"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:background="@color/white"/>
    </RelativeLayout>
</RelativeLayout>

tem布局:
album_photos_adapter.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/album_photo_layout"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:background="@color/grey"
    android:descendantFocusability="blocksDescendants">
    <ImageView
        android:id="@+id/album_photo"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:scaleType="centerCrop"
        android:clickable="false" />
</LinearLayout>

主代码:
SelectPhotoActivity.java

package com.xter.comunityserver.Album;

import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;

import com.xter.comunityserver.BaseActivity;
import com.xter.comunityserver.R;
import com.xter.comunityserver.Util.PermissionsUtils;
import com.xter.comunityserver.Util.PictureUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class SelectPhotoActivity extends BaseActivity implements SelectPhotoAdapter.CallBackActivity,OnClickListener{
    private static String TAG = "SelectPhotoActivity";
    SelectPhotoAdapter allPhotoAdapter =  null;
    ImageView album_cancel_and_back;//左上角返回键
    LinearLayout show_album_list;//展开相册列表
    TextView album_folder_name;//当前相册名
    ImageView album_folder_name_icon;//展开箭头图标
    GridView album_photos_view;//当前界面所有的照片
    RelativeLayout album_folder_list_layout;//图片文件夹视图
    ListView album_folder_list_item;//文件列表中的子项

    private AlbumListAdapter albumListAdapter;
    private List<AlbumBean> albumList = new ArrayList<>();//相册列表
    boolean isShowAlbum;//相册列表是展开的还是关闭的

    //头像图片路径
    String pictureFile = Environment.getExternalStorageDirectory()+"/Pictures/";//此处的Pictures对应与provider_paths下的path,是为了保证fileprovider的路径一致
    public String cameraPhotoUrl;//拍照完的照片名
    private File photoFile;//存储拍照照片的文件
    public static final int REQ_CAMARA = 1000;//相机请求码
    private final int CLIP_PHOTO_BY_SELF_REQUEST_CODE = 3;//自定义裁剪界面请求码
    private File headIconFile = null;// 相册或者拍照保存的文件
    private File headClipFile = null;// 裁剪后的头像
    private String headFileNameStr = "headIcon.jpg";
    private String clipFileNameStr = "clipIcon.jpg";
    private String headFileSuffix = ".jpg";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.album_photos_layout);
    }

    private void initView(){
        album_photos_view = findViewById(R.id.album_photos_view);
        allPhotoAdapter = new SelectPhotoAdapter(this, new ArrayList<SelectPhotoAdapter.SelectPhotoEntity>());
        album_photos_view.setAdapter(allPhotoAdapter);
        album_cancel_and_back = findViewById(R.id.album_cancel_and_back);
        show_album_list = findViewById(R.id.show_album_list);
        album_folder_name = findViewById(R.id.album_folder_name);
        album_folder_name_icon = findViewById(R.id.album_folder_name_icon);
        album_folder_list_layout = findViewById(R.id.album_folder_list_layout);
        album_folder_list_item = findViewById(R.id.album_folder_list_item);
        headClipFile = new File(pictureFile, clipFileNameStr);

        //图片点击事件
        album_photos_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if(position == 0){
                    cameraPhotoUrl = System.currentTimeMillis() + "temp.jpg";//相机拍完之后的命名
                    try {
                        SharedPreferences camerasp = getSharedPreferences("Camera", Context.MODE_PRIVATE);
                        if (camerasp != null) {
                            SharedPreferences.Editor editor = camerasp.edit();
                            editor.putString("photoUrl", cameraPhotoUrl);
                            editor.apply();
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }

                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    photoFile = new File(pictureFile, cameraPhotoUrl);
                    Uri uri;
                    if(Build.VERSION.SDK_INT >= 24) {
                        uri = FileProvider.getUriForFile(
                                SelectPhotoActivity.this,
                                getPackageName() + ".fileprovider",
                                photoFile);
                    }else {
                        uri = Uri.fromFile(photoFile);
                    }
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                    startActivityForResult(intent, REQ_CAMARA);
                }else {
                    SelectPhotoAdapter.SelectPhotoEntity entity = allPhotoAdapter.allPhotoList.get(position-1);
                    clipPhotoBySelf(entity.url);
                }
            }
        });

        //选择相册的布局
        album_folder_list_layout.setOnClickListener(this);//外层

        //绑定点击
        album_cancel_and_back.setOnClickListener(this);
        show_album_list.setOnClickListener(this);

        getpermissions();
    }

    /**
     * 进入程序后检查权限
     */
    public void getpermissions(){
        String[] permissions = new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CAMERA};
        PermissionsUtils.getInstance().chekPermissions(this, permissions, permissionsResult);
    }
    //创建监听权限的接口对象
    PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() {
        @Override
        public void passPermissons() {
            showPhoto();
        }
        @Override
        public void forbitPermissons() {
            finish();
        }
    };
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //就多一个参数this
        PermissionsUtils.getInstance().onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    private void showPhoto(){
        //扫描手机上所有的图片
        SelectPhotoAdapter.getPhotoFromLocalStorage(SelectPhotoActivity.this, new SelectPhotoAdapter.LookUpPhotosCallback() {
            @Override
            public void onSuccess(ArrayList<SelectPhotoAdapter.SelectPhotoEntity> photoArrayList) {
                if(photoArrayList == null || photoArrayList.size() ==0)return;
                allPhotoAdapter.allPhotoList.clear();
                allPhotoAdapter.allPhotoList.addAll(photoArrayList);
                allPhotoAdapter.notifyDataSetChanged();
                //添加一个默认的相册用来存放所有图片
                AlbumBean defaultAlbum = new AlbumBean();
                defaultAlbum.albumFolder = Environment.getExternalStorageDirectory();
                defaultAlbum.topImagePath = photoArrayList.get(0).url;
                defaultAlbum.imageCounts = photoArrayList.size();
                defaultAlbum.folderName = "所有图片";
                albumList.add(0,defaultAlbum);
                if(albumListAdapter != null){//这个回调优先于查找相册回调
                    Log.i(TAG,"图片落后回调");
                    albumListAdapter.notifyDataSetChanged();
                }
            }
        });
        //查找并设置手机上的所有相册
        AlbumBean.getAllAlbumFromLocalStorage(SelectPhotoActivity.this, new AlbumBean.AlbumListCallback() {
            @Override
            public void onSuccess(ArrayList<AlbumBean> result) {
                albumList.addAll(result);
                albumListAdapter = new AlbumListAdapter(SelectPhotoActivity.this,albumList);
                album_folder_list_item.setAdapter(albumListAdapter);
            }
        });

        album_folder_list_item.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if(albumList!=null && position < albumList.size() && albumList.get(position) != null){//满足条件才能set
                    album_folder_name.setText(albumList.get(position).folderName);
                }
                isShowAlbum=false;
                hideAlbum();
                AlbumBean.getAlbumPhotosFromLocalStorage(SelectPhotoActivity.this, albumList.get(position), new AlbumBean.AlbumPhotosCallback() {
                    @Override
                    public void onSuccess(ArrayList<SelectPhotoAdapter.SelectPhotoEntity> photos) {
                        allPhotoAdapter.allPhotoList.clear();//因为是ArrayAdapter,所以引用不能重置
                        allPhotoAdapter.allPhotoList.addAll(photos);
                        allPhotoAdapter.notifyDataSetChanged();
                    }
                });
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(album_folder_list_item == null)
            initView();
    }

    @Override
    public void updateSelectActivityViewUI() {

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent dataIntent) {
        super.onActivityResult(requestCode, resultCode, dataIntent);
        switch (requestCode) {
            case SelectPhotoAdapter.REQ_CAMARA: {//1000如果是相机发来的
                if (RESULT_OK == resultCode) {//系统默认值
                    String cameraPhotoUrl = "temp.jpg";
                    try {
                        SharedPreferences camerasp = getSharedPreferences("Camera", Context.MODE_PRIVATE);
                        if (camerasp != null) {
                            cameraPhotoUrl = camerasp.getString("photoUrl", "temp.jpg");//得到之前在adapter里存好的文件名
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    File file = new File(pictureFile, cameraPhotoUrl);//这个文件指针指向拍好的图片文件
                    final String imageFilePath = file.getAbsolutePath();
                    clipPhotoBySelf(imageFilePath);
                    break;
                }
            }
            case CLIP_PHOTO_BY_SELF_REQUEST_CODE:
                if (RESULT_OK == resultCode){
                    //将裁剪后的图片保存到本地
                    final String clipFilePath = headClipFile.getAbsolutePath();
                    Log.e(TAG,"要裁剪的图片地址"+headClipFile);
                    headClipFile = new File(clipFilePath);
                    String clipUrl = null;
                    ContentResolver cr = SelectPhotoActivity.this.getContentResolver();
                    clipUrl =PictureUtils.insertImage(this, cr, headClipFile, true);//返回值为要发送图片的url
                    Uri uri = Uri.parse(clipUrl);
                    //将裁剪得的照片的url字符串传回去
                    Intent intent = new Intent();
                    intent.putExtra("selectPhotos",uri);//把获取到图片交给别的Activity
                    setResult(RESULT_OK, intent);
                    finish();
                    break;
                }else
                    break;

        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.album_cancel_and_back:
                finish();
                break;
            case R.id.show_album_list:
                if(isShowAlbum)
                    hideAlbum();//现在是展示album的状态
                else
                    showAlbum();//现在是关闭(正常)状态
                break;
            case R.id.album_folder_list_layout:
                hideAlbum();
                break;
        }
    }

    /**
     * 隐藏相册选择页
     */
    void hideAlbum(){
        if(Build.VERSION.SDK_INT >=11) {
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(album_folder_list_layout, "alpha", 1.0f, 0.0f);
            ObjectAnimator animator2 = ObjectAnimator.ofFloat(album_folder_name_icon, "rotationX", 180f, 360f);
            ObjectAnimator animator3 = ObjectAnimator.ofFloat(album_folder_list_layout, "translationY", -dp2Px(100));
            AnimatorSet set = new AnimatorSet();
            set.setDuration(300).playTogether(animator1, animator2, animator3);
            set.start();
            set.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    album_folder_list_layout.setVisibility(View.GONE);
                }
            });
        }else {
            album_folder_list_layout.setVisibility(View.GONE);
        }
        isShowAlbum=false;
    }

    /**
     * 显示相册选择页
     */
    void showAlbum(){
        if(Build.VERSION.SDK_INT>=11) {
            album_folder_list_layout.setVisibility(View.VISIBLE);//一定要显示,才能执行动画操作
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(album_folder_list_layout, "alpha", 0.0f, 1.0f);
            ObjectAnimator animator2 = ObjectAnimator.ofFloat(album_folder_name_icon, "rotationX", 0f, 180f);
            ObjectAnimator animator3 = ObjectAnimator.ofFloat(album_folder_list_layout, "translationY", dp2Px(100));
            AnimatorSet set = new AnimatorSet();
            set.setDuration(300).playTogether(animator1, animator2, animator3);
            set.start();
        }else {
            album_folder_list_layout.setVisibility(View.VISIBLE);//一定要显示,才能执行动画操作
        }
        isShowAlbum=true;
    }

    public int dp2Px(int dp) {
        try {
            DisplayMetrics metric = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metric);
            return (int) (dp * metric.density + 0.5f);
        } catch (Exception e) {
            e.printStackTrace();
            return dp;
        }
    }

    /**
     * 调用自定义切图方法
     *
     * @param filePath
     */
    protected void clipPhotoBySelf(String filePath) {
        Log.i(TAG, "通过自定义方式去剪辑这个照片");
        //进入裁剪页面,此处用的是自定义的裁剪页面而不是调用系统裁剪
        Intent intent = new Intent(SelectPhotoActivity.this, ClipPictureActivity.class);
        intent.putExtra(ClipPictureActivity.IMAGE_PATH_ORIGINAL, filePath);
        intent.putExtra(ClipPictureActivity.IMAGE_PATH_AFTER_CROP,
                headClipFile.getAbsolutePath());

        startActivityForResult(intent, CLIP_PHOTO_BY_SELF_REQUEST_CODE);

    }

}

主适配器代码:
SelectPhotoAdapter.java

package com.xter.comunityserver.Album;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.xter.comunityserver.R;
import java.io.Serializable;
import java.util.ArrayList;
import android.content.Context;
import static com.xter.comunityserver.Util.ScreenUtils.getScreenWidth;

public class SelectPhotoAdapter extends ArrayAdapter<SelectPhotoAdapter.SelectPhotoEntity>{
    private static String TAG = "SelectPhotoAdapter";
    private Activity mActivity;
    public ArrayList<SelectPhotoEntity> allPhotoList;
    public static final int REQ_CAMARA = 1000;
    private ImageLoader imageLoader;//图片加载器
    private int destWidth, destHeight;
    int screenWidth;

    public SelectPhotoAdapter(Activity activity, ArrayList<SelectPhotoEntity> array) {
        super(activity, R.layout.album_photos_adapter, array);
        this.mActivity = activity;
        this.allPhotoList = array;
        this.imageLoader = new ImageLoader(activity);
        screenWidth = getScreenWidth(activity);
        this.destWidth = (screenWidth - 20) / 3;
        this.destHeight = (screenWidth - 20) / 3;
    }

    @Override
    public int getCount() {
        return allPhotoList.size()+1;//加一是为了那个相机图标
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            viewHolder = new ViewHolder();

            convertView = LayoutInflater.from(getContext()).inflate(R.layout.album_photos_adapter, parent, false);
            viewHolder.album_photo_layout = (LinearLayout) convertView.findViewById(R.id.album_photo_layout);
            viewHolder.album_photo = (ImageView) convertView.findViewById(R.id.album_photo);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        if (viewHolder.album_photo.getLayoutParams() != null) {
            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) viewHolder.album_photo.getLayoutParams();
            lp.width = destWidth;
            lp.height = destHeight;
            viewHolder.album_photo.setLayoutParams(lp);
        }


        if (position == 0) {//第一个位置显示一个小相机
            Log.e(TAG,"点击的位置:"+position);
            imageLoader.setAsyncBitmapFromSD(null,viewHolder.album_photo,0,false,false,false);//防止回调覆盖了imageView原来的bitmap
            viewHolder.album_photo.setImageDrawable(getDrawable(mActivity,R.drawable.album_cameraadd));
        } else if((allPhotoList != null) && (position >= 0) && (allPhotoList.size() >= position) && (allPhotoList.get(position-1) != null)){
            final SelectPhotoEntity photoEntity = allPhotoList.get(position-1);
            final String filePath = photoEntity.url;
            imageLoader.setAsyncBitmapFromSD(filePath,viewHolder.album_photo,screenWidth/3,false,true,true);
            viewHolder.album_photo_layout.setTag(R.id.album_photo_layout,photoEntity);
        }
        return convertView;
    }


    class ViewHolder {
        public LinearLayout album_photo_layout;
        public ImageView album_photo;
    }

    public interface CallBackActivity{
        void updateSelectActivityViewUI();
    }

    public static class SelectPhotoEntity implements Serializable, Parcelable {
        public String url;
        public int isSelect;

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(this.url);
            dest.writeInt(this.isSelect);
        }

        public SelectPhotoEntity() {
        }

        protected SelectPhotoEntity(Parcel in) {
            this.url = in.readString();
            this.isSelect = in.readInt();
        }

        public static final Parcelable.Creator<SelectPhotoEntity> CREATOR = new Parcelable.Creator<SelectPhotoEntity>() {
            @Override
            public SelectPhotoEntity createFromParcel(Parcel source) {
                return new SelectPhotoEntity(source);
            }

            @Override
            public SelectPhotoEntity[] newArray(int size) {
                return new SelectPhotoEntity[size];
            }
        };

        @Override
        public String toString() {
            final StringBuffer sb = new StringBuffer("SelectPhotoEntity{");
            sb.append("url='").append(url).append('\'');
            sb.append(", isSelect=").append(isSelect);
            sb.append('}');
            return sb.toString();
        }

        @Override
        public int hashCode() {//使用hashcode和equals方法防止重复
            if(url != null)return url.hashCode();
            return super.hashCode();
        }

        @Override
        public boolean equals(Object o) {
            if(o instanceof SelectPhotoEntity){
                return o.hashCode() == this.hashCode();
            }
            return super.equals(o);
        }
    }

    public static Drawable getDrawable(Context context, int id) {
        if ((context == null) || (id < 0)) {
            return null;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return context.getResources().getDrawable(id, null);
        } else {
            return context.getResources().getDrawable(id);
        }
    }

    /**
     * 从系统相册里面取出图片的uri
     */
    public static void getPhotoFromLocalStorage(final Context context, final LookUpPhotosCallback completeCallback) {
        //在子线程中获取图片
        new MultiTask<Void,Void,ArrayList<SelectPhotoEntity>>(){

            @Override
            protected ArrayList<SelectPhotoEntity> doInBackground(Void... params) {
                ArrayList<SelectPhotoEntity> allPhotoArrayList = new ArrayList<>();

                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                ContentResolver mContentResolver = context.getContentResolver();//得到内容处理者实例

                String sortOrder = MediaStore.Images.Media.DATE_MODIFIED + " desc";//设置拍摄日期为倒序
                // 只查询jpeg和png的图片
                Cursor mCursor = mContentResolver.query(mImageUri, new String[]{MediaStore.Images.Media.DATA}, MediaStore.Images.Media.MIME_TYPE + "=? or " + MediaStore.Images.Media.MIME_TYPE + "=?", new String[]{"image/jpeg", "image/png"}, sortOrder);
                if (mCursor == null) return
                        allPhotoArrayList;
                int size = mCursor.getCount();
                if (size == 0)
                    return
                            allPhotoArrayList;
                for (int i = 0; i < size; i++) {//遍历全部图片
                    mCursor.moveToPosition(i);
                    String path = mCursor.getString(0);// 获取图片的路径
                    SelectPhotoEntity entity = new SelectPhotoEntity();
                    entity.url = path;//将图片的uri放到对象里去
                    allPhotoArrayList.add(entity);
                }
                mCursor.close();
                return allPhotoArrayList;
            }

            @Override
            protected void onPostExecute(ArrayList<SelectPhotoEntity> photoArrayList) {
                super.onPostExecute(photoArrayList);
                if(photoArrayList == null)return;
                if(completeCallback != null)completeCallback.onSuccess(photoArrayList);
            }
        }.executeDependSDK();
    }

    /**
     * 查询照片成功的回调函数
     */
    public interface LookUpPhotosCallback {
        void onSuccess(ArrayList<SelectPhotoEntity> photoArrayList);
    }
}

所有的工具类代码如图片加载工具都放在源码里了。点击下载源码
最后只需要在设置头像的界面接收相册裁剪返回的参数就可以了:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode,resultCode,data);
        if (resultCode != RESULT_OK){
            return;
        }
        if(resultCode == RESULT_OK && resultCode != RESULT_CANCELED){
            switch (requestCode){
                case REQUEST_def_CODE:
                    String path = data.getParcelableExtra("selectPhotos").toString();
                    Bitmap bitmap = PictureUtils.getScalesBitmap(path,this);
                    headimage.setImageBitmap(bitmap);
                    break;
            }
        }
    }

有不明白的地方请联系我:
仿微信修改头像,自定义相册、自定义裁剪