Android从系统Gallery获取图片具体实现
前言
在android应用中,经常有场景会需要使用到设备上存储的图片,而直接从路径中获取无疑是非常不便利的。所以一般推荐调用系统的gallery应用,选择图片,然后使用它。本篇博客将讲解如何在android中通过系统gallery获取图片。
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"的图片缩略图。
gallery获取图片demo
既然已经知道了启动gallery的action,和它如何返回选中的数据,那么接下来通过一个简单的demo来演示一下如何从系统gallery中获取图片,并把获取到的图片展示到界面的一个imageview中。
package cn.bgxt.sysgallerydemo;
import android.net.uri;
import android.os.bundle;
import android.util.log;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.button;
import android.widget.imageview;
import android.app.activity;
import android.content.intent;
public class mainactivity extends activity {
private button btn_getimage;
private imageview iv_image;
private final static string tag = "main";
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
btn_getimage = (button) findviewbyid(r.id.btn_getimage);
iv_image = (imageview) findviewbyid(r.id.iv_image);
btn_getimage.setonclicklistener(getimage);
}
private view.onclicklistener getimage = new onclicklistener() {
@override
public void onclick(view v) {
// 设定action和minitype
intent intent = new intent();
intent.setaction(intent.action_pick);
intent.settype("image/*");
// 以需要返回值的模式开启一个activity
startactivityforresult(intent, 0);
}
};
@override
protected void onactivityresult(int requestcode, int resultcode, intent data) {
// 如果获取成功,resultcode为-1
log.i(tag, "resultcode:" + resultcode);
if (requestcode == 0 && resultcode == -1) {
// 获取原图的uri,它是一个内容提供者
uri uri = data.getdata();
iv_image.setimageuri(uri);
}
super.onactivityresult(requestcode, resultcode, data);
}
}
效果展示:
总结
本篇博客到这里就基本上讲解了如何在android下调用系统gallery获取图片,其实功能实现很简单,主要是要注意action和minitype不要写错了,并且返回值是一个uri。虽然现在越来越多需要用到图片的商业应用,都在自己开发获取设备图片的功能,但是使用系统自带的gallery来获取不失为一种快速实现功能的解决办法。为了方便起见,系统的gallery源码,也会一并打包放到源码中,有需要的可以下载来看看。
下一篇: 菠萝炒鸡肉的做法,这样做美味又健康