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

来源:互联网 发布:手机淘宝怎么赚钱 编辑:程序博客网 时间:2024/05/22 13:34

相信很多同学遇到过在项目中要上传相册中的图片,然而却因为各种版本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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}// 初始化控件private void init() {// TODO Auto-generated method stubbtnSelect = (Button) findViewById(R.id.btn_select);btnSelect.setOnClickListener(this);ivResult = (ImageView) findViewById(R.id.iv_result);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.btn_select:Utils.getInstance().selectPicture(this);break;case R.id.iv_result:break;}}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.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,然后再转换为uriString 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 blocke.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;// DocumentProviderif (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {// ExternalStorageProviderif (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}// DownloadsProviderelse 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);}// MediaProviderelse 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 addressif (isGooglePhotosUri(uri))return uri.getLastPathSegment();return getDataColumn(context, uri, null, null);}// Fileelse 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版本就可以获取到路径。


完整项目源码下载


6 0