Android--從系統Gallery獲取圖片


前言

  在Android應用中,經常有場景會需要使用到設備上存儲的圖片,而直接從路徑中獲取無疑是非常不便利的。所以一般推薦調用系統的Gallery應用,選擇圖片,然后使用它。本篇博客將講解如何在Android中通過系統Gallery獲取圖片。

 

Gallery應用

  Android原生內置了很多App,而Gallery為圖庫,用於操作設備上的圖片,它會在開機的時候主動掃描設備上存儲的圖片,並可以使用Gallery操作它們。既然要使用Gallery,那么先看看它的AndroidManifest.xml清單文件。

 1         <activity android:name="com.android.camera.ImageGallery"
 2                 android:label="@string/gallery_label"
 3                 android:configChanges="orientation|keyboardHidden"
 4                 android:icon="@drawable/ic_launcher_gallery">
 5             <intent-filter>
 6                 <action android:name="android.intent.action.MAIN" />
 7                 <category android:name="android.intent.category.DEFAULT" />
 8             </intent-filter>
 9             <intent-filter>
10                 <action android:name="android.intent.action.VIEW" />
11                 <category android:name="android.intent.category.DEFAULT" />
12                 <data android:mimeType="vnd.android.cursor.dir/image" />
13             </intent-filter>
14             <intent-filter>
15                 <action android:name="android.intent.action.VIEW" />
16                 <category android:name="android.intent.category.DEFAULT" />
17                 <data android:mimeType="vnd.android.cursor.dir/video" />
18             </intent-filter>
19             <intent-filter>
20                 <action android:name="android.intent.action.GET_CONTENT" />
21                 <category android:name="android.intent.category.OPENABLE" />
22                 <data android:mimeType="vnd.android.cursor.dir/image" />
23             </intent-filter>
24             <intent-filter>
25                 <action android:name="android.intent.action.GET_CONTENT" />
26                 <category android:name="android.intent.category.OPENABLE" />
27                 <category android:name="android.intent.category.DEFAULT" />
28                 <data android:mimeType="image/*" />
29                 <data android:mimeType="video/*" />
30             </intent-filter>
31             <intent-filter>
32                 <action android:name="android.intent.action.PICK" />
33                 <category android:name="android.intent.category.DEFAULT" />
34                 <data android:mimeType="image/*" />
35                 <data android:mimeType="video/*" />
36             </intent-filter>
37             <intent-filter>
38                 <action android:name="android.intent.action.PICK" />
39                 <category android:name="android.intent.category.DEFAULT" />
40                 <data android:mimeType="vnd.android.cursor.dir/image" />
41             </intent-filter>
42         </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的源碼,找找其中選中圖片后的返回值。

 1     private void launchCropperOrFinish(IImage img) {
 2         Bundle myExtras = getIntent().getExtras();
 3 
 4         long size = MenuHelper.getImageFileSize(img);
 5         if (size < 0) {
 6             // Return if the image file is not available.
 7             return;
 8         }
 9 
10         if (size > mVideoSizeLimit) {
11             DialogInterface.OnClickListener buttonListener =
12                     new DialogInterface.OnClickListener() {
13                 public void onClick(DialogInterface dialog, int which) {
14                     dialog.dismiss();
15                 }
16             };
17             new AlertDialog.Builder(this)
18                     .setIcon(android.R.drawable.ic_dialog_info)
19                     .setTitle(R.string.file_info_title)
20                     .setMessage(R.string.video_exceed_mms_limit)
21                     .setNeutralButton(R.string.details_ok, buttonListener)
22                     .show();
23             return;
24         }
25 
26         String cropValue = myExtras != null ? myExtras.getString("crop") : null;
27         if (cropValue != null) {
28             Bundle newExtras = new Bundle();
29             if (cropValue.equals("circle")) {
30                 newExtras.putString("circleCrop", "true");
31             }
32 
33             Intent cropIntent = new Intent();
34             cropIntent.setData(img.fullSizeImageUri());
35             cropIntent.setClass(this, CropImage.class);
36             cropIntent.putExtras(newExtras);
37 
38             /* pass through any extras that were passed in */
39             cropIntent.putExtras(myExtras);
40             startActivityForResult(cropIntent, CROP_MSG);
41         } else {
42             Intent result = new Intent(null, img.fullSizeImageUri());
43             if (myExtras != null && myExtras.getBoolean("return-data")) {
44                 // The size of a transaction should be below 100K.
45                 Bitmap bitmap = img.fullSizeBitmap(
46                         IImage.UNCONSTRAINED, 100 * 1024);
47                 if (bitmap != null) {
48                     result.putExtra("data", bitmap);
49                 }
50             }
51             setResult(RESULT_OK, result);
52             finish();
53         }
54     }

  以上的ImageGallery.java的部分源碼,從setResult()方法可以看出,它返回的Intent包含了選中圖片的Uri,它是一個content://開頭的內容提供者,並且如果傳遞過去的Intent的Extra中,包含一個name為"return-data"並且值為true的時候,還會往Extra中寫入name為"data"的圖片縮略圖。

 

Gallery獲取圖片Demo

  既然已經知道了啟動Gallery的Action,和它如何返回選中的數據,那么接下來通過一個簡單的Demo來演示一下如何從系統Gallery中獲取圖片,並把獲取到的圖片展示到界面的一個ImageView中。

 1 package cn.bgxt.sysgallerydemo;
 2 
 3 import android.net.Uri;
 4 import android.os.Bundle;
 5 import android.util.Log;
 6 import android.view.View;
 7 import android.view.View.OnClickListener;
 8 import android.widget.Button;
 9 import android.widget.ImageView;
10 import android.app.Activity;
11 import android.content.Intent;
12 
13 public class MainActivity extends Activity {
14     private Button btn_getImage;
15     private ImageView iv_image;
16     private final static String TAG = "main";
17 
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.activity_main);
22 
23         btn_getImage = (Button) findViewById(R.id.btn_getImage);
24         iv_image = (ImageView) findViewById(R.id.iv_image);
25 
26         btn_getImage.setOnClickListener(getImage);
27     }
28 
29     private View.OnClickListener getImage = new OnClickListener() {
30 
31         @Override
32         public void onClick(View v) {
33             // 設定action和miniType
34             Intent intent = new Intent();
35             intent.setAction(Intent.ACTION_PICK);
36             intent.setType("image/*");
37             // 以需要返回值的模式開啟一個Activity
38             startActivityForResult(intent, 0);
39         }
40     };
41 
42     @Override
43     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
44         // 如果獲取成功,resultCode為-1
45         Log.i(TAG, "resultCode:" + resultCode);
46         if (requestCode == 0 && resultCode == -1) {
47             // 獲取原圖的Uri,它是一個內容提供者
48             Uri uri = data.getData();
49             iv_image.setImageURI(uri);
50         }
51         super.onActivityResult(requestCode, resultCode, data);
52     }
53 }

  效果展示:

 

  源碼下載

 

總結

  本篇博客到這里就基本上講解了如何在Android下調用系統Gallery獲取圖片,其實功能實現很簡單,主要是要注意Action和miniType不要寫錯了,並且返回值是一個Uri。雖然現在越來越多需要用到圖片的商業應用,都在自己開發獲取設備圖片的功能,但是使用系統自帶的Gallery來獲取不失為一種快速實現功能的解決辦法。為了方便起見,系統的Gallery源碼,也會一並打包放到源碼中,有需要的可以下載來看看。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM