Android下ContentProvider的实例

来源:互联网 发布:中央空调控制系统软件 编辑:程序博客网 时间:2024/06/05 07:17

     一.前些日期研究了下Android下ContentProvider的使用,先将具体的使用方法记下来,方便以后的实际使用扩展。

1.新建工程TestContentProvider此工程是独立的ContentProvider类类似如系统内置的ContactProvider,新建包名com.test.content。

2.文件DataBaseOpen.java,代码如下,主要用于建立数据库,表,及进行数据库的操作等。

package com.test.content;

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

public class DataBaseOpen extends SQLiteOpenHelper {

 private final static String DB_NAME = "test.db";
 public static final int DB_VERSION = 1;
 
 public DataBaseOpen(Context context, String name, CursorFactory factory,
   int version) {
  super(context, name, factory, version);
  // TODO Auto-generated constructor stub
 }
 public DataBaseOpen(Context context) {
  super(context, DB_NAME, null, DB_VERSION);
  // TODO Auto-generated constructor stub
 }
 @Override
 public void onCreate(SQLiteDatabase arg0) {
  // TODO Auto-generated method stub
  String sql = "CREATE TABLE IF NOT EXISTS student (id integer PRIMARY KEY autoincrement,stuId text NOT NULL unique,name text NOT NULL)";
  arg0.execSQL(sql);
  sql = "CREATE TABLE IF NOT EXISTS score (id integer PRIMARY KEY autoincrement,stuId text NOT NULL unique,name text NOT NULL)";
  
  arg0.execSQL(sql);
 }

 @Override
 public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
  // TODO Auto-generated method stub
  onCreate(arg0);
 }

}

2.TestProvider.java继承ContentProvider定义外部访问的规则,具体如下

package com.test.content;

import org.apache.http.client.utils.URIUtils;

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 TestProvider extends ContentProvider {
 //数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头 
 public static final String STUDENTS_TYPE = "vnd.android.cursor.dir/student"; 
 //单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头 
 public static final String STUDENTS_ITEM_TYPE = "vnd.android.cursor.item/student";  
 
 public static final String SCORES_TYPE = "vnd.android.cursor.dir/score"; 
 //单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头 
 public static final String SCORES_ITEM_TYPE = "vnd.android.cursor.item/score";  
 
 public static final String AUTHORITY = "com.android.provider.studentprovider"; 
 /*自定义匹配码*/ 
 public static final int STUDENTS = 1;  
 /*自定义匹配码*/ 
 public static final int STUDENT = 2;  
 
 public static final int SCORES = 3;  
 /*自定义匹配码*/ 
 public static final int SCORE = 4;
 public static final Uri STUDENTS_URI = Uri.parse("content://" + AUTHORITY + "/student");  
 public static final Uri SCORES_URI = Uri.parse("content://" + AUTHORITY + "/score"); 
 /*这里UriMatcher是用来匹配Uri的类,使用match()方法匹配路径时返回匹配码*/ 
 private static final UriMatcher sMatcher; 
 protected SQLiteDatabase mDb;
 static { 
  sMatcher = new UriMatcher(UriMatcher.NO_MATCH);//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码 
  //如果match()方法匹配content://cn.android.provider.personprovider/person路径,返回匹配码为PERSONS 
  sMatcher.addURI(AUTHORITY, "student", STUDENTS); 
  //如果match()方法匹配content://cn.android.provider.personprovider/person/230路径,返回匹配码为PERSON 
  sMatcher.addURI(AUTHORITY, "student/#", STUDENT); 
  sMatcher.addURI(AUTHORITY, "score", SCORES); 
  sMatcher.addURI(AUTHORITY, "score/#", SCORE); 
 }  
 private DataBaseOpen databaseHelper;
 @Override
 public int delete(Uri arg0, String arg1, String[] arg2) {
  // TODO Auto-generated method stub
  return 0;
 }

 @Override
 public String getType(Uri uri) {
  // TODO Auto-generated method stub
  switch (sMatcher.match(uri))
  {  
   case STUDENTS: 
   return STUDENTS_TYPE; 
   case STUDENT: 
    
   return STUDENTS_ITEM_TYPE; 
   case SCORES: 
    return SCORES_TYPE; 
   case SCORE: 
    return SCORES_ITEM_TYPE; 
   default:  
    return null; 
  }
 }

 @Override
 public Uri insert(Uri uri, ContentValues values) {
  // TODO Auto-generated method stub
  switch (sMatcher.match(uri))
  {  
   case STUDENTS: 
    mDb = databaseHelper.getWritableDatabase();
    long rowId  = 0;
    try
    {
     rowId = mDb.insertOrThrow("student", "stuId", values);
    }
    catch(Exception e)
    {
     e.printStackTrace();
    }
      return ContentUris.withAppendedId(STUDENTS_URI, rowId);
   case STUDENT: 
     
      return null; 
   case SCORES: 
    mDb = databaseHelper.getWritableDatabase();
    long Id  = 0;
    try
    {
     Id = mDb.insertOrThrow("score", "stuId", values);
    }
    catch(Exception e)
    {
     e.printStackTrace();
    }
      return ContentUris.withAppendedId(SCORES_URI, Id); 
    
   case SCORE: 
    return null; 
   default:  
    return null; 
  }
 }

 @Override
 public boolean onCreate() {
  // TODO Auto-generated method stub
  databaseHelper = new DataBaseOpen(this.getContext()); 
  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;
 }

}

 3.AndroidManifest.xml 配置自定义的ContentProvider如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.content"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <provider android:name=".TestProvider" android:authorities="com.android.provider.studentprovider"/> 
       
    </application>

