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>
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瘋狂講義》
文章系原創,轉載請註明出處