Android疑惑之使用ContentProvider实现数据共享
Anroid疑惑之使用ContentProvider实现数据共享
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); } }