(四十四)通过系统Gallery获取图片
1、前言
在Android应用中,经常有场景会需要使用到设备上存储的图片,而直接从路径中获取无疑是非常不便利的。所以一般推荐调用系统的Gallery应用,选择图片,然后使用它。本文将讲解如何在Android中通过系统Gallery获取图片。
2、Gallery应用
Android原生内置了很多App,而Gallery为图库,用于操作设备上的图片,它会在开机的时候主动扫描设备上存储的图片,并可以使用Gallery操作它们。既然要使用Gallery,那么先看看它的AndroidManifest.xml清单文件。
<activity android:name="com.android.camera.ImageGallery" android:label="@string/gallery_label" android:configChanges="orientation|keyboardHidden" android:icon="@drawable/ic_launcher_gallery"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/image" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/video" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.OPENABLE" /> <data android:mimeType="vnd.android.cursor.dir/image" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.GET_CONTENT" /> <category android:name="android.intent.category.OPENABLE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> <data android:mimeType="video/*" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.dir/image" /> </intent-filter> </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的源码,找找其中选中图片后的返回值。
private void launchCropperOrFinish(IImage img) { Bundle myExtras = getIntent().getExtras(); long size = MenuHelper.getImageFileSize(img); if (size < 0) { // Return if the image file is not available. return; } if (size > mVideoSizeLimit) { DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }; new AlertDialog.Builder(this) .setIcon(android.R.drawable.ic_dialog_info) .setTitle(R.string.file_info_title) .setMessage(R.string.video_exceed_mms_limit) .setNeutralButton(R.string.details_ok, buttonListener) .show(); return; } String cropValue = myExtras != null ? myExtras.getString("crop") : null; if (cropValue != null) { Bundle newExtras = new Bundle(); if (cropValue.equals("circle")) { newExtras.putString("circleCrop", "true"); } Intent cropIntent = new Intent(); cropIntent.setData(img.fullSizeImageUri()); cropIntent.setClass(this, CropImage.class); cropIntent.putExtras(newExtras); /* pass through any extras that were passed in */ cropIntent.putExtras(myExtras); startActivityForResult(cropIntent, CROP_MSG); } else { Intent result = new Intent(null, img.fullSizeImageUri()); if (myExtras != null && myExtras.getBoolean("return-data")) { // The size of a transaction should be below 100K. Bitmap bitmap = img.fullSizeBitmap( IImage.UNCONSTRAINED, 100 * 1024); if (bitmap != null) { result.putExtra("data", bitmap); } } setResult(RESULT_OK, result); finish(); } }
以上的ImageGallery.java的部分源码,从setResult()方法可以看出,它返回的Intent包含了选中图片的Uri,它是一个content://开头的内容提供者,并且如果传递过去的Intent的Extra中,包含一个name为"return-data"并且值为true的时候,还会往Extra中写入name为"data"的图片缩略图。
3、Gallery获取图片Demo
既然已经知道了启动Gallery的Action,和它如何返回选中的数据,那么接下来通过一个简单的Demo来演示一下如何从系统Gallery中获取图片,并把获取到的图片展示到界面的一个ImageView中。
package com.example.gallerytest; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity implements OnClickListener { private Button btn_getImage; private ImageView iv_image; private final static String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_getImage = (Button) findViewById(R.id.bt); iv_image = (ImageView) findViewById(R.id.iv); btn_getImage.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); intent.setType("image/*"); // 以需要放回值得模式 startActivityForResult(intent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub if (requestCode == 0 && resultCode == -1) { Uri uri = data.getData(); iv_image.setImageURI(uri); } super.onActivityResult(requestCode, resultCode, data); } }
4、转载自:http://www.fengfly.com/plus/view-214216-2.html