android头像上传(获取头像加剪切)

因为项目中需要用到头像上传的功能,所以就下个Ddmo先来实现下。

demo我是类似仿微信的,在一个GridView中展示所有的图片,其中第一个item可以去照相;获取到图片后再进行剪切。

图片的剪切是从网上找的感觉不错就用,暂时也没有测试。

获取图片可以用:https://github.com/lovetuzitong/MultiImageSelector来实现

这里的圆形图像是用https://github.com/hdodenhof/CircleImageView来实现的

Demo写的比较粗糙,效果只是在4.4的手机和7.0的模拟器跑了一遍,所以可能会出现问题的。

下载资源:http://download.csdn.net/download/qq_29774291/9955206

如下是demo的效果图:

如下是选择图片中的代码

通过LoaderManager来获取到所有的图片,然后第一个进行拍照的处理

  1 package com.item.demo.photo.activity;
  2 
  3 import android.Manifest;
  4 import android.app.LoaderManager;
  5 import android.content.ContentResolver;
  6 import android.content.Context;
  7 import android.content.CursorLoader;
  8 import android.content.Intent;
  9 import android.content.Loader;
 10 import android.content.pm.PackageManager;
 11 import android.database.Cursor;
 12 import android.net.Uri;
 13 import android.os.Build;
 14 import android.os.Environment;
 15 import android.provider.MediaStore;
 16 import android.support.annotation.NonNull;
 17 import android.support.v4.content.ContextCompat;
 18 import android.support.v4.content.FileProvider;
 19 import android.support.v7.app.AppCompatActivity;
 20 import android.os.Bundle;
 21 import android.text.TextUtils;
 22 import android.util.Log;
 23 import android.view.View;
 24 import android.widget.AdapterView;
 25 import android.widget.GridView;
 26 import android.widget.ImageView;
 27 
 28 import com.item.demo.photo.BuildConfig;
 29 import com.item.demo.photo.R;
 30 import com.item.demo.photo.adapter.MyPhotoAdapter;
 31 import com.item.demo.photo.uilts.Image;
 32 import java.io.File;
 33 import java.util.ArrayList;
 34 import java.util.List;
 35 
 36 /**
 37  * 图片选择界面
 38  */
 39 public class MyPhotoActivity extends AppCompatActivity {
 40 
 41     private static final int REQUEST_CAPTURE = 100;
 42     //private static final int REQUEST_PICK = 101;
 43     private static final int REQUEST_CROP_PHOTO = 102;
 44 
 45     public static  final int FINSH_RESULT = 104;//截图后的返回
 46 
 47     private static final int LOADER_ID = 0x0100;
 48     private LoadCallBack mLoad = new LoadCallBack();
 49 
 50     private MyPhotoAdapter mAdapter;
 51     private List<Image> images = new ArrayList<>();
 52     //调用照相机返回图片文件
 53     private File tempFile;
 54     private static final int MIN_IMAGE_FILE_SIZE = 10 * 1024; // 最小的图片大小
 55 
 56     @Override
 57     protected void onCreate(Bundle savedInstanceState) {
 58         super.onCreate(savedInstanceState);
 59         setContentView(R.layout.activity_my_photo);
 60 
 61         GridView gv_photo = (GridView)findViewById(R.id.gv_photo);
 62         ImageView img_back = (ImageView)findViewById(R.id.iv_back);
 63         images.add(new Image());
 64         mAdapter = new MyPhotoAdapter(this,images);
 65         gv_photo.setAdapter(mAdapter);
 66         gv_photo.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 67             @Override
 68             public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
 69                 if(i == 0){
 70                     //第一个就去照相
 71                    if(hasPermission(new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE})){
 72                        gotoCamera();
 73                    }else {
 74                        requestPermission(0x02,new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE});
 75                    }
 76                 }else {
 77                     //这里点击获取到图片地址然后裁剪
 78                     gotoClipActivity(Uri.parse(images.get(i).getPath()));
 79                 }
 80             }
 81         });
 82         img_back.setOnClickListener(new View.OnClickListener() {
 83             @Override
 84             public void onClick(View view) {
 85                 finish();
 86             }
 87         });
 88     }
 89 
 90     @Override
 91     protected void onStart() {
 92         super.onStart();
 93 
 94         if(hasPermission(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE})){
 95             getLoaderManager().initLoader(LOADER_ID,null,mLoad);
 96         }else {
 97             requestPermission(0x01,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE});
 98         }
 99     }
