内容提供者(ContentReslove)

ContentReslove

可以通过getContentResolver( )方法获取到该类的实例,ContentReslover中提供了一系列的方法用于对数据进行CRUD操作,其中insert( )方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据。

Uri主要由两部分组成,权限和路径。一般权限写为com.example.app.provider,路径为要查的表名所以标准写法为:

content://com.example.app.provider/table1
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
query()方法对应SQL部分描述
urifrom table_name指定查询某个应用下的某一张表
projectionselect column,column2指定查询的列名
selectionwhere column=value指定where的约束条件
selectionArgs-为where中的占位符提供具体的值
orderByorder by column1,column2指定查询结果的排序方式
    if(cursor!=null){
        while(cursor.moveToNext()){
            String column1 = cur.getString(cursor.getColumnIndex("column1"));
            int column2 = cursor.getInt(cursor.getColumnIndex("column2"));
        }
        //关闭索引
        cursor.close();
    }

添加数据

    ContentValues values = new ContentValues();
    values.put("column1","text");
    values.put("column2",1);
    getContentResolver().insert(uri,values);

修改数据

    ContentValues values = new ContentValues();
    vallues.put("column1","");
    getContentResolver().update(uri,values,"column1 = ? and column2 = ?",new String[]{"text","1"});

删除数据

    getContentResolver().delete(uri,"column2 = ?",new String[]{"1"});

读取联系人

添加权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>

"*********************主布局文件为Listview************************"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <ListView
    //ListView的id,便于在java文件下寻找
        android:id="@+id/contacts_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
         />

</LinearLayout>
"*********************主方法*********************"
import android.support.v7.app.ActionBarActivity;

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

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
    ListView contactsView;
    // 添加适配器
    ArrayAdapter<String> adapter;
    // 定义一个联系人的集合
    List<String> contactsList = new ArrayList<String>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contactsView = (ListView) findViewById(R.id.contacts_view);
        //适配器的设置
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
        //安装好适配器
        contactsView.setAdapter(adapter);
        readContacts();
    }

    private void readContacts() {
        Cursor cursor = null;
        try {
        //ContactsContract.CommonDataKinds.Phone.CONTENT_URI是一个常量,这个常量就是Uri.parse()方法解析出来的,下面的那两个也是同样的意思
            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对象关闭
                cursor.close();
            }
        }
    }

}

创建自己的内容提供者

uri的写法

    content://com.example.app.provider/table1
                "包名"    "内容提供者标志"   "表名"
    *:表示匹配任意长度的字符,因此匹配任意表内容的URI为
    content://com.example.app.provider/*
    #:表示匹配任意长度的数字,一次匹配一个表中任意一行数据内容的uri可以写为
    content://com.example.app.provider/table1/#

MIME在android中的规定

    1.必须以vnd开头
    2.如果内容以URI以路径结尾,则后面跟android.cursor.dir/,如果内容URI以id结尾,则后面接android.cursor.item/
    3.最后接上vnd.<authority>.<path>
    例如1:对于content://com.example.app.provider/table1
    对应MIME:vnd.android.cursor.dir/vnd.com.example.app.provider.table1
    例如2:对于content://com.example.app.provider/table1
MIME:vnd.android.cursor.item/vnd.com.example.app.provider.table1

下面要用到的辅助类

    package com.example.databaseandroid;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;


    public class MyDatabaseeHelper extends SQLiteOpenHelper{
        public static final String CREATE_BOOK = "create table book ("+"id integer primary key autoincrement,"
                +"author text," 
                +"price real,"
                +"pages integer,"
                +"name text,"
                //新添加的语句
                +"category_id integer)";
        public static final String CREATE_CATEGORY = "create table category("+
                "id integer primary key autoincrement,"
                +"category_name text,"
                +"category_code integer)";


        public MyDatabaseeHelper(Context context, String name, CursorFactory factory, int version) {
            super(context, name, factory, version);

        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_BOOK);
            db.execSQL(CREATE_CATEGORY);



        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            switch(oldVersion){
            case 1:
                db.execSQL(CREATE_CATEGORY);
            //添加语句
            case 2:
                db.execSQL("alter table Book add column category_id integer");
            default:
            }
        }

    }


1.创建自己的ContentProvider

