第八章 Content Provider

第八章 Content Provider

Android中推荐使用content provider方法在不同包之间共享数据

content provider可以被视为一个数据仓库 他如何存储数据与应用如何使用它无关。然而应用如何使用一致的编程接口来访问存储在它里面的数据却非常重要。Content provider的行为与数据库非常相似(可以查询它、编辑它的内容、添加或者删除内容)

与数据库不同的是:一个content provider可以使用不同的方式存储他的数据,数据可以被存储在数据库中、文件中、网络上

Content provider的种类:

Browser:存储浏览器数据,如浏览器书签、浏览器访问历史等

CallLog:存储通话数据,如未接电话、电话详情等

Contacts:存储通讯录详情

MediaStore:存储多媒体文件,如音频、视频、图片

Settings:存储设备的设置和偏好设置

除了许多内置的content provider以外,可以创建自定义的content provider

要查询一个content provider,需要以统一资源标识符URI的形式指定查询字符串,以及一个可选的特定行说明符

 

使用contenet provider:

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.jfdimarzio.contentproviders.MainActivity">

 

 

    <TextView

        android:text="ISBN"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/textView"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toTopOf="@+id/activity_main"

        android:layout_marginTop="16dp"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1" />

 

    <EditText

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:inputType="text"

        android:ems="10"

        android:id="@+id/txtISBN"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toBottomOf="@+id/textView"

        android:layout_marginTop="8dp"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1"

        app:layout_constraintBottom_toTopOf="@+id/textView2"

        android:layout_marginBottom="8dp"

        app:layout_constraintHorizontal_bias="0.46"

        app:layout_constraintVertical_bias="0.100000024" />

 

    <TextView

        android:text="Title"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/textView2"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toTopOf="@+id/activity_main"

        android:layout_marginTop="142dp"

        tools:layout_constraintTop_creator="1"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1" />

 

    <EditText

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:inputType="text"

        android:ems="10"

        android:id="@+id/txtTitle"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toBottomOf="@+id/textView2"

        android:layout_marginTop="8dp"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1" />

 

    <Button

        android:text="Add Title"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/btnAdd"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toBottomOf="@+id/txtTitle"

        android:layout_marginTop="112dp"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1"

        android:onClick="onClickAddTitle" />

 

    <Button

        android:text="Retrieve Titles"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:id="@+id/btnRetrieve"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintTop_toBottomOf="@+id/btnAdd"

        android:layout_marginTop="32dp"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        tools:layout_constraintRight_creator="1"

        android:onClick="onClickRetrieveTitles"  />

</android.support.constraint.ConstraintLayout>

 

package com.jfdimarzio.contentproviders;

 

 

import android.content.ContentProvider;

import android.content.ContentUris;

import android.content.ContentValues;

import android.content.Context;

import android.content.UriMatcher;

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;

import android.text.TextUtils;

import android.util.Log;

 

public class BooksProvider extends ContentProvider {

    static final String PROVIDER_NAME = "com.jfdimarzio.provider.Books";

    static final Uri CONTENT_URI = Uri.parse("content://"+ PROVIDER_NAME + "/books");

    static final String _ID = "_id";

    static final String TITLE = "title";

    static final String ISBN = "isbn";

    static final int BOOKS = 1;

    static final int BOOK_ID = 2;

    private static final UriMatcher uriMatcher;

    static{

        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

        uriMatcher.addURI(PROVIDER_NAME, "books", BOOKS);

        uriMatcher.addURI(PROVIDER_NAME, "books/#", BOOK_ID);

    }

    //---for database use---

    SQLiteDatabase booksDB;

    static final String DATABASE_NAME = "Books";

    static final String DATABASE_TABLE = "titles";

    static final int DATABASE_VERSION = 1;

    static final String DATABASE_CREATE =

            "create table " + DATABASE_TABLE +

                    " (_id integer primary key autoincrement, "

                    + "title text not null, isbn text not null);";

    private static class DatabaseHelper extends SQLiteOpenHelper

    {

        DatabaseHelper(Context context) {

            super(context, DATABASE_NAME, null, DATABASE_VERSION);

        }

        @Override

        public void onCreate(SQLiteDatabase db)

        {

            db.execSQL(DATABASE_CREATE);

        }

        @Override

        public void onUpgrade(SQLiteDatabase db, int oldVersion,

                              int newVersion) {

            Log.w("Provider database",

                    "Upgrading database from version " +

                            oldVersion + " to " + newVersion +

                            ", which will destroy all old data");

            db.execSQL("DROP TABLE IF EXISTS titles");

            onCreate(db);

        }

    }

 

    @Override