</manifest>

 二.编写测试范文自定义的ContentProvider

 1.新建工程TestProviderClient。包名com.test.client

其中一个测试入口的Activiy TestProviderClientActivity.java代码如下

package com.test.client;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class TestProviderClientActivity extends Activity {
    /** Called when the activity is first created. */
 private Button mStu;
 private Button mSco;
 private EditText  mMsg;
 private EditText mNum;
 TextView mRet;
 private Context mConText;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMsg = (EditText)this.findViewById(R.id.msgId);
        mNum = (EditText)this.findViewById(R.id.num);
        mStu = (Button)this.findViewById(R.id.btnStu);
        mSco = (Button)this.findViewById(R.id.btnSco);
        mRet = (TextView)this.findViewById(R.id.ret);
        mConText = this.getBaseContext();
        View.OnClickListener l = new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    int id = v.getId();
    String msg = mMsg.getText().toString();
    String num = mNum.getText().toString();
    if(null == msg || null == num)return;
    ContentValues value = new ContentValues();
    ContentResolver cr = mConText.getContentResolver();
    value.clear();
    value.put("stuId", msg);
    value.put("name", num);
    Uri uri = null;
   
    try {
     if(id == R.id.btnStu)
     {
      
      uri = cr.insert(Uri.parse("content://com.android.provider.studentprovider/student"), value);
      
     }
     else if(id == R.id.btnSco)
     {
      uri = cr.insert(Uri.parse("content://com.android.provider.studentprovider/score"), value);
     }
     mRet.setText(uri.toString());
    } catch (Exception e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
    
   }
  };
  mStu.setOnClickListener(l);
  mSco.setOnClickListener(l);
    }
   
}

2.布局文件如下main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/msgId"
        android:singleLine="true"/>
    <EditText android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/num"
        android:inputType="number"
        android:singleLine="true"/>
    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >
    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:id = "@+id/btnStu"
        android:text="插入到学生表"
        android:layout_weight="1"/>
    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:id = "@+id/btnSco"
        android:text="插入到成绩表"
        android:layout_weight="1"/>
    </LinearLayout>
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/ret"/>
</LinearLayout>

3.工程的AndroidManifest.xml文件如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.client"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="8" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TestProviderClientActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

三1.总结一下,本实例不够完整,只是测试了下调用ContenProvider的插入数据的操作,且系统没有该自定义ContentProvider会报错(可以检查系统是否已经有了自定义的ContentProvider的安装包如存在则进行后续的操作,无可以提示安装)。

2.ContenProvider可以随运用一起发布,方便其他运用访问数据,对数据库的操作可以采用事务处理。