ContentProvider是我學習安卓這幾個月以來碰到最難理解的一塊,感覺很難掌握,不知道如何使用這一塊內容,有些方法的參數使用起來真的是令人發指,我也不打算一下子把全部內容都運用自如,那是不可能的事情,下面是學習ContentProvider所實現的一個實例:
實例:使用ContentProvider共享生詞本數據
這個實例可以簡單實現添加生詞和查詢生詞的功能,我原本想擴展一下這個應用程序的功能,但卻不知道從何做起,只是簡簡單單換了了界面背景就是了。
創建項目:DictProvider
項目運行效果:
下面只給出主要代碼布局文件和string資源文件均不給出
運行以上項目需要在Menifest文件注冊相關信息,和設置相關權限
- <activity Android:name=".ResultActivity"
- android:theme="@android:style/Theme.Dialog"
- android:label="找到的單詞">
- </activity>
- <provider android:name=".DictProvider"
- android:authorities="org.crazyit.providers.dictprovider"/>
定義的工具類:Words.java
- package wwj.dictprovider;
-
- import android.net.Uri;
-
- import android.provider.BaseColumns;
- public final class Words
- {
- // 定義該ContentProvider的Authority
- public static final String AUTHORITY
- = "org.crazyit.providers.dictprovider";
- //定義一個靜態內部類
- public static final class Word implements BaseColumns
- {
- // 定義Content所允許操作的3個數據列
- public final static String _ID = "_id";
- public final static String WORD = "word";
- public final static String DETAIL = "detail";
- // 定義該Content提供服務的兩個Uri
- public final static Uri DICT_CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/words");
- public final static Uri WORD_CONTENT_URI =
- Uri.parse("content://" + AUTHORITY + "/word");
- }
- }
因為要用到SQLite數據庫,所以需要繼承SQLiteOpenHelper類
==>MyDatabaseHelper.java
- package wwj.dictprovider;
-
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
-
- public class MyDatabaseHelper extends SQLiteOpenHelper
- {
- final String CREATE_TABLE_SQL =
- "create table dict(_id integer primary key autoincrement , word , detail)";
- /**
- * @param context
- * @param name
- * @param version
- */
- public MyDatabaseHelper(Context context, String name, int version)
- {
- super(context, name, null, version);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db)
- {
- // 第一個使用數據庫時自動建表
- db.execSQL(CREATE_TABLE_SQL);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
- {
- System.out.println("--------onUpdate Called--------"
- + oldVersion + "--->" + newVersion);
- }
- }
實現ContentProvider類:DictProvider.java
- package wwj.dictprovider;
-
- import android.content.ContentProvider;
- import android.content.ContentUris;
- import android.content.ContentValues;
- import android.content.UriMatcher;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.net.Uri;
-
- public class DictProvider extends ContentProvider
- {
- private static UriMatcher matcher
- = new UriMatcher(UriMatcher.NO_MATCH);
- private static final int WORDS = 1;
- private static final int WORD = 2;
- private MyDatabaseHelper dbOpenHelper;
- static
- {
- // 為UriMatcher注冊兩個Uri
- matcher.addURI(Words.AUTHORITY, "words", WORDS);
- matcher.addURI(Words.AUTHORITY, "word/#", WORD);
- }
- // 第一次調用該DictProvider時,系統先創建DictProvider對象,並回調該方法
- @Override
- public boolean onCreate()
- {
- dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1);
- return true;
- }
- // 插入數據方法
- @Override
- public Uri insert(Uri uri, ContentValues values)
- {
- // 獲得數據庫實例
- SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
- // 插入數據,返回行ID
- long rowId = db.insert("dict", Words.Word._ID, values);
- // 如果插入成功返回uri
- if (rowId > 0)
- {
- // 在已有的 Uri的後面追加ID數據
- Uri wordUri = ContentUris.withAppendedId(uri, rowId);
- // 通知數據已經改變
- getContext().getContentResolver().notifyChange(wordUri, null);
- return wordUri;
- }
- return null;
- }
- // 刪除數據的方法
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs)
- {
- SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
- // 記錄所刪除的記錄數
- int num = 0;
- // 對於uri進行匹配。
- switch (matcher.match(uri))
- {
- case WORDS:
- num = db.delete("dict", selection, selectionArgs);
- break;
- case WORD:
- // 解析出所需要刪除的記錄ID
- long id = ContentUris.parseId(uri);
- String where = Words.Word._ID + "=" + id;
- // 如果原來的where子句存在,拼接where子句
- if (selection != null && !selection.equals(""))
- {
- where = where + " and " + selection;
- }
- num = db.delete("dict", where, selectionArgs);
- break;
- default:
- throw new IllegalArgumentException("未知Uri:" + uri);
- }
- // 通知數據已經改變
- getContext().getContentResolver().notifyChange(uri, null);
- return num;
- }
- // 修改數據的方法
- @Override
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs)
- {
- SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
- // 記錄所修改的記錄數
- int num = 0;
- switch (matcher.match(uri))
- {
- case WORDS:
- num = db.update("dict", values, selection, selectionArgs);
- break;
- case WORD:
- // 解析出想修改的記錄ID
- long id = ContentUris.parseId(uri);
- String where = Words.Word._ID + "=" + id;
- // 如果原來的where子句存在,拼接where子句
- if (selection != null && !selection.equals(""))
- {
- where = where + " and " + selection;
- }
- num = db.update("dict", values, where, selectionArgs);
- break;
- default:
- throw new IllegalArgumentException("未知Uri:" + uri);
- }
- // 通知數據已經改變
- getContext().getContentResolver().notifyChange(uri, null);
- return num;
- }
- // 查詢數據的方法
- @Override
- public Cursor query(Uri uri, String[] projection, String selection,
- String[] selectionArgs, String sortOrder)
- {
- SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
- switch (matcher.match(uri))
- {
- case WORDS:
- // 執行查詢
- return db.query("dict", projection, selection, selectionArgs,
- null, null, sortOrder);
- case WORD:
- // 解析出想查詢的記錄ID
- long id = ContentUris.parseId(uri);
- String where = Words.Word._ID + "=" + id;
- // 如果原來的where子句存在,拼接where子句
- if (selection != null && !"".equals(selection))
- {
- where = where + " and " + selection;
- }
- return db.query("dict", projection, where, selectionArgs, null,
- null, sortOrder);
- default:
- throw new IllegalArgumentException("未知Uri:" + uri);
- }
- }
- // 返回指定uri參數對應的數據的MIME類型
- @Override
- public String getType(Uri uri)
- {
- switch(matcher.match(uri))
- {
- // 如果操作的數據是多項記錄
- case WORDS:
- return "vnd.android.cursor.dir/org.crazyit.dict";
- // 如果操作的數據是單項記錄
- case WORD:
- return "vnd.android.cursor.item/org.crazyit.dict";
- default:
- throw new IllegalArgumentException("未知Uri:" + uri);
- }
- }
- }
主Activity文件:DictResolver.java
- package wwj.dictprovider;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Map;
-
- import android.app.Activity;
- import android.content.ContentResolver;
- import android.content.ContentValues;
- import android.content.Intent;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
-
- public class DictResolver extends Activity
- {
- ContentResolver contentResolver;
- Button insert = null;
- Button search = null;
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- // 獲取系統的ContentResolver對象
- contentResolver = getContentResolver();
- insert = (Button)findViewById(R.id.insert);
- search = (Button)findViewById(R.id.search);
- // 為insert按鈕的單擊事件綁定事件監聽器
- insert.setOnClickListener(new OnClickListener()
- {
- @Override
- public void onClick(View source)
- {
- //獲取用戶輸入
- String word = ((EditText)findViewById(R.id.word))
- .getText().toString();
- String detail = ((EditText)findViewById(R.id.detail))
- .getText().toString();
- //插入生詞記錄
- ContentValues values = new ContentValues();
- values.put(Words.Word.WORD , word);
- values.put(Words.Word.DETAIL , detail);
- contentResolver.insert(Words.Word.DICT_CONTENT_URI, values);
- //顯示提示信息
- Toast.makeText(DictResolver.this, "添加生詞成功!" , 8000)
- .show();
- }
- });
- // 為search按鈕的單擊事件綁定事件監聽器
- search.setOnClickListener(new OnClickListener()
- {
- @Override
- public void onClick(View source)
- {
- // 獲取用戶輸入
- String key = ((EditText) findViewById(R.id.key)).getText()
- .toString();
- // 執行查詢
- Cursor cursor = contentResolver.query(
- Words.Word.DICT_CONTENT_URI, null
- , "word like ? or detail like ?"
- , new String[]{"%" + key + "%" , "%" + key + "%"}
- , null);
- //創建一個Bundle對象
- Bundle data = new Bundle();
- data.putSerializable("data", converCursorToList(cursor));
- //創建一個Intent
- Intent intent = new Intent(DictResolver.this
- , ResultActivity.class);
- intent.putExtras(data);
- //啟動Activity
- startActivity(intent);
- }
- });
- }
-
- private ArrayList<Map<String, String>> converCursorToList(
- Cursor cursor)
- {
- ArrayList<Map<String, String>> result
- = new ArrayList<Map<String, String>>();
- // 遍歷Cursor結果集
- while (cursor.moveToNext())
- {
- // 將結果集中的數據存入ArrayList中
- Map<String, String> map = new HashMap<String, String>();
- // 取出查詢記錄中第2列、第3列的值
- map.put(Words.Word.WORD, cursor.getString(1));
- map.put(Words.Word.DETAIL, cursor.getString(2));
- result.add(map);
- }
- return result;
- }
- }
ResultActivity.java
- package wwj.dictprovider;
-
- import java.util.List;
- import java.util.Map;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
-
- public class ResultActivity extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.popup);
- ListView listView = (ListView)findViewById(R.id.show);
- Intent intent = getIntent();
- //獲取該intent所攜帶的數據
- Bundle data = intent.getExtras();
- //從Bundle數據包中取出數據
- @SuppressWarnings("unchecked")
- List<Map<String, String>> list =
- (List<Map<String, String>>)data.getSerializable("data");
- //將List封裝成SimpleAdapter
- SimpleAdapter adapter = new SimpleAdapter(ResultActivity.this, list, R.layout.line
- , new String[]{"word", "detail"}
- , new int[]{R.id.word, R.id.detail});
- //填充ListView
- listView.setAdapter(adapter);
- }
- }