《SQLite数据库与Contentprovider(2)》要点:
本文介绍了SQLite数据库与Contentprovider(2),希望对您有用。如果有疑问,可以联系我们。
ContentProvider:
在创建ContentProvider时,必要首先使用数据库、文件系统或网络实现底层存储功能,
然后在继承ContentProvider的类中实现基本数据操作的接口函数,包含添加、删除、查找和更新等功能.
调用者不能够直接调用ContentProvider的接口函数,而必要使用ContentResolver对象,
通过URI间接调用ContentProvider.下图是ContentProvider调用关系.
URI:
URI是通用资源标志符(Uniform Resource Identifier),用来定位任何远程或当地的可用资源
ContentProvider使用的URI语法布局如下
content://<authority>/<data_path>/<id>
content://是通用前缀,表现该URI用于ContentProvider定位资源,无需修改.
<authority>是授权者名称,用来确定具体由哪一个ContentProvider提供资源.因此,一般<authority>都由类的小写全称组成,以保证唯一性.
<data_path>是数据路径,用来确定哀求的是哪个数据集.
例如:
content://edu.hrbeu.peopleprovider/people/3
可以省略id(/3)部门那么意味着整个数据.
UriMatcher:
在新构造的ContentProvider类中,通过构造一个UriMatcher,判断URI是单条数据还是多条数据.
public void addURI (String authority, String path, int code)
authority表现匹配的授权者名称
path表现数据路径
#可以代表任何数字 (content://<authority>/<data_path>/#)
code表现返回代码(uriMatcher.match(uri))的返回值)
注册ContentProvider :
<provider android:name = ".PeopleProvider" android:authorities = "edu.hrbeu.peopleprovider"/>
实例:
ContentProvider一般用于两个分歧的进程之间的数据共享.
首先是步骤1:
*只要在AndroidManifast中注册provider就会执行对应的provider类.无需再MainActivity中调用或无需直接调用自定义的new provider.
即系统自动会加载调用PeopleProvider类.
继承ContentProvider时代码如下:
import android.content.*;import android.database.Cursor;import android.net.Uri; public class PeopleProvider extends ContentProvider{ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub return null; } @Override public boolean onCreate { // TODO Auto-generated method stub return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; }}
类似数据库操作.可以这么理解,相对来说好理解.
开始贴代码...
package edu.hrbeu.contentproviderdemo; import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.content.UriMatcher;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;public class PeopleProvider extends ContentProvider { private static final String DB_NAME = "people.db"; private static final String DB_TABLE = "peopleinfo"; private static final int DB_VERSION = 1; private SQLiteDatabase db; private DBOpenHelper dbOpenHelper; private static final int MULTIPLE_PEOPLE = 1; private static final int SINGLE_PEOPLE = 2; private static final UriMatcher uriMatcher; static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(People.AUTHORITY, People.PATH_MULTIPLE, MULTIPLE_PEOPLE); uriMatcher.addURI(People.AUTHORITY, People.PATH_SINGLE, SINGLE_PEOPLE); } @Override public boolean onCreate { // TODO Auto-generated method stub Context context = getContext; dbOpenHelper = new DBOpenHelper(context, DB_NAME, null, DB_VERSION); db = dbOpenHelper.getWritableDatabase; if (db == null) return false; else return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteQueryBuilder qb = new SQLiteQueryBuilder; qb.setTables(DB_TABLE); switch(uriMatcher.match(uri)){ case SINGLE_PEOPLE: qb.appendWhere(People.KEY_ID + "=" + uri.getPathSegments.get(1)); break; default: break; } Cursor cursor = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext.getContentResolver, uri); return cursor; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: return People.MINE_TYPE_MULTIPLE; case SINGLE_PEOPLE: return People.MINE_TYPE_SINGLE; default: throw new IllegalArgumentException("Unkown uri:"+uri);} } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub long id = db.insert(DB_TABLE, null, values); if ( id > 0 ){ Uri newUri = ContentUris.withAppendedId(People.CONTENT_URI, id); getContext.getContentResolver.notifyChange(newUri, null); return newUri; } throw new SQLException("Failed to insert row into " + uri); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count = 0; switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: count = db.delete(DB_TABLE, selection, selectionArgs); break; case SINGLE_PEOPLE: String segment = uri.getPathSegments.get(1); count = db.delete(DB_TABLE, People.KEY_ID + "=" + segment, selectionArgs); break; default: throw new IllegalArgumentException("Unsupported URI:" + uri);} getContext.getContentResolver.notifyChange(uri, null); return count; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count; switch(uriMatcher.match(uri)){ case MULTIPLE_PEOPLE: count = db.update(DB_TABLE, values, selection, selectionArgs); break; case SINGLE_PEOPLE: String segment = uri.getPathSegments.get(1); count = db.update(DB_TABLE, values, People.KEY_ID+"="+segment, selectionArgs); break; default: throw new IllegalArgumentException("Unknow URI:" + uri); } getContext.getContentResolver.notifyChange(uri, null); return count; } private static class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } private static final String DB_CREATE = "create table " + DB_TABLE + " (" + People.KEY_ID + " integer primary key autoincrement, " + People.KEY_NAME+ " text not null, " + People.KEY_AGE+ " integer," + People.KEY_HEIGHT + " float);"; @Override public void onCreate(SQLiteDatabase _db) { // TODO Auto-generated method stub _db.execSQL(DB_CREATE); } @Override public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) { // TODO Auto-generated method stub _db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE); onCreate(_db); } } }
package edu.hrbeu.contentproviderdemo;import android.net.Uri; public class People{ public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir"; public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item"; public static final String MINE_ITEM = "vnd.hrbeu.people"; public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MINE_ITEM; public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MINE_ITEM; public static final String AUTHORITY = "edu.hrbeu.peopleprovider"; public static final String PATH_SINGLE = "people/#"; public static final String PATH_MULTIPLE = "people"; public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE; public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); public static final String KEY_ID = "_id"; public static final String KEY_NAME = "name"; public static final String KEY_AGE = "age"; public static final String KEY_HEIGHT = "height";}
MainActivity是空的...不贴出来了.
运行成果没有任何内容,因为仅是添加了一个provider.
看一下步调2:
在另一个App中调用此ContentProvider.
无需再AndroidManifast中注册provider.
只需对应步骤1中的People类里的静态变量是完全匹配的便是可以了.
也就是说URI需要与我们自定义的ContentProvider坚持一致.
package edu.hrbeu.contentresolverdemo;import android.net.Uri; public class People{ public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir"; public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item"; public static final String MINE_ITEM = "vnd.hrbeu.people"; public static final String MINE_TYPE_SINGLE = MIME_ITEM_PREFIX + "/" + MINE_ITEM; public static final String MINE_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/" + MINE_ITEM; public static final String AUTHORITY = "edu.hrbeu.peopleprovider"; public static final String PATH_SINGLE = "people/#"; public static final String PATH_MULTIPLE = "people"; public static final String CONTENT_URI_STRING = "content://" + AUTHORITY + "/" + PATH_MULTIPLE; public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); public static final String KEY_ID = "_id"; public static final String KEY_NAME = "name"; public static final String KEY_AGE = "age"; public static final String KEY_HEIGHT = "height";}
操作Contentpriver提供的数据我们必要用到ContentResolver:
package edu.hrbeu.contentresolverdemo;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class ContentResolverDemo extends Activity { private EditText nameText; private EditText ageText; private EditText heightText; private EditText idEntry; private TextView labelView; private TextView displayView; private ContentResolver resolver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_content_resolver_demo); nameText = (EditText) findViewById(R.id.name); ageText = (EditText) findViewById(R.id.age); heightText = (EditText) findViewById(R.id.hight); idEntry = (EditText) findViewById(R.id.id); labelView = (TextView) findViewById(R.id.label); displayView = (TextView) findViewById(R.id.display); Button addButton = (Button) findViewById(R.id.button1); Button queryAllButton = (Button) findViewById(R.id.button2); Button clearButton = (Button) findViewById(R.id.button3); Button queryButton = (Button) findViewById(R.id.button6); Button deleteButton = (Button) findViewById(R.id.button5); Button updateButton = (Button) findViewById(R.id.button7); resolver = this.getContentResolver; addButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub ContentValues values = new ContentValues; values.put(People.KEY_NAME, nameText.getText.toString); values.put(People.KEY_AGE, Integer.parseInt(ageText.getText.toString)); values.put(People.KEY_HEIGHT, Float.parseFloat(heightText.getText.toString)); Uri newUri = resolver.insert(People.CONTENT_URI, values); labelView.setText("添加成功,URI:" + newUri); } }); queryAllButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub Cursor cursor = resolver.query(People.CONTENT_URI, new String[] { People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT }, null, null, null); if (cursor == null) { labelView.setText("数据库中没有数据"); return; } labelView.setText("数据库:" + String.valueOf(cursor.getCount) + "条记录"); String msg = ""; if (cursor.moveToFirst) { do { msg += "ID:" + cursor.getInt(cursor .getColumnIndex(People.KEY_ID)) + ","; msg += "姓名:" + cursor.getString(cursor .getColumnIndex(People.KEY_NAME)) + ","; msg += "年龄:" + cursor.getInt(cursor .getColumnIndex(People.KEY_AGE)) + ", "; msg += "身高:" + cursor.getFloat(cursor .getColumnIndex(People.KEY_HEIGHT)) + "\n"; } while (cursor.moveToNext); } displayView.setText(msg); } }); clearButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub displayView.setText(""); } }); queryButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEntry.getText.toString); Cursor cursor = resolver.query(uri, new String[] { People.KEY_ID, People.KEY_NAME, People.KEY_AGE, People.KEY_HEIGHT }, null, null, null); if (cursor == null) { labelView.setText("数据库中没有数据"); return; } String msg = ""; if (cursor.moveToFirst) { msg += "ID:" + cursor.getInt(cursor .getColumnIndex(People.KEY_ID)) + ","; msg += "姓名:" + cursor.getString(cursor .getColumnIndex(People.KEY_NAME)) + ","; msg += "年龄:" + cursor.getInt(cursor .getColumnIndex(People.KEY_AGE)) + ", "; msg += "身高:" + cursor.getFloat(cursor .getColumnIndex(People.KEY_HEIGHT)) + "\n"; } labelView.setText("数据库:"); displayView.setText(msg); } }); deleteButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEntry.getText.toString); int result = resolver.delete(uri, null, null); String msg = "删除ID为" + idEntry.getText.toString + "的数据" + (result > 0 ? "成功" : "失败"); labelView.setText(msg); } }); updateButton.setOnClickListener(new OnClickListener { @Override public void onClick(View v) { // TODO Auto-generated method stub ContentValues values = new ContentValues; values.put(People.KEY_NAME, nameText.getText.toString); values.put(People.KEY_AGE, Integer.parseInt(ageText.getText.toString)); values.put(People.KEY_HEIGHT, Float.parseFloat(heightText.getText.toString)); Uri uri = Uri.parse(People.CONTENT_URI_STRING + "/" + idEntry.getText.toString); int result = resolver.update(uri, values, null, null); String msg = "更新ID为" + idEntry.getText.toString + "的数据" + (result > 0 ? "成功" : "失败"); labelView.setText(msg); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater.inflate(R.menu.content_resolver_demo, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId; if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}
事成相识的结构文件也附上:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="edu.hrbeu.contentresolverdemo.ContentResolverDemo" > <TextView android:id="@+id/Username" android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="用户名:"> </TextView> <EditText android:id="@+id/name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_below="@id/Username" > </EditText> <TextView android:id="@+id/Userage" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/name" android:text="年龄:"> </TextView> <EditText android:id="@+id/age" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/Userage"> </EditText> <TextView android:id="@+id/Userhight" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/age" android:text="身高:"> </TextView> <EditText android:id="@+id/hight" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/Userhight"> </EditText> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button1" android:layout_alignBottom="@+id/button1" android:layout_centerHorizontal="true" android:text="全部显示" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button2" android:layout_alignBottom="@+id/button2" android:layout_alignRight="@+id/hight" android:text="清除显示" /> <TextView android:id="@+id/Userid" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/button1" android:text="ID:"> </TextView> <EditText android:id="@+id/id" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_below="@id/Userid"> </EditText> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button5" android:layout_alignBottom="@+id/button5" android:layout_alignLeft="@+id/button2" android:text="ID查询" /> <Button android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/button6" android:layout_alignBottom="@+id/button6" android:layout_alignLeft="@+id/button3" android:text="ID更新" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/hight" android:text="添加数据" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/id" android:layout_below="@+id/id" android:text="ID删除" /> <TextView android:id="@+id/display" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/label" android:layout_below="@+id/label" android:layout_marginTop="23dp" /> <TextView android:id="@+id/label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/button5" android:layout_below="@+id/button6" android:layout_marginTop="14dp" /></RelativeLayout>
运行成果:
欢迎参与《SQLite数据库与Contentprovider(2)》讨论,分享您的想法,维易PHP学院为您提供专业教程。