sharedpreferences和文件雖然都能實現數據共享,但是卻無法實現數據庫的共享,所以android提供了contentProvider的方法來實現數據庫的共享,下面就來介紹contentprovider
1.contentprovider的目的是爲了實現數據的共享,爲了使用contentprovider就需要先重寫其中的4種方法oncreate,insert,delete,query, oncreate爲創建時調用的方法,insert爲插入數據時的方法,delete未刪除數據時的方法,query爲查詢時使用的方法。這幾個方法是必須實現的,原始方法如下:
public boolean onCreate():
//insert第一個參數爲uri,第二個參數爲要插入的值
public Uri insert(Uri uri, ContentValues values)
//delete第一個參數爲uri,第二個參數爲sql語句的選擇條件,第三個參數爲當selection參數中有佔位符時,取值從第三個參數中獲取
public int delete(Uri uri, String selection, String[] selectionArgs)
//數據更新,參數與delete是一致的
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
//查詢函數第一個參數是uri,第二個參數爲返回的項目即select 與from之前的這一部分,三,四參數和上面一致,第五個參數是排序方式
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
//返回數據的mime類型
public String getType(Uri uri)
2.contentprovider使用的關鍵Universal Resource Identifier,簡寫爲URI,方便的理解方式爲web開發中的url類似的概念,就是提供數據的訪問“鏈接”,分三部分組成,”content://”,數據路徑,ID標誌符,android提供了兩個用以操作uri的類UriMatcher 和ContentUris 。
一,UriMatcher
UriMatcher的主要作用是用來初始化Uri
初始化方法如下,第一步:
UriMatcher sMatcher=new UriMatcher(UriMatcher.NO_MATCH);;
第二步,註冊所需的URI,第一個參數爲authorities,第二個參數爲路徑,第三個參數爲匹配碼,是之後用來進行uri匹配時用到的值
sMatcher.addURI("com.example.ui_demo","mytable", 1);
sMatcher.addURI("com.example.ui_demo","mytable"+"/#", 2);
第三步,URI匹配
Uri uri = Uri.parse("content://com.example.ui_demo/mytable/10");
switch (sMatcher.match(uri)) {
case 1:
//匹配碼爲1時的操作
case 2:
//匹配碼爲2時的操作
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
二,ContentUris是用來從給定的uri中獲取ID,或是添加ID用
1.爲路徑加上ID
Uri uri = Uri.parse("content://com.example.ui_demo/mytable");
Uri noteUri=ContentUris.withAppendedId(ur, 10);
則此時的URI爲”content://com.example.ui_demo/mytable/10”
2.獲取路徑ID
Uri uri = Uri.parse("content://com.example.ui_demo/mytable/10");
long id=ContentUris.parseId(uri);
此時獲取的ID值爲10
三,實際使用時並不是直接使用contentProvider來操作數據,而是通過contentResolver來供外部應用操作contentProvider中的數據,實際的調用ContentProvider是在contentResolver的使用中進行的,而ContentProvider和ContenResolver是怎麼關聯起來的,可以參考下面的博客,博主寫的很全面
http://blog.csdn.net/yangxinle137/article/details/5985608
四,完整的運用過程如下
1.創建一個數據庫供contentprovider使用,這個在上一篇中有詳細介紹,這裏就不多說了
2.註冊contentprovider
提供provider的程序,注意provider的註冊需要卸載application內,而權限的註冊需要放在之外
<permission android:name="com.example.ui_demo.dataprovider.READ_DATABASE" />
<permission android:name="com.example.ui_demo.dataprovider.WRITE_DATABASE" />
<provider android:name=".dataprovider"
android:authorities="com.example.ui_demo"
android:exported="true"
android:readPermission="com.example.ui_demo.dataprovider.READ_DATABASE"
android:writePermission="com.example.ui_demo.dataprovider.WRITE_DATABASE"></provider>
要使用provider的應用程序定義在application之外
<uses-permission android:name="com.example.ui_demo.dataprovider.READ_DATABASE"/>
<uses-permission android:name="com.example.ui_demo.dataprovider.WRITE_DATABASE"/>
3.註冊完畢後,就是重寫contentprovider的方法了,重寫過程如下
public class dataprovider extends ContentProvider {
//刪除considerprovider數據
private final static String tag="ContentProvider";
private datasave database;
private SQLiteDatabase mydata=null;
private static final UriMatcher sMatcher;
static{
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI("com.example.ui_demo","mytable", 1);
sMatcher.addURI("com.example.ui_demo","mytable"+"/#", 2);
}
//構造函數,獲得上下文
@Override
public int delete(Uri uri, String arg1, String[] arg2) {
// TODO Auto-generated method stub
Log.i(tag,"start delete provider data");
mydata= database.getDataBase();
int count = 0;
switch (sMatcher.match(uri)) {
case 1:
count = mydata.delete("mytable",arg1, arg2);
break;
case 2:
long id=ContentUris.parseId(uri);
String where="ID="+id;
count= mydata.delete(table.TNAME,where,arg2);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
//獲取considerprovider數據類型
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
Log.i(tag,"start get provider type");
switch (sMatcher.match(uri)) {
case 1:
return table.CONTENT_TYPE;
case 2:
return table.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
}
//插入considerprovider數據
@Override
public Uri insert(Uri uri, ContentValues value) {
// TODO Auto-generated method stub
Log.i(tag,"start insert provider data");
mydata=database.getDataBase();
switch (sMatcher.match(uri)) {
case 1:
Log.i(tag,"start insert data");
try{
mydata.insert(table.TNAME, null, value);//返回第幾行
}catch(Exception e){
Log.i(tag,e.getMessage());
}
long id=(Integer) value.get("ID");
Uri ur=Uri.parse("content://com.example.ui_demo/mydata");
//添加id
Uri noteUri=ContentUris.withAppendedId(ur, id);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
Log.i(tag,"start create provider");
//打開數據庫,參數上下文,數據庫名,工廠類,數據庫版本
database=new datasave(this.getContext());
database.create("mytable");
return false;
}
//獲取considerprovider數據
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// TODO Auto-generated method stub
Log.i(tag,"start query provider data");
mydata=database.getDataBase();
Cursor cur=null;
switch (sMatcher.match(uri)) {
case 1:
Log.i(tag,"start query mytable provider data");
cur=mydata.query(table.TNAME,projection,selection,selectionArgs,null,null,null);
break;
case 2:
long id = ContentUris.parseId(uri);
Log.i(tag,"start query mytable id provider data"+id);
String sql="select * from mytable where ID ="+id;
//String where = "ID=" + id;
// cur=mydata.query(table.TNAME,projection,where,selectionArgs,null,null,null);
cur=mydata.rawQuery(sql, new String[]{});
break;
default:
throw new IllegalArgumentException("Unknown URI1"+uri);
}
return cur;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
Log.i(tag,"start update provider data");
return 0;
}
}
4.通過contentResolver來操作數據
contentResolver=ShareDemo.this.getContentResolver();//獲取對象
Cursor cur=null;
try{
cur=contentResolver.query(uri, null, null, null, null);
}catch(Exception e){
Log.i("ContentProvider",e.getMessage());
}
while(cur.moveToNext()){
//Toast.makeText(this,cur.getString(1)+"ok1", Toast.LENGTH_LONG).show();
list.add(cur.getString(0));
list.add(cur.getString(1));
//Toast.makeText(this,cur.getString(0)+"ok", Toast.LENGTH_LONG).show();
}
listshow showlist=new listshow(ShareDemo.this,list);
showlist.show();
示例代碼
dataprovider.java
package com.example.ui_demo;
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.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
public class dataprovider extends ContentProvider {
//刪除considerprovider數據
private final static String tag="ContentProvider";
private Context context;
private datasave database;
private SQLiteDatabase mydata=null;
private static final UriMatcher sMatcher;
static{
sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sMatcher.addURI("com.example.ui_demo","mytable", 1);
sMatcher.addURI("com.example.ui_demo","mytable"+"/#", 2);
}
//構造函數,獲得上下文
@Override
public int delete(Uri uri, String arg1, String[] arg2) {
// TODO Auto-generated method stub
Log.i(tag,"start delete provider data");
mydata= database.getDataBase();
int count = 0;
switch (sMatcher.match(uri)) {
case 1:
count = mydata.delete("mytable",arg1, arg2);
break;
case 2:
long id=ContentUris.parseId(uri);
String where="ID="+id;
count= mydata.delete(table.TNAME,where,arg2);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
//獲取considerprovider數據類型
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
Log.i(tag,"start get provider type");
switch (sMatcher.match(uri)) {
case 1:
return table.CONTENT_TYPE;
case 2:
return table.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
}
//插入considerprovider數據
@Override
public Uri insert(Uri uri, ContentValues value) {
// TODO Auto-generated method stub
Log.i(tag,"start insert provider data");
mydata=database.getDataBase();
switch (sMatcher.match(uri)) {
case 1:
Log.i(tag,"start insert data");
try{
mydata.insert(table.TNAME, null, value);//返回第幾行
}catch(Exception e){
Log.i(tag,e.getMessage());
}
long id=(Integer) value.get("ID");
Uri ur=Uri.parse("content://com.example.ui_demo/mydata");
//添加id
Uri noteUri=ContentUris.withAppendedId(ur, id);
this.getContext().getContentResolver().notifyChange(noteUri, null);
return noteUri;
default:
throw new IllegalArgumentException("Unknown URI"+uri);
}
}
@Override
public boolean onCreate() {
// TODO Auto-generated method stub
Log.i(tag,"start create provider");
//打開數據庫,參數上下文,數據庫名,工廠類,數據庫版本
database=new datasave(this.getContext());
database.create("mytable");
return false;
}
//獲取considerprovider數據
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
// TODO Auto-generated method stub
Log.i(tag,"start query provider data");
mydata=database.getDataBase();
Cursor cur=null;
switch (sMatcher.match(uri)) {
case 1:
Log.i(tag,"start query mytable provider data");
cur=mydata.query(table.TNAME,projection,selection,selectionArgs,null,null,null);
break;
case 2:
long id = ContentUris.parseId(uri);
Log.i(tag,"start query mytable id provider data"+id);
String sql="select * from mytable where ID ="+id;
//String where = "ID=" + id;
// cur=mydata.query(table.TNAME,projection,where,selectionArgs,null,null,null);
cur=mydata.rawQuery(sql, new String[]{});
break;
default:
throw new IllegalArgumentException("Unknown URI1"+uri);
}
return cur;
}
@Override
public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
// TODO Auto-generated method stub
Log.i(tag,"start update provider data");
return 0;
}
//數據庫類
public static class datasave{
private SQLiteDatabase dbase=null;
public datasave(Context context){
//打開數據庫
Log.i(tag,"open or create database");
try{
dbase=context.openOrCreateDatabase("mydata.db",Context.MODE_PRIVATE, null);
}catch(Exception e){
Log.i(tag,e.getMessage());
}
}
//創建表
public void create(String TableName){
Log.i(tag,"create table if not exists");
try{
String create="CREATE TABLE"+" IF NOT EXISTS "+TableName+" (ID INTEGER,NAME TEXT)";
dbase.execSQL(create);
}catch(Exception e){
Log.i(tag,e.getMessage());
}
}
public void insert(String TableName,String []selections){
Log.i(tag,"insert table data");
try{
String insert="insert into "+TableName+" values(selections[0],selections[1]);";
dbase.execSQL(insert);
}catch(Exception e){
Log.i(tag,e.getMessage());
}
}
public void delete(String TableName){
Log.i(tag,"delete table data");
try{
String delete="DROP TABLE"+TableName;
dbase.execSQL(delete);
}catch(Exception e){
Log.i(tag,e.getMessage());
}
}
public SQLiteDatabase getDataBase(){
return this.dbase;
}
}
public static class table {
public static final String DBNAME = "mydata.db";
public static final String TNAME = "mytable";
public static final int VERSION = 3;
public static final String TID = "tid";
public static final String ID = "ID";
public static final String NAME = "NAME";
public static final String AUTOHORITY = "com.example_ui.demo";
public static final int ITEM = 1;
public static final int ITEM_ID = 2;
//匹配類型,如爲MME類型返回CONTENT_TYPE,反之返回ITEM_TYPE
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/mytable";
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/mytable";
public static final Uri uri = Uri.parse("content://" + AUTOHORITY + "/mytable");
}
}
readotherdatabase.java
package com.example.readotherdatabase;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TableLayout table=null;
private ContentResolver contentResolver;
private List<String> list=new ArrayList<String>();
private SQLiteDatabase mydata;
private ListView listshow;
private String []mysql={"讀取","讀取(ID)","刪除","插入"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
table=(TableLayout)this.findViewById(R.id.item);
contentResolver=MainActivity.this.getContentResolver();
listshow=(ListView)this.findViewById(R.id.listshowc);
//Uri uri = Uri.parse("content://com.example.ui_demo/mytable");
myadapter m=new myadapter(this);
listshow.setAdapter(m);
}
public void updataview(Uri uri){
Cursor cur=null;
try{
cur=contentResolver.query(uri, null, null, null, null);
}catch(Exception e){
Log.i("ContentProvider",e.getMessage());
}
while(cur.moveToNext()){
//Toast.makeText(this,cur.getString(1)+"ok1", Toast.LENGTH_LONG).show();
list.add(cur.getString(0));
list.add(cur.getString(1));
//Toast.makeText(this,cur.getString(0)+"ok", Toast.LENGTH_LONG).show();
}
listshow showlist=new listshow(MainActivity.this,list);
showlist.show();
}
public class myadapter extends BaseAdapter{
private Context context;
public myadapter(Context context){
this.context=context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return mysql.length;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View vi, ViewGroup vg) {
// TODO Auto-generated method stub
Button button=new Button(MainActivity.this);
button.setText(mysql[position]);
button.setId(position);
buttonclick m=new buttonclick();
button.setOnClickListener(m);
return button;
}
}
@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;
}
@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);
}
public class buttonclick implements OnClickListener{
private int i=0;
@Override
public void onClick(View vi) {
// TODO Auto-generated method stub
if(vi.getId()==0){
//查詢表
Uri uri = Uri.parse("content://com.example.ui_demo/mytable");
updataview(uri);
}else if(vi.getId()==1){
//讀取帶ID
Uri uri = Uri.parse("content://com.example.ui_demo/mytable/10");
updataview(uri);
}else if(vi.getId()==2){
Uri uri=Uri.parse("content://com.example.ui_demo/mytable/11");
contentResolver.delete(uri, null, null);
uri = Uri.parse("content://com.example.ui_demo/mytable");
updataview(uri);
}else if(vi.getId()==3){
Uri uri=Uri.parse("content://com.example.ui_demo/mytable");
ContentValues value=new ContentValues();
value.put("ID",11);
value.put("NAME","lianggong zhazha");
contentResolver.insert(uri, value);
updataview(uri);
}
}
}
public class listshow{
private List<String> list;
private Context context;
public listshow(Context context,List<String> list){
this.context=context;
this.list=list;
}
public void show(){
table.removeAllViews();
for(int i=0;i<list.size();i=i+2){
try{
TableRow row=new TableRow(context);
TextView text=new TextView(context);
text.setText(list.get(i).toString());
text.setId(i);
TextView text1=new TextView(context);
text1.setText(list.get(i+1).toString());
text1.setId(i+1);
row.addView(text);
row.addView(text1);
table.addView(row);
}catch(Exception e){
Toast.makeText(MainActivity.this,e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
}