总体思路,只需要获取到该应用程序的内容URI,然后借助ContentResolver进行增删改查操作。

"********************主要的布局文件**************************"
package com.example.databaseandroid;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
/**
  * 继承ContentProvider来创建自己的内容提供器
  */
public class MyProvider extends ContentProvider{
    public static final int BOOK_DIR = 0;
    public static final int BOOK_ITEM = 1;
    public static final int CATEGORY_DIR = 2;
    public static final int CATEGORY_ITEM = 3;
    public static final String AUTHORITY = "com.example.databaseandroid.provider";
    private MyDatabaseeHelper dbHelper;
    private static UriMatcher uriMatcher;
    /**
     *在静态代码块里对UriMatcher进行了初始化操作,将期望匹配的几种Uri格式添加进去了。
     */
    static{
        //uriMatcher可以轻松的实现匹配内容URI功能
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        //addURI()方法接收三个参数,可以分别把权限、路径和一个自定义的代码传进去。
        uriMatcher.addURI(AUTHORITY,"book",BOOK_DIR);
        uriMatcher.addURI(AUTHORITY,"book/#",BOOK_ITEM);
        uriMatcher.addURI(AUTHORITY,"category",CATEGORY_DIR);
        uriMatcher.addURI(AUTHORITY,"category/#",CATEGORY_ITEM);
    }
    /**
    *初始化内容提供其时使用,只有当ContentResolver尝试访问我们程序中的数据时,内容提供者才会被初始化,初始化成功返回true
    */
    @Override
    public boolean onCreate() {
        //创建数据库,获得数据库的实例
        dbHelper = new MyDatabaseeHelper(getContext(), "BookStore.db", null, 2);
        return true;
    }
    /**
    *从内容提供器查询数据,使用URI参数来确定是哪一张表,projection参数用于指定查询的列,selection和selectionArgs参数用来约束查询的条件,sortOrder指定排序方式,查询结果放在Cursor中。
    */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        //查询数据
        SQLiteDatabase db= dbHelper.getReadableDatabase();
        Cursor cursor = null;
        //当调用match()方法时,可以传入uri,返回自定义的代码
        switch(uriMatcher.match(uri)){
        case BOOK_DIR:
            cursor = db.query("book", projection, selection, selectionArgs, null, null, sortOrder);

            break;
        case BOOK_ITEM:
            String bookId = uri.getPathSegments().get(1);
            cursor = db.query("book", projection, "id = ?", new String[]{bookId}, null, null, sortOrder);
            break;
        case CATEGORY_DIR:
            cursor = db.query("category", projection, selection, selectionArgs, null, null, sortOrder);
            break;
        case CATEGORY_ITEM:
            String categoryId = uri.getPathSegments().get(1);
            cursor = db.query("category", projection, "id = ?", new String[]{categoryId}, null, null, sortOrder);

            break;
        default:
            break;
        }
        return cursor;
    }
    /**
    *根据传入内容的uri来返回相应的MIME类型,这个参数正是调用ContentResolver的增删改查时传递过来的
    */
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)){
        case BOOK_DIR:
            return "vnd.android.cursor.dir/vnd.com.example.databaseandroid.provider.book";
        case BOOK_ITEM:
            return "vnd.android.currsor.item/vnd.com.example.databaseandroid.provider.book";
        case CATEGORY_DIR:
            return "vnd.android.cursor.dir/vnd.com.example.databaseandroid.provider.category";
        case CATEGORY_ITEM:
            return "vnd.android.cursor.item/vnd.com.example.databaseandroid.provider.category";
        }
        return null;
    }
    /**
    *向内容提供器添加一条数据,使用uri找到要添加的表,待添加的数据保存在values中,添加完成后,返回一个用于表示这条新纪录的uri
    */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        //添加数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        switch(uriMatcher.match(uri)){
        case BOOK_DIR:

        case BOOK_ITEM:
            long newBookId = db.insert("book", null, values);
            uriReturn = Uri.parse("content://"+AUTHORITY+"/book/"+newBookId);

            break;
        case CATEGORY_DIR:
        case CATEGORY_ITEM:
            long newCategoryId = db.insert("category", null, values);
            uriReturn = Uri.parse("content://"+AUTHORITY+"/category/"+newCategoryId);

            break;
        default:
            break;
        }
        return uriReturn;
    }
    /**
     * 删除数据,被删除的哪一行将作为返回值返回。
     */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch(uriMatcher.match(uri)){
        case BOOK_DIR:
            deletedRows = db.delete("book", selection, selectionArgs);

            break;
        case BOOK_ITEM:
            String bookId = uri.getPathSegments().get(1);
            deletedRows = db.delete("book", "id = ?", new String[]{bookId});
            break;
        case CATEGORY_DIR:
            deletedRows = db.delete("category", selection, selectionArgs);

            break;
        case CATEGORY_ITEM:
            String categoryId = uri.getPathSegments().get(1);
            deletedRows = db.delete("category", "id = ?", new String[]{categoryId});
            break;
        default:
            break;

        }
        return deletedRows;
    }
    /**
     * 使用uri参数来确定更新哪一张表中的数据,新数据保存在values参数中,selection和selectionArgs参数用于约束更新哪一行,受影响的行数将作为返回值返回。
     */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows =0;
        switch(uriMatcher.match(uri)){
        case BOOK_DIR:
            updatedRows = db.update("book", values, selection, selectionArgs);

            break;
        case BOOK_ITEM:
            String bookId = uri.getPathSegments().get(1);
            updatedRows = db.update("book", values, "id = ?", new String[]{bookId});

            break;
        case CATEGORY_DIR:
            updatedRows = db.update("category", values, selection, selectionArgs);
            break;
        case CATEGORY_ITEM:
            String categoryId = uri.getPathSegments().get(1);
            updatedRows = db.update("category", values, "id = ?", new String[]{categoryId});
            break;
        default:
            break;
        }
        return updatedRows;
    }

}
"***************必须要在内容提供者的应用中添加权限***************"
//MyProvider为上面所写的类名,前面为包名。
 <provider
            android:name="com.example.databaseandroid.MyProvider"

            android:authorities="com.example.databaseandroid.provider" >
        </provider>

