ContentProvider學習筆記(下)--查看內存卡上的圖片

android系統同樣爲其他的應用程序訪問多媒體資源提供了ContentProvider

MediaStore.Audio.Media.EXTERNAL_CONTENT_URI:存儲在SD卡上的音頻文件ContentProvider的URI

MediaStore.Audio.Media.INTERNAL_CONTENT_URI:存儲在手機內部存儲器卡上的音頻文件ContentProvider的URI

MediaStore.Images.Media.EXTERNAL_CONTENT_URI:存儲在SD卡上的圖像文件文件ContentProvider的URI

MediaStore.Images.Media.INTERNAL_CONTENT_URI:存儲在手機內部存儲器上圖像文件ContentProvider的URI

MediaStore.Video.Media.INTERNAL_CONTENT_URI:存儲在手機內部存儲器上的視頻文件ContentProvider的URI

MediaStore.Video.Media.EXTERNAL_CONTENT_URI:存儲在SD卡上的視頻文件ContentProvider的URI

這是在系統中,android爲我們提供的方法問多媒體庫的URI ,在這個應用中,用到了MediaStore.Images.Media.EXTERNAL_CONTENT_URI來獲取多媒體中存放在SD卡上的圖像資源,在這個小應用中,單擊查看按鈕的時候將SD卡上的圖像的名稱放在一個listview中顯示出來,單擊添加按鈕的時候,將一張圖片添加到多媒體庫中,當點擊一個item的時候,將文件名對應的圖像通過一個對話框顯示出來。

考慮到用戶在點擊查看之後,再點擊添加按鈕,這個時候ContentProvider中的數據就發生了變化,所以在應用中還需要爲ContentProvider添加一個監聽器。監聽ContentProvider數據變化的監聽器需要繼承ContentObserver類,並且重寫其中的OnChange方法,當它監聽的ContentProvider的數據發生變化的時候onChange方法就會自動的調用。

爲了監聽ContentProvider中數據的變化,還需要爲ContentResolver註冊一個監聽器,需要調用其registerContentObserver方法,其中的是三個參數解釋如下,uri:改監聽器監聽的ContentProvider的uri,notifyForDescendents:如果改參數爲true,假如註冊監聽的URI爲content://adc,那麼URI爲content://adc/xyz或者content://adc/xyx/fff的數據發生變化時候也會觸發該監聽器,否則只有URI爲content://adc的數據發生變化的時候纔會觸發監聽器,observer爲監聽器實例。

下面爲實現代碼

MainActivity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
   	android:orientation="vertical"
    >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/look"
            android:id="@+id/look"
            ></Button>
        
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add"
            android:id="@+id/add"
            
            ></Button>
    </LinearLayout>

    <ListView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
    	android:id="@+id/listview"
        >
    </ListView>

</LinearLayout>


item.xml中只有一個TextView用來顯示文件名,view.xml文件中只有一個ImageView用來顯示圖像,因此在這裏不在給出。

MainActivity.java


package com.example.myosimgview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
	private Button lookButton ;
	private Button addButton;
	private ListView listview;
	private ArrayList<Map<String,Object>> maps = new ArrayList<Map<String,Object>>();
	private ArrayList<String> filePath = new ArrayList<String>();//用來存放文件路徑的集合
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	lookButton = (Button) this.findViewById(R.id.look);
	addButton = (Button) this.findViewById(R.id.add);
	
	//爲contentresolver註冊一個監聽器,監聽MediaStore.Images.Media.EXTERNAL_CONTENT_URI
	this.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, false, new MyContentObserver(new Handler()){});

	lookButton.setOnClickListener(new OnClickListener(){

		@Override
		public void onClick(View v) {
			
			Cursor cursor = MainActivity.this.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
			
			while(cursor.moveToNext()){
				String name = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME));
				HashMap<String,Object> map = new HashMap<String,Object>();
				byte [] data = cursor.getBlob(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
				String path = new String(data);
				filePath.add(path);
				map.put("name",name);
				maps.add(map);
			}
			listview = (ListView) MainActivity.this.findViewById(R.id.listview);
			SimpleAdapter adapter = new SimpleAdapter(MainActivity.this,maps,R.layout.item,new String[]{"name"},new int []{R.id.name});
			listview.setOnItemClickListener(new OnItemClickListener(){

				@Override
				public void onItemClick(AdapterView<?> arg0, View arg1,
						int arg2, long arg3) {
					View view = MainActivity.this.getLayoutInflater().inflate(R.layout.view, null);
					ImageView image = (ImageView) view.findViewById(R.id.image);
					image.setImageBitmap(BitmapFactory.decodeFile(filePath.get(arg2)));
					new AlertDialog.Builder(MainActivity.this).setView(view).setPositiveButton("確定", null).show();
				}
			});
			listview.setAdapter(adapter);
		}
	});
	
	
	addButton.setOnClickListener(new OnClickListener(){

		@Override
		public void onClick(View v) {
			Bitmap bitmap =  BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.a);
			String resultURI = MediaStore.Images.Media.insertImage(MainActivity.this.getContentResolver(), bitmap, "美女","清純美女");
			if(resultURI != null){
				Toast.makeText(MainActivity.this, "添加圖片成功", 0).show();
				//當ContentProvider中的數據發生變化的時候,通知所有的監聽者(第二個參數爲null表示通知所有的監聽者)
				MainActivity.this.getContentResolver().notifyChange(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null);
			}
		}});
	}
	
	private class MyContentObserver extends ContentObserver{

		public MyContentObserver(Handler handler) {
			super(handler);
			// TODO Auto-generated constructor stub
		}
		
		@Override
		public void onChange(boolean selfChange) {
			//當收到了數據改變通知的時候,用Toast的方式通知用戶
			Toast.makeText(MainActivity.this, "系統中添加了新圖片,請按查看按鈕查看", 0).show();
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
}


本文參考用書:《Android瘋狂講義》

文章系原創,轉載請註明出處



發佈了31 篇原創文章 · 獲贊 31 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章