ContentProvider示例

http://hi.baidu.com/pekdou/item/b2a070c37552af210831c678java

 

首先,我本身是各初學者,網上一些關於ContentProvider的例子也很多,我本身試了不少,但老是有問題,終於今天哥本身寫了個出來,本身摸索着寫真是太累了。android

首先說個查詢一條記錄的toy demo:web

ContentProviderExample(Project name)sql

     |_src數據庫

     |     |_com.motorola.snow.toy數組

     |          |_ContentProviderExample.javaapp

     |          |_DataProvider.javaeclipse

     |_reside

     |      |_layoutspa

     |      |      |_main.xml

     |      |_values

     |      |_drawable

     |

     |_AndroidManifest.xml

(這是工程的目錄,要寫這麼詳細是由於:我看的幾個文檔都是在講怎樣怎樣,沒有一個圖示。有時候我都不能分辨)

下面一一介紹每一個文件須要寫寫什麼東西:

ContentProviderExample.java

package com.motorola.snow.toy;
import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
public class ContentProviderExample extends Activity {
 // public static final String AUTHORITY = "com.motorola.snow";
 public static final Uri CONTENT_URI = Uri
   .parse("content://com.motorola.snow/students");
 private static final String[] PROJECTION = new String[] { "stu_no",
   "stu_name" };
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  TextView tv = (TextView) findViewById(R.id.showOne);
  Cursor c = getContentResolver().query(CONTENT_URI, PROJECTION,
    "stu_no = ?", new String[] { "S1001" }, null);
  c.moveToFirst();
  tv.setText(c.getString(1));
 }
}

DataProvider.java

package com.motorola.snow.toy;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.util.Log;
public class DataProvider extends ContentProvider {
 private static final String DATABASE_NAME = "stu_database";
 private static final int VERSION = 1;
 private static final String TABLE_NAME = "students";
 private DataBaseHelper helper;
 private class DataBaseHelper extends SQLiteOpenHelper {
  public DataBaseHelper(Context context) {
   super(context, DATABASE_NAME, null, VERSION);
  }
  @Override
  public void onCreate(SQLiteDatabase db) {
   // TODO Auto-generated method stub
   db.execSQL("CREATE TABLE students (stu_no TEXT, stu_name TEXT)");
   String sql1 = "insert into students (stu_no, stu_name) values ('S1001', 'Tom')";
   String sql2 = "insert into students (stu_no, stu_name) values ('S1002', 'John')";
   String sql3 = "insert into students (stu_no, stu_name) values ('S1003', 'Jack')";
   try {
    db.execSQL(sql1);
    db.execSQL(sql2);
    db.execSQL(sql3);
   } catch (Exception e) {
    e.printStackTrace();
    Log.println(0, "insert error",
      "Some error occur when create table");
   }
  }
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
   // TODO Auto-generated method stub
  }
 }
 @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
  return null;
 }
 @Override
 public Uri insert(Uri uri, ContentValues values) {
  // TODO Auto-generated method stub
  return null;
 }
 @Override
 public boolean onCreate() {
  helper = new DataBaseHelper(getContext());
  return true;
 }
 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
  SQLiteDatabase db = helper.getReadableDatabase();
  Cursor c = db.query("students", projection, selection, selectionArgs, null, null,
    null);
  return c;
 }
 @Override
 public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
  // TODO Auto-generated method stub
  return 0;
 }
}
 

main.xml

view plaincopy to clipboardprint?
01.<?xml version="1.0" encoding="utf-8"?>   
02.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android 
03.    android:orientation="vertical"  
04.    android:layout_width="fill_parent"  
05.    android:layout_height="fill_parent"  
06.    >   
07.<TextView     
08.    android:layout_width="fill_parent"    
09.    android:layout_height="wrap_content"    
10.    android:text="@string/hello"  
11.    />   
12.       
13.<TextView    
14.    android:id="@+id/showOne"  
15.    android:layout_width="fill_parent"    
16.    android:layout_height="wrap_content"       
17.    />   
18.</LinearLayout>  
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
    
<TextView 
 android:id="@+id/showOne"
 android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
 />
</LinearLayout>
 

AndroidManifest.xml

