`

使用contentprovider共享生词本数据

阅读更多
摘自李刚<疯狂android>备份学习使用

首先我们为该contentprovider定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下:
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所允许操作的三个数据列
		public static final String _ID = "_id";
		public static final String WORD = "word";
		public static final String DETAIL = "detail";
		
		//定义该content提供服务的两个Uri
		public static final Uri DICT_CONTETN_URI =
			Uri.parse("content://" + AUTHORITY + "/words");
		public static final Uri WORD_CONTENT_URI = 
			Uri.parse("content://" + AUTHORITY + "/word");
	}
}


上面的工具类只是定义了一些简单的工具类,这个工具类的作用就是告诉其他应用程序,访问该contentprovider的一些常用入口。

数据库创建MyDatabaseHelper代码:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDatabaseHelper extends SQLiteOpenHelper{

	private final String CREATE_TABLE_SQL= 
		"create table dict(_id integer primary key autoincrement, word , detail)";
	
	public MyDatabaseHelper(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, 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的子类,并重写其中的增、删、改、查等方法,类代码如下。

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;

import com.dictprovider.content.Words;
import com.mydatabasehelper.database.MyDatabaseHelper;

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{
		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", null, 1);
		return true;
	}
	
	@Override
	public Uri insert(Uri uri, ContentValues values) {
		//获得数据库实例
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		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:{
			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;
		}
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return num;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		int num = 0;
		switch(matcher.match(uri)){
		case WORDS:{
			num = db.update("dict", values, selection, selectionArgs);
			break;
		}
		case WORD:{
			long id = ContentUris.parseId(uri);
			String where = Words.Word._ID + "=" + id;
			if(selection != null && !"".equals(selection)){
				where = where + " and " + selection;
			}
			num = db.update("dict", values, where, selectionArgs);
			break;
		}
		}
		getContext().getContentResolver().notifyChange(uri, null);
		return num;
	}

	
	@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";
		}
		}
		return null;
	}

	@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:{
			long id = ContentUris.parseId(uri);
			String where = Words.Word._ID + "=" + id;
			if(selection != null && !selection.equals("")){
				where = where + " and " + selection;
			}
			return db.query("dict", projection, selection, selectionArgs, null, null, sortOrder);
		}
		}
		return null;
	}
}



上面的dictProvider类很简单,它除了继承系统的contentprovider之外,还实现了操作数据的增、删、改、查等方法,那木该contentprovider就开发完成了。

接下来需要在androidmanifest.xml文件中注册该contentprovider,这就需要在androidmanifest.xml文件中增加如下配置片段:
<provider android:name="com.dictprovider.provider.DictProvider"
            android:authorities="org.crazyit.providers.dictprovider"/>


至此,暴露生词本数据的contentprovider开发完成。为了测试该contentprovider的开发是否成功,接下来再开发一个应用程序,该应用程序将会通过contentresolver来操作生词本中的数据。
该程序同样提供了添加生词、查询生词的功能,只是改程序并不保存数据,而是访问前面dictProvider所共享的数据,下面是contentresolver的类的代码。

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.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.dictprovider.content.Words;
import com.dictprovider.observer.WordObserver;

public class MainActivity extends Activity {

	ContentResolver contentResolver;
	Button insert = null;
	Button search = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//获取系统contentresolver对象
		contentResolver = getContentResolver();
		getContentResolver().registerContentObserver(Uri.parse("content://" + Words.AUTHORITY), true, new WordObserver(this,new Handler()));
		
		
		insert = (Button)findViewById(R.id.insert);
		search = (Button)findViewById(R.id.search);
		
		insert.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				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_CONTETN_URI, values);
				Toast.makeText(MainActivity.this, "insert success", Toast.LENGTH_SHORT).show();
			}
		});
		
		search.setOnClickListener(new OnClickListener() {
			
			//获取用户输入
			@Override
			public void onClick(View v) {
				String key = ((EditText)findViewById(R.id.key)).getText().toString();
			
			//执行查询
			Cursor cursor = contentResolver.query(
					Words.Word.DICT_CONTETN_URI, null, 
					"word like ? or detail like ?", 
					new String[]{"%" + key + "%", "%" + key + "%"}, 
					null);
			
			//创建一个bundle对象
			Bundle data = new Bundle();
			data.putSerializable("data", converCursorToList(cursor));
			
			Intent intent = new Intent(MainActivity.this, ResultActivity.class);
			intent.putExtras(data);
			startActivity(intent);
			}
		});
	}
	
	private ArrayList<Map<String, String>> converCursorToList(Cursor cursor){
		ArrayList<Map<String, String>> result = new ArrayList<Map<String,String>>();
		while(cursor.moveToNext()){
			Map<String, String> map = new HashMap<String, String>();
			map.put(Words.Word.WORD, cursor.getString(1));
			map.put(Words.Word.DETAIL, cursor.getString(2));
			result.add(map);
		}
		return result;
	}
}



工程代码见附件
分享到:
评论

相关推荐

    Android实现使用自定义ContentProvider共享生词本数据库

    将任务01生词本作业中生成的生词本数据库通过自定义ContentProvider的方式,共享给其他应用。 要求如下: (1) 使用自定义SQLiteOpenHelper来管理数据库; (2) 提交作业应列出操作数据的Uri及数据表的字段名称; (3) ...

    实验8 contentProvider共享数据1

    在本实验中,我们将学习如何创建和使用`ContentProvider`,以及如何通过`ContentResolver`和`ContentObserver`来与`ContentProvider`交互。 一、ContentProvider基础 `ContentProvider`是Android四大组件之一,它...

    安卓生词本源码sqlite

    - ContentProvider遵循Android的URI模式,使得其他应用程序也能安全地访问生词本数据。 6. CursorLoader和LoaderManager: - 对于UI线程与数据库交互,推荐使用CursorLoader,它基于LoaderManager,能够在后台...

    Android studio移动应用开发—生词表

    8. **ContentProvider**: 如果选择使用SQLite数据库,可以考虑使用ContentProvider来统一数据访问接口,虽然对于初级项目这不是必须的。 9. **Intent**: Intent是Android中用来启动Activity或Service,传递数据的...

    疯狂Andriod讲义——实例章节

    书中提供了大量的实例,演示了如何使用这些组件实现特定功能,如启动服务、接收广播消息、共享数据等。 ### 资源访问与图形/图像处理 资源访问是Android应用开发中的另一个关键环节。本书详细阐述了如何加载和使用...

    开心词场论文

    - **ContentProvider**:管理应用程序间的数据共享。 ##### 英语背单词软件的需求分析与性能分析 - **需求分析**:明确用户对背单词软件的基本需求,如支持多种学习模式、个性化复习计划等。 - **性能分析**:评估...

    CIDIAN.rar_android开发_Java_

    对于Android开发,还要掌握Android特有的组件,如BroadcastReceiver、Service和ContentProvider,它们分别用于全局事件监听、后台服务执行和数据共享。 描述中提到“可以提供准备考研的人们更好地学习英语”,这...

Global site tag (gtag.js) - Google Analytics