Android获取系统相册图片并裁剪(兼容4.4以上版本)

原创 2016年05月30日 16:47:46

相信很多同学遇到过在项目中要上传相册中的图片,然而却因为各种版本android手机,会有些不兼容的问题。

我们在打开系统相册时,通常会有两种做法:

Intent.ACTION_PICK  直接打开系统相册

<span style="font-size:18px;">Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);</span>

Intent.ACTION_GET_CONTENT 通过内容类型

<span style="font-size:18px;">Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);</span>

选择Intent.ACTION_GET_CONTENT需要做一下兼容处理

<span style="font-size:18px;">if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
     intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
} else {
     intent.setAction(Intent.ACTION_GET_CONTENT);
}</span>

在选择图片的时候,打开相册选择图片(根据是否4.4设置不同action)ACTION_OPEN_DOCUMENT是官方建议



这是一个简单的案例,文章末尾会附带源码:

Activity代码

<span style="font-size:18px;">package com.parcool.mycroppicandupload;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.Calendar;

import com.parcool.mycroppicandupload.utils.AppConstant;
import com.parcool.mycroppicandupload.utils.Utils;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private Button btnSelect;
	private ImageView ivResult;

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

	// 初始化控件
	private void init() {
		// TODO Auto-generated method stub
		btnSelect = (Button) findViewById(R.id.btn_select);
		btnSelect.setOnClickListener(this);
		ivResult = (ImageView) findViewById(R.id.iv_result);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn_select:
			Utils.getInstance().selectPicture(this);
			break;

		case R.id.iv_result:
			break;
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode != Activity.RESULT_OK) {
			return;
		}
		if (null == data) {
			return;
		}
		Uri uri = null;
		if (requestCode == AppConstant.KITKAT_LESS) {
			uri = data.getData();
			Log.d("tag", "uri=" + uri);
			// 调用裁剪方法
			Utils.getInstance().cropPicture(this, uri);
		} else if (requestCode == AppConstant.KITKAT_ABOVE) {
			uri = data.getData();
			Log.d("tag", "uri=" + uri);
			// 先将这个uri转换为path,然后再转换为uri
			String thePath = Utils.getInstance().getPath(this, uri);
			Utils.getInstance().cropPicture(this,
					Uri.fromFile(new File(thePath)));
		} else if (requestCode == AppConstant.INTENT_CROP) {
			Bitmap bitmap = data.getParcelableExtra("data");
			ivResult.setImageBitmap(bitmap);
			File temp = new File(Environment.getExternalStorageDirectory()
					.getPath() + "/yourAppCacheFolder/");// 自已缓存文件夹
			if (!temp.exists()) {
				temp.mkdir();
			}
			File tempFile = new File(temp.getAbsolutePath()+"/"
					+ Calendar.getInstance().getTimeInMillis() + ".jpg"); // 以时间秒为文件名
			// 图像保存到文件中
			FileOutputStream foutput = null;
			try {
				foutput = new FileOutputStream(tempFile);
				if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, foutput)) {
					Toast.makeText(MainActivity.this,
							"已生成缓存文件,等待上传!文件位置:" + tempFile.getAbsolutePath(),
							Toast.LENGTH_LONG).show();
				}
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}</span>
Util代码

一定要注意,获取到的路径转成Uri要用:Uri.fromFile(new File("filePath"))

<span style="font-size:18px;">@SuppressLint("NewApi")
	public String getPath(final Context context, final Uri uri) {

		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

		// DocumentProvider
		if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
			// ExternalStorageProvider
			if (isExternalStorageDocument(uri)) {
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				if ("primary".equalsIgnoreCase(type)) {
					return Environment.getExternalStorageDirectory() + "/"
							+ split[1];
				}

				// TODO handle non-primary volumes
			}
			// DownloadsProvider
			else if (isDownloadsDocument(uri)) {
				final String id = DocumentsContract.getDocumentId(uri);
				final Uri contentUri = ContentUris.withAppendedId(
						Uri.parse("content://downloads/public_downloads"),
						Long.valueOf(id));

				return getDataColumn(context, contentUri, null, null);
			}
			// MediaProvider
			else if (isMediaDocument(uri)) {
				final String docId = DocumentsContract.getDocumentId(uri);
				final String[] split = docId.split(":");
				final String type = split[0];

				Uri contentUri = null;
				if ("image".equals(type)) {
					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
				} else if ("video".equals(type)) {
					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
				} else if ("audio".equals(type)) {
					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
				}

				final String selection = "_id=?";
				final String[] selectionArgs = new String[] { split[1] };

				return getDataColumn(context, contentUri, selection,
						selectionArgs);
			}
		}
		// MediaStore (and general)
		else if ("content".equalsIgnoreCase(uri.getScheme())) {

			// Return the remote address
			if (isGooglePhotosUri(uri))
				return uri.getLastPathSegment();

			return getDataColumn(context, uri, null, null);
		}
		// File
		else if ("file".equalsIgnoreCase(uri.getScheme())) {
			return uri.getPath();
		}

		return null;
	}</span>




