前言
在Android应用中,经常有场景会需要使用到设备上存储的图片,而直接从路径中获取无疑是非常不便利的。所以一般推荐调用系统的Gallery应用,选择图片,然后使用它。本篇博客将讲解如何在Android中通过系统Gallery获取图片。
Gallery应用
Android原生内置了很多App,而Gallery为图库,用于操作设备上的图片,它会在开机的时候主动扫描设备上存储的图片,并可以使用Gallery操作它们。既然要使用Gallery,那么先看看它的AndroidManifest.xml清单文件。
复制代码
1<activity android:name="com.android.camera.ImageGallery"
2android:label="@string/gallery_label"
3android:configChanges="orientation|keyboardHidden"
4android:icon="@drawable/ic_launcher_gallery">
5<intent-filter>
6<action android:name="android.intent.action.MAIN" />
7<category android:name="android.intent.category.DEFAULT" />
8</intent-filter>
9<intent-filter>
10<action android:name="android.intent.action.VIEW" />
11<category android:name="android.intent.category.DEFAULT" />
12<data android:mimeType="vnd.android.cursor.dir/image" />
13</intent-filter>
14<intent-filter>
15<action android:name="android.intent.action.VIEW" />
16<category android:name="android.intent.category.DEFAULT" />
17<data android:mimeType="vnd.android.cursor.dir/video" />
18</intent-filter>
19<intent-filter>
20<action android:name="android.intent.action.GET_CONTENT" />
21<category android:name="android.intent.category.OPENABLE" />
22<data android:mimeType="vnd.android.cursor.dir/image" />
23</intent-filter>
24<intent-filter>
25<action android:name="android.intent.action.GET_CONTENT" />
26<category android:name="android.intent.category.OPENABLE" />
27<category android:name="android.intent.category.DEFAULT" />
28<data android:mimeType="image/*" />
29<data android:mimeType="video/*" />
30</intent-filter>
31<intent-filter>
32<action android:name="android.intent.action.PICK" />
33<category android:name="android.intent.category.DEFAULT" />
34<data android:mimeType="image/*" />
35<data android:mimeType="video/*" />
36</intent-filter>
37<intent-filter>
38<action android:name="android.intent.action.PICK" />
39<category android:name="android.intent.category.DEFAULT" />
40<data android:mimeType="vnd.android.cursor.dir/image" />
41</intent-filter>
42</activity>
复制代码
上面是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的源码,找找其中选中图片后的返回值。
复制代码
1private void launchCropperOrFinish(IImage img) {
2Bundle myExtras = getIntent().getExtras();
3
4long size = MenuHelper.getImageFileSize(img);
5if (size < 0) {
6// Return if the image file is not available.
7return;
8}
9
10if (size > mVideoSizeLimit) {
11DialogInterface.OnClickListener buttonListener =
12new DialogInterface.OnClickListener() {
13public void onClick(DialogInterface dialog, int which) {
14dialog.dismiss();
15}
16};
17new 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();
23return;
24}
25
26String cropValue = myExtras != null ? myExtras.getString("crop") : null;
27if (cropValue != null) {
28Bundle newExtras = new Bundle();
29if (cropValue.equals("circle")) {
30newExtras.putString("circleCrop", "true");
31}
32
33Intent cropIntent = new Intent();
34cropIntent.setData(img.fullSizeImageUri());
35cropIntent.setClass(this, CropImage.class);
36cropIntent.putExtras(newExtras);
37
38/* pass through any extras that were passed in */
39cropIntent.putExtras(myExtras);
40startActivityForResult(cropIntent, CROP_MSG);
41} else {
42Intent result = new Intent(null, img.fullSizeImageUri());
43if (myExtras != null && myExtras.getBoolean("return-data")) {
44// The size of a transaction should be below 100K.
45Bitmap bitmap = img.fullSizeBitmap(
46IImage.UNCONSTRAINED, 100 * 1024);
47if (bitmap != null) {
48result.putExtra("data", bitmap);
49}
50}
51setResult(RESULT_OK, result);
52finish();
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 {
14private Button btn_getImage;
15private ImageView iv_image;
16private final static String TAG = "main";
17
18@Override
19protected void onCreate(Bundle savedInstanceState) {
20super.onCreate(savedInstanceState);
21setContentView(R.layout.activity_main);
22
23btn_getImage = (Button) findViewById(R.id.btn_getImage);
24iv_image = (ImageView) findViewById(R.id.iv_image);
25
26btn_getImage.setOnClickListener(getImage);
27}
28
29private View.OnClickListener getImage = new OnClickListener() {
30
31@Override
32public void onClick(View v) {
33// 设定action和miniType
34Intent intent = new Intent();
35intent.setAction(Intent.ACTION_PICK);
36intent.setType("image/*");
37// 以需要返回值的模式开启一个Activity
38startActivityForResult(intent, 0);
39}
40};
41
42@Override
43protected void onActivityResult(int requestCode, int resultCode, Intent data) {
44// 如果获取成功,resultCode为-1
45Log.i(TAG, "resultCode:" + resultCode);
46if (requestCode == 0 && resultCode == -1) {
47// 获取原图的Uri,它是一个内容提供者
48Uri uri = data.getData();
49iv_image.setImageURI(uri);
50}
51super.onActivityResult(requestCode, resultCode, data);
52}
53 }