100 
101     private class LoadCallBack implements LoaderManager.LoaderCallbacks<Cursor>{
102         private final String[] IMAGE_PROJECTION = new String[]{
103                 MediaStore.Images.Media._ID,//Id
104                 MediaStore.Images.Media.DATA,//图片路径
105                 MediaStore.Images.Media.DATE_ADDED//图片的创建时间
106         };
107 
108         @Override
109         public Loader<Cursor> onCreateLoader(int id, Bundle args) {
110             //创建一个Loader
111             if(id == LOADER_ID){
112                 //如果是我们的ID则进行初始化
113                 return new CursorLoader(getBaseContext(),
114                         MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
115                         IMAGE_PROJECTION,
116                         null,
117                         null,
118                         IMAGE_PROJECTION[2] + " DESC");
119             }
120             return null;
121         }
122 
123         @Override
124         public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
125             //当Loader加载完成时
126             List<Image> images = new ArrayList<>();
127             //判断是否有数据
128             if(data != null){
129                 int count = data.getCount();
130                 if(count > 0){
131                     data.moveToFirst();
132                     // 得到对应的列的Index坐标
133                     int indexId = data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]);
134                     int indexPath = data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]);
135                     int indexDate = data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]);
136                     do {
137                         // 循环读取,直到没有下一条数据
138                         int id = data.getInt(indexId);
139                         String path = data.getString(indexPath);
140                         long dateTime = data.getLong(indexDate);
141 
142                         File file = new File(path);
143                         if (!file.exists() || file.length() < MIN_IMAGE_FILE_SIZE) {
144                             // 如果没有图片,或者图片大小太小,则跳过
145                             continue;
146                         }
147                         // 添加一条新的数据
148                         Image image = new Image();
149                         image.setId(id);
150                         image.setPath(path);
151                         image.setDate(dateTime);
152                         images.add(image);
153 
154                     } while (data.moveToNext());
155                 }
156             }
157             updateSource(images);
158         }
159 
160         @Override
161         public void onLoaderReset(Loader<Cursor> loader) {
162             updateSource(null);
163         }
164     }
165 
166     /**
167      * 通知Adapter数据更改的方法
168      * @param images 新的数据
169      */
170     private void updateSource(List<Image> images){
171         this.images.clear();
172         this.images.add(new Image());
173         if(images == null || images.size() == 0) return;
174         this.images.addAll(images);
175         mAdapter.notifyDataSetChanged();
176     }
177 
178     /**
179      *权限的返回
180      */
181     @Override
182     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
183         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
184         switch(requestCode){
185             case 0x02:
186                 if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
187                     gotoCamera();
188                 }
189                 break;
190             case 0x01:
191                 if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
192                     getLoaderManager().initLoader(LOADER_ID,null,mLoad);
193                 }
194         }
195     }
196 
197     @Override
198     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
199         super.onActivityResult(requestCode, resultCode, data);
200         switch (requestCode){
201             case REQUEST_CAPTURE://系统相机返回
202                 if(resultCode == RESULT_OK){
203                     Log.d("jiejie","--------相机---------" + Uri.fromFile(tempFile).toString());
204                     Log.d("jiejie","--------path----------" + getRealFilePathFromUri(MyPhotoActivity.this,Uri.fromFile(tempFile)));
205                     gotoClipActivity(Uri.fromFile(tempFile));
206                 }
207 
208                 break;
209             case REQUEST_CROP_PHOTO:
210                 if(resultCode == RESULT_OK){
211                     if(data != null){
212                         Uri uri = data.getData();
213                         Log.d("jiejie","-------------" + data.getData().getPath());
214                         String cropImagePath = getRealFilePathFromUri(MyPhotoActivity.this,uri);
215                         Log.d("jiejie","------crop--------" + cropImagePath);
216                         Intent intent = new Intent();
217                         intent.putExtra("image",cropImagePath);
218                         setResult(FINSH_RESULT,intent);
219                         MyPhotoActivity.this.finish();
220                     }
221 
222                 }
223                 break;
224         }
225     }
226 
227     /**
228      * 跳转到系统照相机
229      */
230     private void gotoCamera(){
231         String SDState = Environment.getExternalStorageState();
232         //判断SD卡是否存在
233         if(SDState.equals(Environment.MEDIA_MOUNTED)){
234             tempFile = new File(checkDirPath(Environment.getExternalStorageDirectory().getPath()+ "/image/"), System.currentTimeMillis() + ".jpg");
235             //隐式的打开调用系统相册
236             Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
237             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
238                 intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
239                 //如果是7.0及以上的系统使用FileProvider的方式创建一个Uri
240                 Uri contentUri = FileProvider.getUriForFile(MyPhotoActivity.this, BuildConfig.APPLICATION_ID + ".fileProvider", tempFile);
241                 intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
242             }else {
243                 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
244             }
245             startActivityForResult(intent,REQUEST_CAPTURE);
246         }
247     }
248 
249     /**
250      * 打开截图的界面
251      * @param uri
252      */
253     private void gotoClipActivity(Uri uri){
254         if(uri == null){
255             return;
256         }
257         Intent intent = new Intent(this,ClipImageActivity.class);
258         intent.putExtra("type",1);
259         intent.setData(uri);
260         startActivityForResult(intent,REQUEST_CROP_PHOTO);
261     }
262 
263     /**
264      * 检查文件是否存在
265      */
266     private static String checkDirPath(String dirPath) {
267         if (TextUtils.isEmpty(dirPath)) {
268             return "";
269         }
270         File dir = new File(dirPath);
271         if (!dir.exists()) {
272             dir.mkdirs();
273         }
274         return dirPath;
275     }
276     /**
277      * 判断是否有指定的权限
278      */
279     public boolean hasPermission(String... permissions) {
280 
281         for (String permisson : permissions) {
282             if (ContextCompat.checkSelfPermission(this, permisson)
283                     != PackageManager.PERMISSION_GRANTED) {
284                 return false;
285             }
286         }
287         return true;
288     }
289     /**
290      * 申请指定的权限.
291      */
292     public void requestPermission(int code, String... permissions) {
293 
294         if (Build.VERSION.SDK_INT >= 23) {
295             requestPermissions(permissions, code);
296         }
297     }
298 
299     /**
300      * 根据Uri返回文件绝对路径
301      * 兼容了file:///开头的 和 content://开头的情况
302      */
303     public static String getRealFilePathFromUri(final Context context, final Uri uri) {
304         if (null == uri) return null;
305         final String scheme = uri.getScheme();
306         String data = null;
307         if (scheme == null)
308             data = uri.getPath();
309         else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
310             data = uri.getPath();
311         } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
312             Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
313             if (null != cursor) {
314                 if (cursor.moveToFirst()) {
315                     int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
316                     if (index > -1) {
317                         data = cursor.getString(index);
318                     }
319                 }
320                 cursor.close();
321             }
322         }
323         return data;
324     }
325 }

