因为项目中需要用到头像上传的功能,所以就下个Ddmo先来实现下。demo我是类似仿微信的,在一个GridView中展示所有的图片,其中第一个item可以去照相;获取到图片后再进行剪切。图片的剪切是从网上找的感觉不错就用,暂时也没有测试。获取图片可以用:https://github ...
因为项目中需要用到头像上传的功能,所以就下个Ddmo先来实现下。
demo我是类似仿微信的,在一个GridView中展示所有的图片,其中第一个item可以去照相;获取到图片后再进行剪切。
图片的剪切是从网上找的感觉不错就用,暂时也没有测试。
获取图片可以用:https://github.com/lovetuzitong/MultiImageSelector来实现
这里的圆形图像是用https://github.com/hdodenhof/CircleImageView来实现的
Demo写的比较粗糙,效果只是在4.4的手机和7.0的模拟器跑了一遍,所以可能会出现问题的。
如下是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,//Id104 MediaStore.Images.Media.DATA,//图片路径105 MediaStore.Images.Media.DATE_ADDED//图片的创建时间106 };107 108 @Override109 public Loader<Cursor> onCreateLoader(int id, Bundle args) {110 //创建一个Loader111 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 @Override124 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 @Override161 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 @Override182 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 @Override198 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的方式创建一个Uri240 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 uri252 */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 }
其中处理动态的权限还需要添加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="@ /> </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(); } }}
原标题:android头像上传(获取头像加剪切)
关键词:Android
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。