Android ContentProvider 簡介

當在系統中部署一個又一個Android應用以後,系統裏將會包含多個Android應用,有時候就須要在小同的應用之問芡亭數據,好比如今有一個短信接收應用,用戶想把接收到的陌生短信的發信人添加到聯繫人管理應用中,就須要在小同應用之問共寧數據。對於這種須要在小同應用之問共亨數據的需求,固然可讓一個應用程序直接去操做另個應用程序所記錄的數據,好比操做它所記錄的SharedPreferences、文件或數據庫等,這種方式顯得太雜亂了:不一樣的應用程序記錄數據的方式差異很大,這種力式不利於應用程序之問進行數據交換。
爲了在應用程序之問交換數據,Android提供了ContentProvider,ContentProvider是不一樣應用程序之間進行數據交換的標準API,當一個應用程序須要把本身的數據暴露給其餘程序使用時,該應用科序就能夠經過提供ContentProvider來實現;其餘應用程序就可經過ContentResolver來操做ContentProvider暴露的數據。
ContentProvider也是Android應刖的四大組件之一,與Activity、Service、BroadcastReceiver類似,它們都須要存AndroidManifest.xml文件中進行配置。
一旦某個應用程序經過ContentProvider暴露了本身的數據操做接口,那麼無論該應用程序是否啓動,其餘應用程序均可經過該接口來操做該應用程序的內部數據,包括增長數據、刪除數據、修改數據、查詢數據等。
java


MyContentProvider

MyUser.javaandroid

package com.supermario.mycontentprovider;

import android.net.Uri;
import android.provider.BaseColumns;

public class MyUser {
    public static final String AUTHORITY = "com.supermario.MyContentProvider";

    // BaseColumn類中已經包含了_id字段
    public static final class User implements BaseColumns {
        // 定義Uri
        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
        // 定義數據表列
         public static final String USER_NAME = "USER_NAME";
    }
}

MyContentProvider.javasql

package com.supermario.mycontentprovider;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;

/**
 * MyContentProvider繼承ContentProvider類,實現其insert,update,delete,getType,
 * onCreate等方法
 */
public class MyContentProvider extends ContentProvider {
    // 定義一個SQLiteDatabase變量
    private SQLiteDatabase sqlDB;
    // 定義一個DatabaseHelper變量
    private DatabaseHelper dbHelper;
    // 數據庫名
    private static final String DATABASE_NAME = "Users.db";
    // 數據庫版本
    private static final int DATABASE_VERSION = 1;
    // 表名
    private static final String TABLE_NAME = "User";

    /**
     * 定義一個內部類
     * 
     * 這個內部類繼承SQLiteOpenHelper類,重寫其方法
     */
    public static class DatabaseHelper extends SQLiteOpenHelper {
        // 構造方法
        public DatabaseHelper(Context context) {
            // 父類構造方法
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        // 當第一次建立數據庫的時候調用該方法,能夠爲數據庫增長一些表,和初始化一些數據
        @Override
        public void onCreate(SQLiteDatabase db) {
            // 在數據庫裏生成一張表
            db.execSQL("Create table "
                    + TABLE_NAME
                    + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);");
        }

        // 當更新數據庫版本的時候,調用該方法。能夠刪除,修改表的一些信息
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
            onCreate(db);
        }
    }

    // 這是一個回調函數,當生成所在類的對象時,這個方法被調用,建立一個數據庫
    @Override
    public boolean onCreate() {
        dbHelper = new DatabaseHelper(getContext());
        return (dbHelper == null) ? false : true;
    }

    // 查詢
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,    String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        qb.setTables(TABLE_NAME);
        Cursor c = qb.query(db, projection, selection, null, null, null,sortOrder);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    // 取得類型
    @Override
    public String getType(Uri uri) {
        return null;
    }

