Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android編程入門 >> android基礎---->ContentProvider的使用

android基礎---->ContentProvider的使用

編輯:Android編程入門

  內容提供器(Content Provider)主要用於在不同的應用程序之間實現數據共享的功能,它提供了一套完整的機制,允許一個程序訪問另一個程序中的數據,同時還能保證被訪數據的安全性。目前,使用內容提供器是Android 實現跨程序共享數據的標准方式。不同於文件存儲和SharedPreferences 存儲中的兩種全局可讀寫操作模式,內容提供器可以選擇只對哪一部分數據進行共享,從而保證我們程序中的隱私數據不會有洩漏的風險。接下來,我們開始內容提供器的學習。content provider的原理說明,參見另外一篇博客(android高級---->ContentProvider的源碼分析)

 

 目錄導航:

  1.   內容提供器簡單說明
  2.   訪問其它的Content Provider
  3.   創建自己的Content Provider
  4.   友情鏈接

 

內容提供器簡單說明

一、 內容提供器的用法:

  • 使用現有的內容提供器來讀取和操作相應程序中的數據
  • 創建自己的內容提供器給我們程序的數據提供外部訪問接口,需要繼承ContentProvider類

二、 ContentResolver的基本用法:

  • 得到實例:  可以通過Context 中的getContentResolver()方法獲取到該類的實例
  • 基本方法:  提供了一系列的方法用於對數據進行CRUD 操作
  • 使用注意:  ContentResolver中的增刪改查方法都是不接收表名參數的,而是使用一個Uri 參數代替,這個參數被稱為Content URI。

三、 內容URI的基本介紹:

  • 重要用作:  內容URI 給內容提供器中的數據建立了唯一標識符
  • 組成部分:  權限(authority)和路徑(path)。
  • 權限路徑:  權限是用於對不同的應用程序做區分的,一般為了避免沖突,都會采用程序包名的方式來進行命名;路徑則是用於對同一應用程序中不同的表做區分的,通常都會添加到權限的後面。

 

訪問其它的Content Provider

創建一個簡單項目,結構如下:

 

一、 在activity_main.xml文件中創建一個ListView的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

 

二、 在MainActivity.java中:

package com.example.linux.getcontact;

import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    ArrayAdapter<String> adapter;
    List<String> contactsList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.listView);
        adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList);
        listView.setAdapter(adapter);
        readContacts();
    }

    private void readContacts() {
        Cursor cursor = null;
        try {
            // 查詢聯系人數據
            cursor = getContentResolver().query(
                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
            while (cursor.moveToNext()) {
                // 獲取聯系人姓名
                String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                // 獲取聯系人手機號
                String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                contactsList.add(displayName + "\n" + number);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }
}

 

三、 讀取系統聯系人是需要聲明權限的,在AndroidManifest.xml中增加權限:

 <uses-permission android:name="android.permission.READ_CONTACTS" />

 

創建自己的Content Provider

  上一個自己的程序中訪問其他應用程序的數據。總體來說思路還是非常簡單的,只需要獲取到該應用程序的內容URI,然後借助ContentResolver進行CRUD 操作就可以了。以下我們創建自己的內容提供器。

創建內容提供器--Server

項目結構:

 

一、 創建一個與數據庫表對應的Bean:Person.java:

package com.example.linux.contentproviderserver.model;

/**
 * Created by Linux on 2016/3/4.
 */
public class Person {

    private Integer _id;
    private String name;
    private String age;

    public Integer get_id() {
        return _id;
    }

    public void set_id(Integer _id) {
        this._id = _id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

 

二、 接著建立一個關於數據庫的工具類:DBOpenHelper.java

package com.example.linux.contentproviderserver.util;

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

/**
 * Created by Linux on 2016/3/4.
 */
public class DBOpenHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "person.db"; //數據庫名稱
    private static final int DATABASE_VERSION = 1;//數據庫版本
    private static final String CREATE_TABLE_PERSON = "CREATE TABLE person (_id integer primary key autoincrement, name varchar(20), age varchar(10))";
    private static final String DROP_TABLE_PERSON = "DROP TABLE IF EXISTS person";

    public DBOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_PERSON);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DROP_TABLE_PERSON);
        onCreate(db);
    }
}

 

三、 創建一個自己的繼承了ContentProvider的內容提供器:PersonProvider.java

  • 做一些初始化的工作:
private final static String TAG = "PersonProvider";
private DBOpenHelper dbOpenHelper;
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
private static final String AUTHORITY = "com.example.linux.contentproviderserver.action.PersonProvider";
private static final String PATH_1 = "person";
private static final String PATH_2 = "person/#";

static {
    Log.i(TAG, "on PersonProvider static");
    MATCHER.addURI(AUTHORITY, PATH_1, PERSONS);
    MATCHER.addURI(AUTHORITY, PATH_2, PERSON);
}

@Override
public boolean onCreate() {
    Log.i(TAG, "on PersonProvider  create");
    this.dbOpenHelper = new DBOpenHelper(this.getContext());
    return false;
}
  • 重寫它的查插入方法:insert()
