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照相、相册获取图片剪裁报错的解决方案

最近在项目中用到了照相和相册取图剪裁上传头像,就在网上逛了逛,基本都是千篇一律,就弄下来用了用,没想到的是各种各样的奇葩问题就出现了。先给大家看看代码问题慢慢来解决 这是调用相机   ...

Android 7.0实际开发中调用系统相机和获取相册照片遇到的坑具备向下兼容

由于最近开发的一款app需要调用系统的照相机功能和获取相册中图片,在做手机版本适配7.0适配的时候,遇到一个大坑,拍照之后的照片,从相册中获取不到,最后Debug测试才知道获取的uri路径不对,最后使...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Android实现获取手机里面的所有图片

public class MainActivity extends Activity {//查看图片按钮 private Button look; private Button add...

Android 4.4前后版本读取图库图片和拍照完美解决方案

4.3或以下,选了图片之后,根据Uri来做处理,很多帖子都有了,我就不详细说了.主要是4.4,如果使用上面pick的原生方法来选图,返回的uri还是正常的,但如果用ACTION_GET_CONTENT...
  • ZBJDSBJ
  • ZBJDSBJ
  • 2015年01月04日 10:27
  • 17624

Android拍照和相册+系统裁剪功能返回图片

最近在使用一加3手机,Android系统6.0,进行测试的时候,发现调用手机的拍照和相册选择图片的功能返回的时候都无法调用系统的裁剪功能,Log日志也没有输出有用的信息。经过在网上大量的查找资料,拍照...

Android 4.4以上拍照或者从图库选择图片,获取图片路径

Android 4.4以上拍照或者从图库选择图片,获取图片路径 最近在做一个从图库选择图片或拍照,然后裁剪的功能.本来是没问题的,一直在用 Intent intent=new Inte...

android 4.4以上调用系统拍照与相册附带图片裁剪

在项目开发中,免不了要与图片打交道,但是获取图片的大部分方式都是通过拍照和选择相册中的照片获取的。下面就来说一下如何调用系统拍照于相册功能获取图片, 首先要知道的是,不管是相机还是相册,其实本质上都是...

解决android4.4以上系统的相册选择图片后获取不到有效的URI

最近用到上传图片, /** * 图片选择及拍照结果 */ @Override protected void onActivityResult(int reque...

android系统裁剪方法

android系统裁剪优化一直是各个厂商定制产品的关键步骤,包括浅层次的去除不必要的apk(android apk裁剪定制 )和深层次的裁剪整个编译系统和框架层.   android作为开源系统,各个...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android获取系统相册图片并裁剪(兼容4.4以上版本)
举报原因:
原因补充:

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