    public int delete(Uri arg0, String arg1, String[] arg2) {

        // arg0 = uri

        // arg1 = selection

        // arg2 = selectionArgs

        int count=0;

        switch (uriMatcher.match(arg0)){

            case BOOKS:

                count = booksDB.delete(

                        DATABASE_TABLE,

                        arg1,

                        arg2);

                break;

            case BOOK_ID:

                String id = arg0.getPathSegments().get(1);

                count = booksDB.delete(

                        DATABASE_TABLE,

                        _ID + " = " + id +

                                (!TextUtils.isEmpty(arg1) ? " AND (" +

                                        arg1 + ')' : ""),

                arg2);

                break;

            default: throw new IllegalArgumentException("Unknown URI " + arg0);

        }

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

        return count;

    }

    @Override

    public String getType(Uri uri) {

        switch (uriMatcher.match(uri)){

            //---get all books---

            case BOOKS:

                return "vnd.android.cursor.dir/vnd.learn2develop.books ";

 

            //---get a particular book---

            case BOOK_ID:

                return "vnd.android.cursor.item/vnd.learn2develop.books ";

 

            default:

                throw new IllegalArgumentException("Unsupported URI: " + uri);

        }

    }

    @Override

    public Uri insert(Uri uri, ContentValues values) {

        //---add a new book---

        long rowID = booksDB.insert(

                DATABASE_TABLE,

                "",

                values);

        //---if added successfully---

        if (rowID>0)

        {

            Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);

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

            return _uri;

        }

        throw new SQLException("Failed to insert row into " + uri);

    }

    @Override

    public boolean onCreate() {

        Context context = getContext();

        DatabaseHelper dbHelper = new DatabaseHelper(context);

        booksDB = dbHelper.getWritableDatabase();

        return (booksDB == null)? false:true;

    }

    @Override

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

                        String[] selectionArgs, String sortOrder) {

        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();

        sqlBuilder.setTables(DATABASE_TABLE);

        if (uriMatcher.match(uri) == BOOK_ID)

            //---if getting a particular book---

            sqlBuilder.appendWhere(

                    _ID + " = " + uri.getPathSegments().get(1));

        if (sortOrder==null || sortOrder=="")

            sortOrder = TITLE;

        Cursor c = sqlBuilder.query(

                booksDB,

                projection,

                selection,

                selectionArgs,

                null,

                null,

                sortOrder);

        //---register to watch a content URI for changes---

        c.setNotificationUri(getContext().getContentResolver(), uri);

        return c;

    }

    @Override

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

                      String[] selectionArgs) {

        int count = 0;

        switch (uriMatcher.match(uri)){

            case BOOKS:

                count = booksDB.update(

                        DATABASE_TABLE,

                        values,

                        selection,

                        selectionArgs);

                break;

            case BOOK_ID:

                count = booksDB.update(

                        DATABASE_TABLE,

                        values,

                        _ID + " = " + uri.getPathSegments().get(1) +

                                (!TextUtils.isEmpty(selection) ? " AND (" +

                                        selection + ')' : ""),

                selectionArgs);

                break;

            default: throw new IllegalArgumentException("Unknown URI " + uri);

        }

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

        return count;

    }

}

 

package com.jfdimarzio.contentproviders;

 

import android.content.ContentValues;

import android.content.CursorLoader;

import android.database.Cursor;

import android.net.Uri;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.EditText;

import android.widget.Toast;

 

public class MainActivity extends AppCompatActivity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

    }

    public void onClickAddTitle(View view) {

        //---add a book---

        ContentValues values = new ContentValues();

        values.put(BooksProvider.TITLE, ((EditText)

                findViewById(R.id.txtTitle)).getText().toString());

        values.put(BooksProvider.ISBN, ((EditText)

                findViewById(R.id.txtISBN)).getText().toString());

        Uri uri = getContentResolver().insert(

                BooksProvider.CONTENT_URI, values);

        Toast.makeText(getBaseContext(),uri.toString(),

                Toast.LENGTH_LONG).show();

    }

    public void onClickRetrieveTitles(View view) {

        //---retrieve the titles---

        Uri allTitles = Uri.parse(

                "content://com.jfdimarzio.provider.Books/books");

        Cursor c;

        CursorLoader cursorLoader = new CursorLoader(

                    this,

                    allTitles, null, null, null,

                    "title desc");

            c = cursorLoader.loadInBackground();

        if (c.moveToFirst()) {

            do{

                Toast.makeText(this,

                        c.getString(c.getColumnIndex(

                                BooksProvider._ID)) + ", " +

                                c.getString(c.getColumnIndex(

                                        BooksProvider.TITLE)) + ", " +

                                c.getString(c.getColumnIndex(

                                        BooksProvider.ISBN)),

                        Toast.LENGTH_SHORT).show();

            } while (c.moveToNext());

        }

    }

}

 

