欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android从系统Gallery获取图片具体实现

程序员文章站 2022-06-29 09:30:59
前言   在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获取图片具体实现

总结

  本篇博客到这里就基本上讲解了如何在android下调用系统gallery获取图片,其实功能实现很简单,主要是要注意action和minitype不要写错了,并且返回值是一个uri。虽然现在越来越多需要用到图片的商业应用,都在自己开发获取设备图片的功能,但是使用系统自带的gallery来获取不失为一种快速实现功能的解决办法。为了方便起见,系统的gallery源码,也会一并打包放到源码中,有需要的可以下载来看看。