天天看點

系出名門Android(9) - 資料庫支援(SQLite), 内容提供器(ContentProvider)

<a href="http://webabcd.blog.51cto.com/1787395/341976" target="_blank">[索引頁]</a>

<a href="http://down.51cto.com/data/100088" target="_blank">[源碼下載下傳]</a>

系出名門Android(9) - 資料庫支援(SQLite), 内容提供器(ContentProvider)

介紹

在 Android 中使用 SQLite, ContentProvider 

資料庫支援(SQLite) - Android 開發平台提供了操作 SQLite 資料庫的相關 API 

内容提供器(ContentProvider) - 當資料需要在應用程式之間共享時,可以在某程式中使用 ContentProvider 定義 URI, 以使其它應用程式可以通過此 URI 通路指定的資料

1、SQLite 的 Demo

DatabaseHelper.java

package com.webabcd.SQLite; 

import android.content.Context; 

import android.database.sqlite.SQLiteDatabase; 

import android.database.sqlite.SQLiteOpenHelper; 

import android.database.sqlite.SQLiteDatabase.CursorFactory; 

// 資料庫操作的 Helper 類 

public class DatabaseHelper extends SQLiteOpenHelper { 

        DatabaseHelper(Context context, String name, CursorFactory cursorFactory, int version) { 

                super(context, name, cursorFactory, version); 

        } 

        @Override 