    // 插入數據
    @Override
    public Uri insert(Uri uri, ContentValues contentvalues) {
        sqlDB = dbHelper.getWritableDatabase();
        long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues);
        if (rowId > 0) {
            Uri rowUri = ContentUris.appendId(MyUser.User.CONTENT_URI.buildUpon(), rowId).build();
            getContext().getContentResolver().notifyChange(rowUri, null);
            return rowUri;
        }
        throw new SQLException("Failed to insert row into" + uri);
    }

    // 刪除數據
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    // 更新數據
    @Override
    public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {
        return 0;
    }
}

MyContentActivity.java數據庫

package com.supermario.mycontentprovider;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;

public class MyContentActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 插入兩條記錄
         insertRecord("Test");
        insertRecord("Guo");
        // 顯示記錄
         displayRecords();
    }

    // 插入記錄
    private void insertRecord(String userName) {
        ContentValues values = new ContentValues();
        values.put(MyUser.User.USER_NAME, userName);
        getContentResolver().insert(MyUser.User.CONTENT_URI, values);
    }

    private void displayRecords() {
        // 構建一個字符串數組用於存放用戶的記錄
         String columns[] = new String[] { MyUser.User._ID,MyUser.User.USER_NAME };
        // 設定ContentProvider的Uri
        Uri myUri = MyUser.User.CONTENT_URI;
        Cursor cur = managedQuery(myUri, columns, null, null, null);
        if (cur.moveToFirst()) {
            String id = null;
            String userName = null;
            do {
                id = cur.getString(cur.getColumnIndex(MyUser.User._ID));
                userName = cur.getString(cur.getColumnIndex(MyUser.User.USER_NAME));
                // 顯示數據表中的數據
                Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG).show();
            } while (cur.moveToNext());
        }
    }
}

AndroidManifest.xml數組

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.supermario.mycontentprovider"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="10" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <!-- 聲明ContentProvider -->
        <provider android:name="MyContentProvider"
            android:authorities="com.supermario.MyContentProvider"></provider>
        <activity
            android:name=".MyContentActivity"
            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>

界面:app

PIC_20131119_160654_9A9


MyContentClient

MyConrentClientActivity.javaide

package com.supermario.mycontentclient;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
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 MyContentClientActivity extends Activity {
    public static final String AUTHORITY = "com.supermario.MyContentProvider";
    private Button insertButton = null;
    // 訪問ContentProvider的Uri
    Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView show=(TextView)findViewById(R.id.show);
        StringBuffer sb=new StringBuffer("");
        // 獲得ContentProvider對於表的全部數據,以遊標格式保存
        Cursor c = managedQuery(CONTENT_URI,
                new String[] { "_id", "USER_NAME" }, null, null, null); 
        // 循環打印ContentProvider的數據
        if (c.moveToFirst()) {
            String _id = null;
            String user_name = null;
            do {
                // 獲得_id列,USER_NAME列
                _id = c.getString(c.getColumnIndex("_id"));
                user_name = c.getString(c.getColumnIndex("USER_NAME"));
 
                sb.append("_id = " + _id + ", user_name = " + user_name+"\n");
            } while (c.moveToNext());
        }
        show.setText(sb);
        // 根據Id獲得控件對象
        insertButton = (Button) findViewById(R.id.insert);
        // 給按鈕綁定事件監聽器
        insertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 獲得EditText輸入的數據
                String username = ((EditText) findViewById(R.id.userName))
                        .getText().toString();
                // 生成一個ContentResolver對象
                ContentResolver cr = getContentResolver();
                // 生成一個ContentValues對象
                ContentValues values = new ContentValues();
                // 將EditText輸入的值,保存到ContentValues對象中
                values.put("USER_NAME", username);
                // 插入數據
                cr.insert(CONTENT_URI, values);
            }
        });
    }
}

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" >
    <!-- 用於顯示數據庫信息 -->
    <TextView 
        android:id="@+id/show"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <!-- 文本編輯框 ,用於輸入信息-->
    <EditText
        android:id="@+id/userName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <!-- 輸入按鈕 -->
    <Button
        android:id="@+id/insert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
</LinearLayout>

AndroidManifest.xmlui

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

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MyContentClientActivity"
            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>

界面:this

PIC_20131119_160646_814

相關文章
相關標籤/搜索