适配器的代码:

package com.item.demo.photo.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.item.demo.photo.R;
import com.item.demo.photo.uilts.Image;

import java.util.List;

/**
 * 图片的适配器
 * Created by Administrator on 2017/8/25.
 */

public class MyPhotoAdapter extends BaseAdapter {
    private Context mContext;
    private List<Image> mData;

    public MyPhotoAdapter(Context mContext, List<Image> mData) {
        this.mContext = mContext;
        this.mData = mData;
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int i) {
        return null;
    }

    @Override
    public long getItemId(int i) {
        return 0;
    }

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        ViewHolder holder;
        if(view == null){
            holder = new ViewHolder();
            view = LayoutInflater.from(mContext).inflate(R.layout.adapter_cell_layout,null);
            holder.mPic = view.findViewById(R.id.item_image);
            holder.mShade = view.findViewById(R.id.item_shade);
            view.setTag(holder);
        }else {
            holder = (ViewHolder) view.getTag();
        }
        if(position < 1){
            //第一个Item 特殊待遇下
            holder.mShade.setVisibility(View.GONE);
            Glide.with(mContext).load(R.drawable.ic_photo_add)
                    .into(holder.mPic);
        }else {
            GlideApp.with(mContext)
                    .load(mData.get(position).getPath())
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .centerCrop()
                    .placeholder(R.color.color_photo)
                    .into(holder.mPic);
//            Glide.with(mContext)
//                    .load(mData.get(position).getPath())//加载路径
//                    .diskCacheStrategy(DiskCacheStrategy.NONE)//不适用缓存
//                    .centerCrop()//居中剪切
//                    .placeholder(R.color.color_photo)//默认颜色
//                    .into(holder.mPic);
        }