view plaincopy to clipboardprint?
01.<?xml version="1.0" encoding="utf-8"?>   
02.<manifest xmlns:android="http://schemas.android.com/apk/res/android 
03.      package="com.motorola.snow.toy"  
04.      android:versionCode="1"  
05.      android:versionName="1.0">   
06.    <application android:icon="@drawable/icon" android:label="@string/app_name">   
07.        <activity android:name=".ContentProviderExample"  
08.                  android:label="@string/app_name">   
09.            <intent-filter>   
10.                <action android:name="android.intent.action.MAIN" />   
11.                <category android:name="android.intent.category.LAUNCHER" />   
12.            </intent-filter>   
13.        </activity>   
14.    <provider android:name="DataProvider"  
15.              android:authorities="com.motorola.snow" >   
16.    </provider>   
17.    </application>   
18.    <uses-sdk android:minSdkVersion="3" />   
19.</manifest>   
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.motorola.snow.toy"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".ContentProviderExample"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 <provider android:name="DataProvider"
     android:authorities="com.motorola.snow" >
 </provider>
    </application>
    <uses-sdk android:minSdkVersion="3" />
</manifest> 

其中有幾個是一直困擾個人問題,在這個工程中終於獲得解決。仍是比較高興的:

1.

在AndroidManifest.xml文件中註冊了

    <provider android:name="DataProvider"
              android:authorities="com.motorola.snow" >
    </provider>

  這句話告訴工程,我在這個工程下定義了一個ContentProvider,名字叫DataProvider(這個類你們看到,其實就是ContentProvider的一個自定義的子類) authorities 定義的字符串實際上在ContentProviderExample.java中定義Uri時作的惟一標示符而已,通常我喜歡跟包同名,不過須要注意的是,這個字符串必須所有爲小寫!!

2.

DataProvider.java其實是我本身定義的ContentProvider的一個子類,須要重寫其繼承下來的方法:我只是實現了一個查詢功能,但實現了其中的一個功能,其餘CRUD的操做應該不難。在這個類裏定義了一個內部類:DatabaseHelper extends SQLiteOpenHelper (一開始看的哪一個文檔也是這樣寫,但是在eclipse中老是報錯,後來才知道必需要重寫它的構造方法,這個構造方法的主要做用就是新建數據庫,我的理解)實際上在下面DataProvider onCreate 方法中定義了一個DataBaseHelper的實例,在定義的時候他會自行調用DataBaseHelper的 onCreate 方法,建立數據庫,所以我爲了簡單起見,建表並插入了幾行數據。這主要要明白這子類中方法的調用順序,一開始我也很難理解。

3.

說說ContentProviderExample這個類吧:首先定義了

public static final Uri CONTENT_URI = Uri
            .parse("content://com.motorola.snow/students");

其實這是某種固定的寫法:這個字符串必須以 content://開始,中間那段要和在AndroidManifest.xml文件中註冊的一致,後面通常用的是數據庫表名,其實這後面還有一截的是數字,我暫時還不太清楚這最後一段數字的用法,這個具體能夠看一下developer.android文檔;

下面定義了一個數組:

private static final String[] PROJECTION = new String[] { "stu_no",
            "stu_name" };

這個數組定義的是:在查詢中須要查詢哪幾列,這裏我查詢的是stu_no和stu_name 2列。

重點說一說下面這段:

Cursor c = getContentResolver().query(CONTENT_URI, PROJECTION,
                "stu_no = ?", new String[] { "S1001" }, null);
        c.moveToFirst();
        tv.setText(c.getString(1));

首先getContentResolver()這個方法返回的是一個ContentProvider的實例,這個方法在全部 Activity中均可以被調用,.query()方法實際上查詢的是在DataProvider中重寫的query()方法,裏面的幾個參數分別是Uri,要查詢的列,查詢條件(where),用來填充查詢語句中?號的值,最後是orderBy沒有,因此爲null,這些參數被傳到DataProvider.query()方法中執行。Android會本身拼出一個查詢字符串。須要注意的是「stu_no=?」查詢條件前面是不須要加where的,android會自行添加。

NOTE:

須要理解的是爲何要定義Uri,我我的的理解:一個比較大的Android工程,可能會用到幾個ContentProvider來存儲數據,所以在AndroidManifest.xml中註冊是須要有個惟一的標識符,不一樣的URi對應不一樣的ContentProvider,將Uri做爲參數傳到query()方法裏,就指明瞭我如今要操做的數據庫到底是哪一個

 

本文來自CSDN博客http://blog.csdn.net/tang_jiajia/archive/2010/03/24/5412164.aspx

相關文章
相關標籤/搜索