在其他应用中访问上一个应用的数据

"************************布局文件************************"
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
   >

    <Button
        android:id="@+id/add_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Add to book" />
    <Button
        android:id="@+id/query_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Query From Book" />

    <Button
        android:id="@+id/update_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Updata Book" />

    <Button
        android:id="@+id/delete_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Delete From book" />
    <TextView 
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</LinearLayout>

"*********************主要的活动文件***********************"
package com.test.dukang;

import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
    private String newId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button addData = (Button) findViewById(R.id.add_data);
        addData.setOnClickListener(this);

        Button queryData = (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(this);

        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(this);

        Button deleteData = (Button) findViewById(R.id.delete_data);
        deleteData.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.add_data:
            Uri uri = Uri.parse("content://com.example.databaseandroid.provider/book");
            ContentValues values = new ContentValues();
            values.put("name", "A Clash of Kings");
            values.put("author", "Gerge Martin");
            values.put("pages", 1040);
            values.put("price", 22.85);
            Uri newUri = getContentResolver().insert(uri, values);
            newId = newUri.getPathSegments().get(1);
            break;
        case R.id.query_data:
            Uri quri = Uri.parse("content://com.example.databaseandroid.provider/book");
            Cursor cursor = getContentResolver().query(quri, null, null, null, null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    String author = cursor.getString(cursor.getColumnIndex("author"));
                    int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                    double price = cursor.getDouble(cursor.getColumnIndex("price"));
                    System.out.println("你好");
                    Log.d("MainAcivity", name);
                    Log.d("MainAcivity", author);
                    Log.d("MainAcivity", ""+pages);
                    Log.d("MainAcivity", ""+price);
                }
                cursor.close();
            }
            break;
        case R.id.update_data:
            Uri uuri = Uri.parse("content://com.example.databaseandroid.provider/book/" + newId);
            ContentValues valuesUpdate = new ContentValues();
            valuesUpdate.put("name", "A Storm of Swords");
            valuesUpdate.put("pages", 1216);
            valuesUpdate.put("price", 24.05);
            getContentResolver().update(uuri, valuesUpdate, null, null);
            break;
        case R.id.delete_data:
            Uri uriDelete=Uri.parse("content://com.example.databaseandroid.provider/book/"+newId);
            getContentResolver().delete(uriDelete, null, null);

            break;
        }

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值