相信很多同学遇到过在项目中要上传相册中的图片,然而却因为各种版本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>
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版本就可以获取到路径。