        return view;
    }
    static class ViewHolder{
        private ImageView mPic;
        private View mShade;
    }
}

 

 

其中处理动态的权限还需要添加7.0的照相处理

在清单文件中加如下配置:

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.item.demo.photo.fileProvider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

 

图片的剪切

package com.item.demo.photo.activity;

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.item.demo.photo.R;
import com.item.demo.photo.view.ClipViewLayout;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 图片剪切
 */
public class ClipImageActivity extends AppCompatActivity implements View.OnClickListener {

    private ClipViewLayout clipViewLayout1;
    private ClipViewLayout clipViewLayout2;
    private ImageView back;
    private TextView tv_ok;
    //类别 1:圆形  2:方形
    private int type;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_clip_image);
        type = getIntent().getIntExtra("type",1);
        initView();
    }

    private void initView() {
        clipViewLayout1 = (ClipViewLayout)findViewById(R.id.clipViewLayout1);
        clipViewLayout2 = (ClipViewLayout)findViewById(R.id.clipViewLayout2);
        back = (ImageView)findViewById(R.id.iv_back);
        tv_ok = (TextView)findViewById(R.id.tv_ok);
        back.setOnClickListener(this);
        tv_ok.setOnClickListener(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(type == 1){
            clipViewLayout1.setVisibility(View.VISIBLE);
            clipViewLayout2.setVisibility(View.GONE);
            //设置图片资源
            clipViewLayout1.setImageSrc(getIntent().getData());
        }else {
            clipViewLayout2.setVisibility(View.VISIBLE);
            clipViewLayout1.setVisibility(View.GONE);
            clipViewLayout2.setImageSrc(getIntent().getData());
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.iv_back:
                finish();
                break;
            case R.id.tv_ok:
                generateUriAndReturn();
                break;
        }
    }

    /**
     * 生成Uri并且通过setResult返回给打开的Activity
     */
    private void generateUriAndReturn() {
        //调用返回剪切图
        Bitmap zoomedCropBitmap;
        if (type == 1) {
            zoomedCropBitmap = clipViewLayout1.clip();
        } else {
            zoomedCropBitmap = clipViewLayout2.clip();
        }
        if (zoomedCropBitmap == null) {
            Log.e("android", "zoomedCropBitmap == null");
            return;
        }
        Uri mSaveUri = Uri.fromFile(new File(getCacheDir(), "cropped_" + System.currentTimeMillis() + ".jpg"));
        if (mSaveUri != null) {
            OutputStream outputStream = null;
            try {
                outputStream = getContentResolver().openOutputStream(mSaveUri);
                if (outputStream != null) {
                    zoomedCropBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
                }
            } catch (IOException ex) {
                Log.e("android", "Cannot open file: " + mSaveUri, ex);
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            Intent intent = new Intent();
            intent.setData(mSaveUri);
            setResult(RESULT_OK, intent);
            finish();
        }
    }
}

 

posted @ 2017-08-28 13:10  王丰蛋哥  阅读(6414)  评论(0编辑  收藏  举报