zoukankan      html  css  js  c++  java
  • 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();
            }
        }
    }
  • 相关阅读:
    线程 定时任务 实现思路
    Days Floating In ShenZhen(1)
    由于未能找到具有自动生成的控件来引发回发事件,导致发生错误
    在ASP.NET中使用AJAX.NET (转译自MSDN)(二)
    Every Time I Wake up I want sleep more
    漂泊在深圳的日子2
    512今日历程
    流金岁月
    对自己的思考
    关于绑定自动生成的下拉式菜单的错误
  • 原文地址:https://www.cnblogs.com/wangfengdange/p/7443389.html
Copyright © 2011-2022 走看看