前言
在Android应用中,经常有场景会需要使用到设备上存储的图片,而直接从路径中获取无疑是非常不便利的。所以一般推荐调用系统的Gallery应用,选择图片,然后使用它。本篇博客将讲解如何在Android中通过系统Gallery获取图片。
Gallery应用
Android原生内置了很多App,而Gallery为图库,用于操作设备上的图片,它会在开机的时候主动扫描设备上存储的图片,并可以使用Gallery操作它们。既然要使用Gallery,那么先看看它的AndroidManifest.xml清单文件。
15 6 97 8 10 1411 12 13 15 1916 17 18 20 2421 22 23 25 3126 27 28 29 30 32 3733 34 35 36 38 4239 40 41
上面是Gallery的AndroidManifest.xml文件中的部分代码,展示了ImageGallery,从众多Intent-filter中可以看出,选取图片应该使用"android.intent.action.PICK",它有两个miniType,"image/*"是用来获取图片的、"video/*"是用来获取视频的。Android中众多Action的字符串其实被封装在Intent类中,android.intent.action.PICK也不例外,它是Intent.ACTION_PICK。
既然知道了启动Gallery的Action,那么再看看ImageGallery.java的源码,找找其中选中图片后的返回值。
1 private void launchCropperOrFinish(IImage img) { 2 Bundle myExtras = getIntent().getExtras(); 3 4 long size = MenuHelper.getImageFileSize(img); 5 if (size < 0) { 6 // Return if the image file is not available. 7 return; 8 } 9 10 if (size > mVideoSizeLimit) {11 DialogInterface.OnClickListener buttonListener =12 new DialogInterface.OnClickListener() {13 public void onClick(DialogInterface dialog, int which) {14 dialog.dismiss();15 }16 };17 new AlertDialog.Builder(this)18 .setIcon(android.R.drawable.ic_dialog_info)19 .setTitle(R.string.file_info_title)20 .setMessage(R.string.video_exceed_mms_limit)21 .setNeutralButton(R.string.details_ok, buttonListener)22 .show();23 return;24 }25 26 String cropValue = myExtras != null ? myExtras.getString("crop") : null;27 if (cropValue != null) {28 Bundle newExtras = new Bundle();29 if (cropValue.equals("circle")) {30 newExtras.putString("circleCrop", "true");31 }32 33 Intent cropIntent = new Intent();34 cropIntent.setData(img.fullSizeImageUri());35 cropIntent.setClass(this, CropImage.class);36 cropIntent.putExtras(newExtras);37 38 /* pass through any extras that were passed in */39 cropIntent.putExtras(myExtras);40 startActivityForResult(cropIntent, CROP_MSG);41 } else {42 Intent result = new Intent(null, img.fullSizeImageUri());43 if (myExtras != null && myExtras.getBoolean("return-data")) {44 // The size of a transaction should be below 100K.45 Bitmap bitmap = img.fullSizeBitmap(46 IImage.UNCONSTRAINED, 100 * 1024);47 if (bitmap != null) {48 result.putExtra("data", bitmap);49 }50 }51 setResult(RESULT_OK, result);52 finish();53 }54 }
以上的ImageGallery.java的部分源码,从setResult()方法可以看出,它返回的Intent包含了选中图片的Uri,它是一个content://开头的内容提供者,并且如果传递过去的Intent的Extra中,包含一个name为"return-data"并且值为true的时候,还会往Extra中写入name为"data"的图片缩略图。
Gallery获取图片Demo
既然已经知道了启动Gallery的Action,和它如何返回选中的数据,那么接下来通过一个简单的Demo来演示一下如何从系统Gallery中获取图片,并把获取到的图片展示到界面的一个ImageView中。
1 package cn.bgxt.sysgallerydemo; 2 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.util.Log; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 import android.widget.ImageView;10 import android.app.Activity;11 import android.content.Intent;12 13 public class MainActivity extends Activity {14 private Button btn_getImage;15 private ImageView iv_image;16 private final static String TAG = "main";17 18 @Override19 protected void onCreate(Bundle savedInstanceState) {20 super.onCreate(savedInstanceState);21 setContentView(R.layout.activity_main);22 23 btn_getImage = (Button) findViewById(R.id.btn_getImage);24 iv_image = (ImageView) findViewById(R.id.iv_image);25 26 btn_getImage.setOnClickListener(getImage);27 }28 29 private View.OnClickListener getImage = new OnClickListener() {30 31 @Override32 public void onClick(View v) {33 // 设定action和miniType34 Intent intent = new Intent();35 intent.setAction(Intent.ACTION_PICK);36 intent.setType("image/*");37 // 以需要返回值的模式开启一个Activity38 startActivityForResult(intent, 0);39 }40 };41 42 @Override43 protected void onActivityResult(int requestCode, int resultCode, Intent data) {44 // 如果获取成功,resultCode为-145 Log.i(TAG, "resultCode:" + resultCode);46 if (requestCode == 0 && resultCode == -1) {47 // 获取原图的Uri,它是一个内容提供者48 Uri uri = data.getData();49 iv_image.setImageURI(uri);50 }51 super.onActivityResult(requestCode, resultCode, data);52 }53 }
效果展示:
总结
本篇博客到这里就基本上讲解了如何在Android下调用系统Gallery获取图片,其实功能实现很简单,主要是要注意Action和miniType不要写错了,并且返回值是一个Uri。虽然现在越来越多需要用到图片的商业应用,都在自己开发获取设备图片的功能,但是使用系统自带的Gallery来获取不失为一种快速实现功能的解决办法。为了方便起见,系统的Gallery源码,也会一并打包放到源码中,有需要的可以下载来看看。