<?xml version="1.0" encoding="utf-8"?>

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.jfdimarzio.provider.MainActivity">

 

 

    <TextView

        android:text="TextView"

        android:layout_width="0dp"

        android:layout_height="60dp"

        android:id="@+id/contactName"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        android:layout_marginStart="63dp"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        android:layout_marginEnd="63dp"

        tools:layout_constraintRight_creator="1"

        app:layout_constraintBottom_toTopOf="@+id/contactID"

        android:layout_marginBottom="40dp"

        tools:layout_constraintBottom_creator="1" />

 

    <TextView

        android:text="TextView"

        android:layout_width="0dp"

        android:layout_height="64dp"

        android:id="@+id/contactID"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        android:layout_marginStart="63dp"

        tools:layout_constraintLeft_creator="1"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        android:layout_marginEnd="63dp"

        tools:layout_constraintRight_creator="1"

        app:layout_constraintBottom_toBottomOf="@+id/activity_main"

        android:layout_marginBottom="56dp"

        tools:layout_constraintBottom_creator="1" />

 

    <ListView

        android:layout_height="0dp"

        android:id="@android:id/list"

        android:layout_width="wrap_content"

        app:layout_constraintLeft_toLeftOf="@+id/activity_main"

        app:layout_constraintTop_toTopOf="@+id/activity_main"

        tools:layout_constraintTop_creator="1"

        app:layout_constraintRight_toRightOf="@+id/activity_main"

        app:layout_constraintBottom_toTopOf="@+id/contactName"

        android:layout_marginBottom="5dp"

        tools:layout_constraintBottom_creator="1" />

</android.support.constraint.ConstraintLayout>

 

package com.jfdimarzio.provider;

 

import android.Manifest;

import android.app.ListActivity;

import android.content.pm.PackageManager;

import android.database.Cursor;

import android.net.Uri;

import android.provider.ContactsContract;

import android.support.v4.app.ActivityCompat;

import android.support.v4.content.ContextCompat;

import android.support.v4.content.CursorLoader;

import android.support.v4.widget.CursorAdapter;

import android.support.v4.widget.SimpleCursorAdapter;

import android.os.Bundle;

import android.util.Log;

import android.widget.Toast;

 

public class MainActivity extends ListActivity {

    final private int REQUEST_READ_CONTACTS = 123;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

 

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)!= PackageManager.PERMISSION_GRANTED ) {

 

            ActivityCompat.requestPermissions(this,

                    new String[]{Manifest.permission.READ_CONTACTS},

                    REQUEST_READ_CONTACTS);

        } else{

            ListContacts();

        }

 

 

        }

    @Override

    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

        switch (requestCode) {

            case REQUEST_READ_CONTACTS:

                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

 

                    ListContacts();

 

                } else {

                    Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();

                }

                break;

            default:

                super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        }

    }

 

    private void PrintContacts(Cursor c)

    {

        if (c.moveToFirst()) {

            do{

 

                String contactID = c.getString(c.getColumnIndex(

                        ContactsContract.Contacts._ID));

                String contactDisplayName =

                        c.getString(c.getColumnIndex(

                                ContactsContract.Contacts.DISPLAY_NAME));

                Log.v("Content Providers", contactID + "," +

                        contactDisplayName);

                //---get phone number---

                //int hasPhone = c.getInt(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

 

                    Cursor phoneCursor =

                            getContentResolver().query(

                                    ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,

                                    ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " +

                            contactID, null, null);

                    while (phoneCursor.moveToNext()) {

                        Log.v("Content Providers",

                                phoneCursor.getString(

                                        phoneCursor.getColumnIndex(

                                                ContactsContract.CommonDataKinds.Phone.NUMBER)));

                    }

                    phoneCursor.close();

 

            } while (c.moveToNext());

        }

    }

 

 

    protected void ListContacts(){

        Uri allContacts = Uri.parse("content://contacts/people");

        Cursor c;

        CursorLoader cursorLoader = new CursorLoader(

                this,

                allContacts,

                null,

                null,

                null,

                null);

        c = cursorLoader.loadInBackground();

 

PrintContacts(c);

 

        String[] columns = new String[]{

                ContactsContract.Contacts.DISPLAY_NAME,

                ContactsContract.Contacts._ID};

 

        int[] views = new int[]{R.id.contactName, R.id.contactID};

        SimpleCursorAdapter adapter;

 

        adapter = new SimpleCursorAdapter(

                this, R.layout.activity_main, c, columns, views,

                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

 

        this.setListAdapter(adapter);

 

 

    }

}

 

 

全部评论

相关推荐

仁者伍敌:牛子这些人还会点一个自动回复,boss都不带回复的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务