zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

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

Android系统 实现 获取 图片 具体 gallery
2023-06-13 09:15:13 时间

前言

  在Android应用中,经常有场景会需要使用到设备上存储的图片,而直接从路径中获取无疑是非常不便利的。所以一般推荐调用系统的Gallery应用,选择图片,然后使用它。本篇博客将讲解如何在Android中通过系统Gallery获取图片。

Gallery应用

  Android原生内置了很多App,而Gallery为图库,用于操作设备上的图片,它会在开机的时候主动扫描设备上存储的图片,并可以使用Gallery操作它们。既然要使用Gallery,那么先看看它的AndroidManifest.xml清单文件。

复制代码代码如下:


<activityandroid:name="com.android.camera.ImageGallery"
               android:label="@string/gallery_label"
               android:configChanges="orientation|keyboardHidden"
               android:icon="@drawable/ic_launcher_gallery">
           <intent-filter>
               <actionandroid:name="android.intent.action.MAIN"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.VIEW"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
               <dataandroid:mimeType="vnd.android.cursor.dir/image"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.VIEW"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
               <dataandroid:mimeType="vnd.android.cursor.dir/video"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.GET_CONTENT"/>
               <categoryandroid:name="android.intent.category.OPENABLE"/>
               <dataandroid:mimeType="vnd.android.cursor.dir/image"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.GET_CONTENT"/>
               <categoryandroid:name="android.intent.category.OPENABLE"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
               <dataandroid:mimeType="image/*"/>
               <dataandroid:mimeType="video/*"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.PICK"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
               <dataandroid:mimeType="image/*"/>
               <dataandroid:mimeType="video/*"/>
           </intent-filter>
           <intent-filter>
               <actionandroid:name="android.intent.action.PICK"/>
               <categoryandroid:name="android.intent.category.DEFAULT"/>
               <dataandroid: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的源码,找找其中选中图片后的返回值。

复制代码代码如下:

privatevoidlaunchCropperOrFinish(IImageimg){
       BundlemyExtras=getIntent().getExtras();

       longsize=MenuHelper.getImageFileSize(img);
       if(size<0){
           //Returniftheimagefileisnotavailable.
           return;
       }

       if(size>mVideoSizeLimit){
           DialogInterface.OnClickListenerbuttonListener=
                   newDialogInterface.OnClickListener(){
               publicvoidonClick(DialogInterfacedialog,intwhich){
                   dialog.dismiss();
               }
           };
           newAlertDialog.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;
       }

       StringcropValue=myExtras!=null?myExtras.getString("crop"):null;
       if(cropValue!=null){
           BundlenewExtras=newBundle();
           if(cropValue.equals("circle")){
               newExtras.putString("circleCrop","true");
           }

           IntentcropIntent=newIntent();
           cropIntent.setData(img.fullSizeImageUri());
           cropIntent.setClass(this,CropImage.class);
           cropIntent.putExtras(newExtras);

           /*passthroughanyextrasthatwerepassedin*/
           cropIntent.putExtras(myExtras);
           startActivityForResult(cropIntent,CROP_MSG);
       }else{
           Intentresult=newIntent(null,img.fullSizeImageUri());
           if(myExtras!=null&&myExtras.getBoolean("return-data")){
               //Thesizeofatransactionshouldbebelow100K.
               Bitmapbitmap=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中。

复制代码代码如下:
packagecn.bgxt.sysgallerydemo;

importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.ImageView;
importandroid.app.Activity;
importandroid.content.Intent;

publicclassMainActivityextendsActivity{
   privateButtonbtn_getImage;
   privateImageViewiv_image;
   privatefinalstaticStringTAG="main";

   @Override
   protectedvoidonCreate(BundlesavedInstanceState){
       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);
   }

   privateView.OnClickListenergetImage=newOnClickListener(){

       @Override
       publicvoidonClick(Viewv){
           //设定action和miniType
           Intentintent=newIntent();
           intent.setAction(Intent.ACTION_PICK);
           intent.setType("image/*");
           //以需要返回值的模式开启一个Activity
           startActivityForResult(intent,0);
       }
   };

   @Override
   protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
       //如果获取成功,resultCode为-1
       Log.i(TAG,"resultCode:"+resultCode);
       if(requestCode==0&&resultCode==-1){
           //获取原图的Uri,它是一个内容提供者
           Uriuri=data.getData();
           iv_image.setImageURI(uri);
       }
       super.onActivityResult(requestCode,resultCode,data);
   }
}

  效果展示:

总结

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