        public void onCreate(SQLiteDatabase db) { 

                // TODO 建立資料庫後,對資料庫的操作 

        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

                // TODO 更改資料庫版本的操作 

        public void onOpen(SQLiteDatabase db) { 

                super.onOpen(db); 

                // TODO 每次成功打開資料庫後首先被執行 

}

Main.java

import java.util.Random; 

import android.app.Activity; 

import android.content.ContentValues; 

import android.database.Cursor; 

import android.database.SQLException; 

import android.os.Bundle; 

import android.view.View; 

import android.widget.Button; 

import android.widget.TextView; 

public class Main extends Activity { 

        private DatabaseHelper dbHelper; 

        private static final String DATABASE_NAME = "db.db"; 

        private static final int DATABASE_VERSION = 1; 

        private static final String TABLE_NAME = "employee"; 

        TextView txtMsg; 

        /** Called when the activity is first created. */ 

        public void onCreate(Bundle savedInstanceState) { 

                super.onCreate(savedInstanceState); 

                setContentView(R.layout.main); 

                dbHelper = new DatabaseHelper(this, DATABASE_NAME, null, 

                                DATABASE_VERSION); 

                txtMsg = (TextView) this.findViewById(R.id.txtMsg); 

                Button btn1 = (Button) this.findViewById(R.id.btn1); 

                btn1.setText("建立表"); 

                btn1.setOnClickListener(new Button.OnClickListener() { 

                        public void onClick(View v) { 

                                CreateTable(); 

                        } 

                }); 

                Button btn2 = (Button) this.findViewById(R.id.btn2); 

                btn2.setText("插入 3 條記錄"); 

                btn2.setOnClickListener(new Button.OnClickListener() { 

                                insertItem(); 

                Button btn3 = (Button) this.findViewById(R.id.btn3); 

                btn3.setText("删除全部記錄"); 

                btn3.setOnClickListener(new Button.OnClickListener() { 

                                deleteItem(); 

                Button btn4 = (Button) this.findViewById(R.id.btn4); 

                btn4.setText("更新指定資料"); 

                btn4.setOnClickListener(new Button.OnClickListener() { 

                                updateItem(); 

                Button btn5 = (Button) this.findViewById(R.id.btn5); 

                btn5.setText("顯示全部資料"); 

                btn5.setOnClickListener(new Button.OnClickListener() { 

                                showItems(); 

                Button btn6 = (Button) this.findViewById(R.id.btn6); 

                btn6.setText("删除表"); 

                btn6.setOnClickListener(new Button.OnClickListener() { 

                                dropTable(); 

        // 建立資料表 

        private void CreateTable() { 

                SQLiteDatabase db = dbHelper.getWritableDatabase(); 

                String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME 

                                + " (ID INTEGER PRIMARY KEY, Name VARCHAR, Age INTEGER);"; 

                try { 

                        db.execSQL(sql); 

                        txtMsg.append("資料表成功建立\n"); 

                } catch (SQLException ex) { 

                        txtMsg.append("資料表建立錯誤\n" + ex.toString() + "\n"); 

                } 

        // 插入資料 

        private void insertItem() { 

                        Random random = new Random(); 

                        for (int i = 0; i &lt; 3; i++) { 

                                String sql = "insert into " + TABLE_NAME 

                                                + " (name, age) values ('name" + String.valueOf(i) 

                                                + "', " + random.nextInt() + ")"; 

                                // execSQL() - 執行指定的 sql 

                                db.execSQL(sql); 

                        txtMsg.append("成功插入 3 條資料\n"); 

                        txtMsg.append("插入資料失敗\n" + ex.toString() + "\n"); 

        // 删除資料 

        private void deleteItem() { 

                        SQLiteDatabase db = dbHelper.getWritableDatabase(); 

                        db.delete(TABLE_NAME, " id &lt; 999999", null); 

                        txtMsg.append("成功删除資料\n"); 

                } catch (SQLException e) { 

                        txtMsg.append("删除資料失敗\n"); 

        // 更新資料 

        private void updateItem() { 

                        ContentValues values = new ContentValues(); 

                        values.put("name", "批量更新後的名字"); 

                        db.update(TABLE_NAME, values, "id&lt;?", new String[] { "3" }); 

                        txtMsg.append("成功更新資料\n"); 

                        txtMsg.append("更新資料失敗\n"); 

        // 查詢資料 

        private void showItems() { 

                SQLiteDatabase db = dbHelper.getReadableDatabase(); 

                        String[] column = { "id", "name", "age" }; 

                        Cursor cursor = db.query(TABLE_NAME, column, null, null, null, 

                                        null, null); 

                        Integer num = cursor.getCount(); 

                        txtMsg.append("共 " + Integer.toString(num) + " 條記錄\n"); 

                        cursor.moveToFirst(); 

                        while (cursor.getPosition() != cursor.getCount()) { 

                                txtMsg.append(Integer.toString(cursor.getPosition()) + "," 

                                                + String.valueOf(cursor.getString(0)) + "," 

                                                + cursor.getString(1) + "," 

                                                + String.valueOf(cursor.getString(2)) + "\n"); 

                                cursor.moveToNext(); 

                        txtMsg.append("讀取資料失敗\n" + ex.toString() + "\n"); 

        // 删除資料表 

        private void dropTable() { 

                String sql = "DROP TABLE IF EXISTS " + TABLE_NAME; 

                        txtMsg.append("資料表删除成功\n"); 

                        txtMsg.append("資料表删除錯誤\n" + ex.toString() + "\n"); 

2、ContentProvider 的 Demo

MyUser.java

package com.webabcd.contentprovider; 

import android.net.Uri; 

import android.provider.BaseColumns; 

// 自定義 ContentProvider 所需的實體類 

public class MyUser { 

        // 必須要有 _id 字段。本例中 BaseColumn 類中已經包含了 _id 字段 

        public static final class User implements BaseColumns { 

                // 定義 CONTENT_URI 

                public static final Uri CONTENT_URI = Uri.parse("content://com.webabcd.MyContentProvider"); 

                // 表資料列 

                public static final String USER_NAME = "USER_NAME"; 

MyContentProvider.java

import java.io.File; 

import java.io.FileInputStream; 

import java.io.FileOutputStream; 

import org.apache.http.util.EncodingUtils; 

import android.content.ContentProvider; 

import android.content.ContentUris; 

import android.database.MatrixCursor; 

// 繼承 ContentProvider 以實作自定義的 ContentProvider(基于檔案的資訊存儲) 

public class MyContentProvider extends ContentProvider { 

        private File file; 

        private FileOutputStream out; 

        private FileInputStream in; 

        // ContentProvider 的删除資料接口 

        public int delete(Uri uri, String selection, String[] selectionArgs) { 

                // TODO Auto-generated method stub 

                return 0; 

        public String getType(Uri uri) { 

                return null; 

        // ContentProvider 的插入資料接口    

        public Uri insert(Uri uri, ContentValues values) { 

                        out = new FileOutputStream(file); 

                        out.write(values.getAsString(MyUser.User.USER_NAME).getBytes()); 

                        out.close(); 

                        int rowId = 0; 

                        Uri rowUri = ContentUris.appendId( 

                                        MyUser.User.CONTENT_URI.buildUpon(), rowId).build(); 

                        getContext().getContentResolver().notifyChange(rowUri, null); 

                        return rowUri; 

                } catch (Exception e) { 

                        return null; 

        // 建立用于儲存資訊的檔案 

        public boolean onCreate() { 

                        // 每個包中應用程式的私有目錄為:/data/data/包名/ 

                        // SD 卡目錄為:/sdcard 

                        file = new File("/data/data/com.webabcd.contentprovider/", 

                                        "demo.txt"); 

                        if (!file.exists()) 

                                file.createNewFile(); 

                        return true; 

                } catch (Exception ex) { 

                        return false; 

        // ContentProvider 的查詢資料接口 

        public Cursor query(Uri uri, String[] projection, String selection, 

                        String[] selectionArgs, String sortOrder) { 

                String content; 

                        in = new FileInputStream(file); 

                        int length = (int) file.length(); 

                        byte[] buffer = new byte[length]; 

                        in.read(buffer, 0, length); 

                        content = EncodingUtils.getString(buffer, "UTF-8"); 

                        in.close(); 

                        String[] columns = new String[] { MyUser.User._ID, MyUser.User.USER_NAME }; 

                        MatrixCursor cur = new MatrixCursor(columns); 

                        String[] values = new String[] { "0", content }; 

                        cur.moveToFirst(); 

                        cur.addRow(values); 

                        return cur; 

        // ContentProvider 的更新資料接口 

        public int update(Uri uri, ContentValues values, String selection, 

                        String[] selectionArgs) { 

import android.provider.Contacts; 

import android.provider.Contacts.People; 

import android.util.Log; 

import android.widget.Toast; 

/* 

* 幾個常用的系統内置的 ContentProvider 如下:    

* content://media/internal/images    這個URI将傳回裝置上存儲的所有圖檔 

* content://contacts/people/ 這個URI将傳回裝置上的所有聯系人資訊 

* content://contacts/people/45 這個URI傳回單個結果(聯系人資訊中ID為45的聯系人記錄) 

*/ 

                btn1.setText("新增聯系人記錄"); 

                                Random random = new Random(); 

                                insertRecords("name" + String.valueOf(random.nextInt()), String 

                                                .valueOf(random.nextInt())); 

                btn2.setText("檢視聯系人記錄"); 

                                displayRecords(); 

                btn3.setText("清除聯系人記錄"); 

                                deleteRecords(); 

                btn4.setText("更新聯系人記錄"); 

                                // 此處隻是示範,id 來自 People._ID ,可參見 displayRecords() 是如何擷取 id 的 

                                int id = 0; 

                                updateRecord(id, "修改後的name"); 

                btn5.setText("新增記錄到 MyContentProvider"); 

                                insertRecord2MyContentProvider("webabcd"); 

                btn6.setText("擷取記錄從 MyContentProvider"); 

                                displayRecord2MyContentProvider(); 

        // 調用 ContentProvider 的插入接口 

        private void insertRecords(String name, String phoneNum) { 

                ContentValues values = new ContentValues(); 

                values.put(People.NAME, name); 

                Uri uri = getContentResolver().insert(People.CONTENT_URI, values); 

                Log.d("MyDebug", uri.toString()); 

                Uri numberUri = Uri.withAppendedPath(uri, 

                                People.Phones.CONTENT_DIRECTORY); 

                Log.d("MyDebug", numberUri.toString()); 

                values.clear(); 

                values.put(Contacts.Phones.TYPE, People.Phones.TYPE_MOBILE); 

                values.put(People.NUMBER, phoneNum); 

                getContentResolver().insert(numberUri, values); 

        // 調用 ContentProvider 的查詢接口 

        private void displayRecords() { 

                String[] columns = new String[] { People._ID, People.NAME, 

                                People.NUMBER }; 

                Uri contacts = People.CONTENT_URI; 

                Log.d("MyDebug", contacts.toString()); 

                Cursor cur = managedQuery(contacts, columns, // 要傳回的資料字段 

                                null, // WHERE子句 

                                null, // WHERE 子句的參數 

                                null // Order-by子句 

                ); 

                if (cur.moveToFirst()) { 

                        String id = null; 

                        String name = null; 

                        String phoneNo = null; 

                        while (cur.getPosition() != cur.getCount()) { 

                                id = cur.getString(cur.getColumnIndex(People._ID)); 

                                name = cur.getString(cur.getColumnIndex(People.NAME)); 

                                phoneNo = cur.getString(cur.getColumnIndex(People.NUMBER)); 

                                Toast.makeText(this, id + " / " + name + " / " + phoneNo, 

                                                Toast.LENGTH_SHORT).show(); 

                                cur.moveToNext(); 

        // 調用 ContentProvider 的删除接口 

        private void deleteRecords() { 

                Uri uri = People.CONTENT_URI; 

                getContentResolver().delete(uri, null, null); 

                // getContentResolver().delete(uri, "NAME=" + "'name'", null); 

        // 調用 ContentProvider 的更新接口 

        private void updateRecord(int recordNo, String name) { 

                Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, recordNo); 

                getContentResolver().update(uri, values, null, null); 

        // 調用自定義 ContentProvider 的插入接口 

        private void insertRecord2MyContentProvider(String name) { 

                values.put(MyUser.User.USER_NAME, name); 

                getContentResolver().insert(MyUser.User.CONTENT_URI, values); 

        // 調用自定義 ContentProvider 的查詢接口 

        private void displayRecord2MyContentProvider() { 

                String[] columns = new String[] { MyUser.User.USER_NAME }; 

                Uri uri = MyUser.User.CONTENT_URI; 

                Cursor cur = managedQuery(uri, columns, null, null, null); 

                while (cur.getPosition() != cur.getCount()) { 

                        String id = cur.getString(cur.getColumnIndex(People._ID)); 

                        String name = cur.getString(cur.getColumnIndex(MyUser.User.USER_NAME)); 

                        Toast.makeText(this, 

                                        id + " / " + name, 

                                        Toast.LENGTH_SHORT).show(); 

                        cur.moveToNext(); 

AndroidManifest.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt; 

&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" 

            package="com.webabcd.contentprovider" 

            android:versionCode="1" 

            android:versionName="1.0"&gt; 

        &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt; 

                &lt;activity android:name=".Main" 

                                    android:label="@string/app_name"&gt; 

                        &lt;intent-filter&gt; 

                                &lt;action android:name="android.intent.action.MAIN" /&gt; 

                                &lt;category android:name="android.intent.category.LAUNCHER" /&gt; 

                        &lt;/intent-filter&gt; 

                &lt;/activity&gt; 

                &lt;!-- 

                        配置一個自定義的 ContentProvider" 

                --&gt; 

                &lt;provider android:name="MyContentProvider" android:authorities="com.webabcd.MyContentProvider" /&gt; 

        &lt;/application&gt; 

        &lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;&lt;/uses-permission&gt; 

        &lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;&lt;/uses-permission&gt; 

        &lt;uses-sdk android:minSdkVersion="3" /&gt; 

&lt;/manifest&gt;

OK

     本文轉自webabcd 51CTO部落格,原文連結:http://blog.51cto.com/webabcd/342098,如需轉載請自行聯系原作者