天天看点

系出名门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,如需转载请自行联系原作者