// 插入person表中的所有記錄 /person
// 插入person表中指定id的記錄 /person/10
@Override
public Uri insert(Uri uri, ContentValues values) {
    Log.i(TAG, "uri: " + uri.getPath() + ", values: " + values.getAsString("name"));
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    switch (MATCHER.match(uri)) {
        case PERSONS:
            // 特別說一下第二個參數是當name字段為空時,將自動插入一個NULL。
            long rowid = db.insert("person", "name", values);
            Uri insertUri = ContentUris.withAppendedId(uri, rowid);// 得到代表新增記錄的Uri
            this.getContext().getContentResolver().notifyChange(uri, null);
            return insertUri;
        case PERSON:
            Log.i("some", "soem");
            return null;
        default:
            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    }
}
  • 重寫它的刪除方法,delete()方法:
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    int count = 0;
    switch (MATCHER.match(uri)) {
        case PERSONS:
            count = db.delete("person", selection, selectionArgs);
            return count;
        case PERSON:
            long id = ContentUris.parseId(uri);
            String where = "_id=" + id;
            if (selection != null && !"".equals(selection)) {
                where = selection + " and " + where;
            }
            count = db.delete("person", where, selectionArgs);
            return count;
        default:
            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    }
}
  • 重寫它的更新方法:update()
@Override
public int update(Uri uri, ContentValues values, String selection,
                  String[] selectionArgs) {
    SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
    int count = 0;
    switch (MATCHER.match(uri)) {
        case PERSONS:
            count = db.update("person", values, selection, selectionArgs);
            return count;
        case PERSON:
            long id = ContentUris.parseId(uri);
            String where = "_id=" + id;
            if (selection != null && !"".equals(selection)) {
                where = selection + " and " + where;
            }
            count = db.update("person", values, where, selectionArgs);
            return count;
        default:
            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    }
}
  • 重寫它的查詢方法,query()
@Override
public Cursor query(Uri uri, String[] projection, String selection,
                    String[] selectionArgs, String sortOrder) {
    Log.i(TAG, "PersonProvider query");
    SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
    int matchResult = MATCHER.match(uri);
    switch (MATCHER.match(uri)) {
        case PERSONS:
            return db.query("person", projection, selection, selectionArgs,
                    null, null, sortOrder);

        case PERSON:
            long id = ContentUris.parseId(uri);
            String where = "_id=" + id;
            if (selection != null && !"".equals(selection)) {
                where = selection + " and " + where;
            }
            return db.query("person", projection, where, selectionArgs, null,
                    null, sortOrder);
        default:
            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    }
}
  • 重寫它的類型方法,getType(0
//返回數據的MIME類型。
@Override
public String getType(Uri uri) {
    Log.i(TAG, "PersonProvider get type");
    switch (MATCHER.match(uri)) {
        case PERSONS:
            return "vnd.android.cursor.dir/person";

        case PERSON:
            return "vnd.android.cursor.item/person";

        default:
            throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
    }
}

 

 五、 在MainActivity方法,為了方便得到數據庫中的數據,添加了查詢與增加方法:

package com.example.linux.contentproviderserver;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import com.example.linux.contentproviderserver.util.DBOpenHelper;

/**
 * writer: huhx
 * 內容提供器的服務端
 */
public class MainActivity extends AppCompatActivity {
    private final static String TAG = "PersonProvider";
    private DBOpenHelper dbOpenHelper;
    SQLiteDatabase database = null;
    private StringBuffer stringBuffer = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "main on create.");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbOpenHelper = new DBOpenHelper(this);
        database = dbOpenHelper.getWritableDatabase();
    }

    // 查詢所有的數據
    public void queryAll(View view) {
        stringBuffer = new StringBuffer();
        Cursor cursor = database.rawQuery("select * from person", null);
        cursor.moveToFirst();
        while(cursor.moveToNext()) {
            String name = cursor.getString(1);
            int age = cursor.getInt(2);
            stringBuffer.append("name: " + name + ", age: " + age + "\n");
        }
        if (stringBuffer.toString().equals("")) {
            Toast.makeText(MainActivity.this, "nothing", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, stringBuffer, Toast.LENGTH_SHORT).show();
        }
    }

    //插入數據
    public void insertData(View view) {
        Object[] object = new Object[]{"linux", 23};
        database.execSQL("insert into person(name, age) values(?, ?)", object);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        database.close();
    }
}

 

使用內容提供器--Client

項目結構:

一、在MainActivity中增加了查詢與插入功能:

package com.example.linux.contentproviderclient;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

/**
 * 內容提供器的客戶端
 */
public class MainActivity extends AppCompatActivity {

    private StringBuffer stringBuffer = new StringBuffer();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 插入數據
    public void insert(View view) {
        ContentResolver contentResolver = getContentResolver();
        Uri insertUri = Uri.parse("content://com.example.linux.contentproviderserver.action.PersonProvider/person");
        ContentValues values = new ContentValues();
        values.put("name", "wangkuifeng");
        values.put("age", 23);
        Uri uri = contentResolver.insert(insertUri, values);
        Toast.makeText(MainActivity.this, "insert success: " + uri, Toast.LENGTH_SHORT).show();
    }

    // 查詢數據
    public void query(View view) {
        ContentResolver contentResolver = getContentResolver();
        Uri queryUri = Uri.parse("content://com.example.linux.contentproviderserver.action.PersonProvider/person/5");
        Cursor queryResult = contentResolver.query(queryUri, null, null, null, null);
        int count = queryResult.getCount();
        for (queryResult.moveToFirst(); !queryResult.isAfterLast(); queryResult.moveToNext()) {
            String name = queryResult.getString(1);
            int age = queryResult.getInt(2);
            stringBuffer.append("name: " + name + ", age: " + age + "\n");
        }
        Toast.makeText(MainActivity.this, stringBuffer.toString() + "\ncount: " + count, Toast.LENGTH_SHORT).show();
        queryResult.close();
    }
}

 

友情鏈接

  • 訪問其它的Content Provider   訪問密碼 777a
  • 創建自己的Content Provider   訪問密碼 7388
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved