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源码,也会一并打包放到源码中,有需要的可以下载来看看。

(0)

相关推荐

  • Android开发学习笔记 Gallery和GridView浅析

    一.Gallery的简介 Gallery(画廊)是一个锁定中心条目并且拥有水平滚动列表的视图,一般用来浏览图片,并且可以响应事件显示信息.Gallery还可以和ImageSwitcher组件结合使用来实现一个通过缩略图来浏览图片的效果. Gallery常用的XML属性 属性名称 描述 android:animationDuration 设置布局变化时动画的转换所需的时间(毫秒级).仅在动画开始时计时.该值必须是整数,比如:100. android:gravity 指定在对象的X和Y轴上如何放置内

  • Android利用ViewPager实现可滑动放大缩小画廊效果

    画廊在很多的App设计中都有,如下图所示: 该例子是我没事的时候写的一个小项目,具体源码地址请访问https://github.com/AlexSmille/YingMi. 该画廊类似封面的效果,滑到中间的图片会慢慢变大,离开的View会慢慢的缩小,同时可设置滑动监听和点击监听. 网上有很多例子都是通过Gallery实现的,而上例的实现是通过ViewPager实现,解决了性能优化的问题,今天特此把它抽出来,封装一下,以便以后的方便使用.最终实现的效果如下: 使用方式 布局中添加该自定义控件 <R

  • Android App开发中使用RecyclerView实现Gallery画廊的实例

    什么是RecyclerView         RecyclerView是Android 5.0 materials design中的组件之一,相应的还有CardView.Palette等.看名字我们就能看出一点端倪,没错,它主要的特点就是复用.我们知道,Listview中的Adapter中可以实现ViewHolder的复用.RecyclerView提供了一个耦合度更低的方式来复用ViewHolder,并且可以轻松的实现ListView.GridView以及瀑布流的效果. RecyclerVie

  • Android ViewPager画廊效果详解及实例

    Android ViewPager 画廊效果 从上面的图片可以看到,当添加多张图片的时候,能够在下方形成一个画廊的效果,我们左右拉动图片来看我们添加进去的图片,效果是不是好了很多呢?下面来看看怎么实现吧! 上面的效果类似Android里面ViewPage的效果,但是跟ViewPager有所不同,ViewPager每次只能显示一张图片. 其实我们是利用到了View的clipChildren属性,我们在这里要把ViewPager以及它的父窗体都设置为false,如下: android:clipChi

  • Android入门之Gallery用法实例解析

    本文实例介绍的Android的Gallery控件是个很不错的看图控件,可以大大减轻开发者对于看图功能的开发,并且效果也很美观.本文实例中的Gallery的用法,主要实现用反射机制来动态读取资源中的图片. 该实例代码运行的效果图如下: main.xml源码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android

  • 怎样删除android的gallery中的图片实例说明

    复制代码 代码如下: /*长按gallery中的图片进行删除该图片的操作*/ gallery.setOnItemLongClickListener(new OnItemLongClickListener(){ @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, final int arg2, long arg3) { // TODO Auto-generated method stub new Ale

  • Android画廊效果之ViewPager显示多个图片

    首先来看下ViewPager显示多个图片效果: 从上面的图片可以看到,当添加多张图片的时候,能够在下方形成一个画廊的效果,我们左右拉动图片来看我们添加进去的图片,效果是不是好了很多呢?下面来看看怎么实现吧! 上面的效果类似Android里面ViewPage的效果,但是跟ViewPager有所不同,ViewPager每次只能显示一张图片. 其实我们是利用到了View的clipChildren属性,我们在这里要把ViewPager以及它的父窗体都设置为false,如下: android:clipCh

  • Android控件Gallery3D效果实例代码

    贴上代码: 1.扩展Gallery: 复制代码 代码如下: public class GalleryFlow extends Gallery { private Camera mCamera = new Camera();//相机类 private int mMaxRotationAngle = 60;//最大转动角度 private int mMaxZoom = -300;////最大缩放值 private int mCoveflowCenter;//半径值 public GalleryFlo

  • Android viewpager 3D画廊的实现方法

    ViewPager有个方法叫做: setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 用于设置ViewPager切换时的动画效果. 这里我们只要自定义一个PageTransformer来实现我们需要的动画偏移效果就好了! public class ScrollOffsetTransformer implements PageTransformer { private static final f

  • Android入门之Gallery+ImageSwitcher用法实例解析

    继上一篇介绍了如何使用Gallery控件之后,本文就来讲一下Gallery 与ImageSwitcher的结合使用.本文所述实例代码将实现一个简单的浏览图片的功能. 先贴出程序运行截图如下: 除了Gallery可以拖拉切换图片,我在ImageSwitcher控件加入了setOnTouchListener事件实现,使得ImageSwitcher也可以在拖拉中切换图片.本例子依然使用JAVA的反射机制来自动读取资源中的图片. main.xml的源码如下: <?xml version="1.0&

  • Android开发实现Gallery画廊效果的方法

    本文实例讲述了Android开发实现Gallery画廊效果的方法.分享给大家供大家参考,具体如下: 画廊 使用Gallery表示,按水平方向显示内容,并且可以用手指直接拖动图片移动,一般用来浏览图片,被选中的选项位于中间,可以响应事件显示信息. xml布局文件基本语法 <Gallery 属性列表 /> Gallery支持4中xml属性 属性名称 描述 android:animationDuration 设置布局变化时动画的转换所需的时间(毫秒级).仅在动画开始时计时.该值必须是整数,比如:10

随机推荐