在onActivityResult里面返回的Uri uri = data.getData();如果是android4.4 uri格式为content://com.android.providers.media.documents/document/image:3952,4.4以下格式为
content://media/external/images/media/3951


另一种方式就是直接设置打开相册的action,
intent.setAction(Intent.ACTION_PICK);
intent.setData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
后面的onActivityResult里面就可以不区分4.4版本就可以获取到路径。


完整项目源码下载


版权声明:本文为博主原创文章,转载请注明来源。

Android 拍照、选择图片并裁剪

前言:前段时间做项目用到了图片裁剪,调用系统裁剪图片,结果在我的小米3上一直有问题,裁剪界面打不开,在其他设备上没问题,于是研究其他软件是怎么做的,淘宝的裁剪图片是自己做的,当然没问题,京东的是调用的...
  • xuehuayous
  • xuehuayous
  • 2016年05月05日 17:38
  • 32123

android 剪切图片

一、调用系统的剪切功能: 事件执行: @Override public void onClick(View v) { if(null == mUri)return; ...
  • yzwlord
  • yzwlord
  • 2012年12月08日 23:43
  • 48924

android拍照图片选取与图片剪裁

最近从以前的项目中扒下来一个常用的模块,在这里有必要记录一下的,就是android上获取图片以及裁剪图片,怎么样?这个功能是不是很常用啊,你随便打开一个App,只要它有注册功能都会有设置人物头像的功能...
  • lee_tianya
  • lee_tianya
  • 2014年10月11日 16:09
  • 17550

Android 头像选择(拍照、相册裁剪),含7.0的坑

作者:夏至,欢迎转载,但请保留这段申明,谢谢。首先,好规则,看看自己的实现效果: 当然,这个github 各种开源库,这里只讲 Android 自带的功能。其实这个也不难,关键点无非就2个: 7.0...
  • u011418943
  • u011418943
  • 2017年08月30日 11:42
  • 2612

Android修改及裁剪头像(适配Android7.0)

  • 2017年07月31日 14:11
  • 77KB
  • 下载

android 选择图片 剪裁 拍照 兼容所有版本的代码

在做项目的时候,总是避免不了头像的剪裁和选取,然而4.4以后 以前能够使用的代码 ,也用不了了。 做下记录吧。因为下面代码我用了几次了。 以后直接复制粘贴。...
  • Jack_King007
  • Jack_King007
  • 2015年06月07日 19:43
  • 1173

Android 调用系统拍照及相册裁剪后作为头像,兼容到5.0

上周做了一个头像主要是为了抽出来封装一下,因为99%的应用都需要个人头像的上进行裁剪然后作为头像.所以考虑到这部分的需求,所以要解耦,为了代码的阅读性,扩展性等.      大家都知道调用系统相机和...
  • u010316858
  • u010316858
  • 2015年11月16日 15:19
  • 2508

调用系统相机、相册、剪裁图片并上传(常用于上传头像,兼容Android7.0)

解决上传头像类似功能在Android 7.0上的兼容问题
  • hansion3333
  • hansion3333
  • 2017年10月31日 09:23
  • 1452

Android获取系统相册图片并裁剪(兼容4.4以上版本)

相信很多同学遇到过在项目中要上传相册中的图片,然而却因为各种版本android手机,会有些不兼容的问题。 我们在打开系统相册时,通常会有两种做法: Intent.ACTION_PICK  直接打开...
  • caihongdao123
  • caihongdao123
  • 2016年05月30日 16:47
  • 7788

Android开发之裁切(拍照+相册)图像并设置头像小结

Android开发之裁切(拍照+相册)图像并设置头像小结
  • wjk7186912
  • wjk7186912
  • 2016年04月11日 05:48
  • 3055
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android获取系统相册图片并裁剪(兼容4.4以上版本)
举报原因:
原因补充:

(最多只允许输入30个字)