Android组件之contentProvider

来源:互联网 发布:app推荐软件 编辑:程序博客网 时间:2024/05/29 04:51

先上文档contentProvider

啥都不说,我们先到文档中查看
文档大致是这么说的:

ContentProvider是android应用程序的构建基础之一,它们封装数据并通过单一的ContentResolver接口提供给应用程序,如果你想要在多个应用程序之间共享数据,ContentProvider是必须需要的,例如,联系人数据由多个应用程序使用,必须存储在内容提供者中。如果不需要在多个应用程序之间共享数据,那么可以通过SQLiteDatabase直接使用数据库
当请求通过ContentResolver完成时,系统将检查给定URI的权限,并将请求传递给在权限内注册的内容提供者。内容提供程序可以解释它想要的其他URI。UriMatcher类有助于解析uri。
在使用ContentProvider时,我们需要继承一下几个方法
1. onCreate()
2.query(Uri, String[], String, String[], String)
3.insert(Uri, ContentValues)
4update(Uri, ContentValues, String, String[])
5.delete(Uri, String, String[])
6.getType(Uri)

ps:数据访问方法(如insert(Uri,ContentValues)和 update(Uri,ContentValues,String,String[]))可以同时从多个线程调用,而且必须是线程安全的
oncreate()方法必须在主线程中被调用

下面我们一个一个搞他们
1.oncreate()
在这里我们对ContentProvider进行初始化,在这里我们不能执行耗时操作,如果我们使用数据库,通常在这里我们使用DatabaseHelper来创建数据库的帮助类,成功返回true
2.query()
在这我们去处理客户端发送的请求命令。
3.insert()
处理插入请求,在调用之后,需要调用notifyChange()通知数据更改
4.update()
处理更新请求,通过selection和selectArgs参数约束更新行,需要调用notifyChange()通知数据更改
5.delete()
处理删除请求,通过selection和selectArgs参数约束更新行,需要调用notifyChange()通知数据更改
6.getType()
用于获取Uri对象所对应的MIME类型,一个内容Uri所对应的MIME字符串有以下三部分组成
1.必须以vnd开头
2如果内容Uri以路径结尾,最后接android.curosr.dir/,如果以id结尾,
最后接android.cursor.item/
3之后接上vnd.< authority>.< path>
所以,对于contnent://com.example.myapplication/table1
这个Uri就可以写成 vnd.android.curosr.dir/vnd.com.example.myapplication.table1
对于contnent://com.example.myapplication/table1/1就可以写成
vnd.android.cursor.item/vnd.com.example.myapplicaion.table1

现在我们来具体实现一下
创建数据库帮助类

package com.example.myapplication;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;/** * Created by fang on 2017/11/13. */public class MyDatabaseHelper extends SQLiteOpenHelper {    String create="create table book(id integer primary key autoincrement,name text,price real,author text)";    public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL(create);    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}

创建ContentProvider

package com.example.myapplication;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;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.util.Log;/** * Created by fang on 2017/11/13. */public class MyContentProvider extends ContentProvider {    String TAG = "TAG";    MyDatabaseHelper helper;    public static UriMatcher uriMatcher;    public static final int BOOK_DIR = 0;    public static final int BOOK_ITEM = 1;    public static final String AUTHORITY = "com.example.myapplication";    static {        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);        uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);        uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);    }    @Override    public boolean onCreate() {        helper = new MyDatabaseHelper(getContext(), "bookStore.db", null, 1);        return true;    }    @Nullable    @Override    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {        SQLiteDatabase database = helper.getReadableDatabase();        Cursor cursor = null;        switch (uriMatcher.match(uri)) {            case BOOK_DIR: {                cursor = database.query("book", projection, selection, selectionArgs, null, null, sortOrder);                break;            }            case BOOK_ITEM: {                String id = uri.getPathSegments().get(1);                //getPathSegments()返回的是将Path部分的内容按照"/"分割并转成List集合,get(1)返回ID                Log.d(TAG, "id=" + id + "    path=" + uri.getPathSegments().get(0));                cursor = database.query("book", projection, "id=?", new String[]{id}, null, null, sortOrder);                break;            }        }        return cursor;    }    @Nullable    @Override    public String getType(@NonNull Uri uri) {        switch (uriMatcher.match(uri)) {            case BOOK_DIR: {                return "vnd.android.cursor.dir/vnd.com.example.myapplication.book";            }            case BOOK_ITEM: {                return "vnd.android.cursor.item/vnd.com.example.myapplication.book";            }        }        return null;    }    /**     * c插入数据,并不需要ID,同一张表,一次插入就行     *     * @param uri     * @param values     * @return     */    @Nullable    @Override    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {        SQLiteDatabase database = helper.getWritableDatabase();        Uri uriId = null;        switch (uriMatcher.match(uri)) {            case BOOK_DIR:            case BOOK_ITEM:                long newbookId = database.insert("book", null, values);                uriId = Uri.parse("content://" + AUTHORITY + "/book/" + newbookId);                break;        }        return uriId;    }    @Override    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {        SQLiteDatabase database = helper.getWritableDatabase();        int row = 0;        switch (uriMatcher.match(uri)) {            case BOOK_DIR: {                row = database.delete("book", selection, selectionArgs);                break;            }            case BOOK_ITEM: {                String bookid = uri.getPathSegments().get(1);                row = database.delete("book", "id=?", new String[]{bookid});                break;            }        }        return row;    }    @Override    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {        SQLiteDatabase database = helper.getWritableDatabase();        int row = 0;        switch (uriMatcher.match(uri)) {            case BOOK_DIR: {                database.update("book", values, selection, selectionArgs);                break;            }            case BOOK_ITEM: {                String id = uri.getPathSegments().get(1);                database.update("book", values, "id=?", new String[]{id});                break;            }        }        return row;    }}

Avtivity

package com.example.myapplication;import android.content.ContentResolver;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    Button delete;    Button query;    Button insert;    Button update;    String path = "content://com.example.myapplication";    String TAG = "TAG";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        delete = (Button) findViewById(R.id.delete);        query = (Button) findViewById(R.id.query);        insert = (Button) findViewById(R.id.insert);        update = (Button) findViewById(R.id.update);        delete.setOnClickListener(this);        query.setOnClickListener(this);        insert.setOnClickListener(this);        update.setOnClickListener(this);    }    @Override    public void onClick(View v) {        if (v == delete) {            int newId = 0;            getContentResolver().delete(Uri.parse(path+"/book/"+newId),null,null);        }        if (v == query) {            Cursor cursor = getContentResolver().query(Uri.parse(path + "/book"), 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 price = cursor.getInt(cursor.getColumnIndex("price"));                    Log.d(TAG, "name=" + name);                    Log.d(TAG, "author" + author);                    Log.d(TAG, "price" + price);                    Log.d(TAG, "=======================");                }            }        }        if (v == insert) {            //create table book(id integer primary key autoincrement,name text,price real,author text            ContentValues contentValues = new ContentValues();            contentValues.put("name", "第一行代码");            contentValues.put("price", 50);            contentValues.put("author", "郭霖");            getContentResolver().insert(Uri.parse(path + "/book"), contentValues);            ContentValues contentValues1 = new ContentValues();            contentValues1.put("name", "Effective java");            contentValues1.put("price", 40);            contentValues1.put("author", "Joshua Bloch");            getContentResolver().insert(Uri.parse(path + "/book"), contentValues1);        }        if (v == update) {            int newID = 2;            ContentValues contentValues1 = new ContentValues();            contentValues1.put("name", "JAVA编程思想");            contentValues1.put("price", 89);            contentValues1.put("author", "Bruce Eckel");            getContentResolver().update(Uri.parse(path + "/book/" + newID), contentValues1, null, null);        }    }}

主布局

<?xml version="1.0" encoding="utf-8"?><LinearLayout 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:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.example.myapplication.MainActivity">    <Button        android:id="@+id/delete"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="delete" />    <Button        android:id="@+id/query"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="query" />    <Button        android:id="@+id/insert"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="insert" />    <Button        android:id="@+id/update"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="update" /></LinearLayout>

现在我们就创建了一个自己的内容提供者
一般来说我们不会将数据暴露出去,相反我们却需要系统提供给我们提供数据,这时候我们就需要知道系统常见的查询条件
在下面我们列出一些

电话联系人:
Uri: ContactsContract.Contacts.CONTENT_URI
String[] columns={“_id”,”display_name”,”has_phone_number”};
不知道固列的。可以使用Contact点出来,就是一堆常量

Uri:ContactsContract.CommonDataKinds.Phone.CONTENT_URI
String[] phone_cols={ContactsContract.CommonDataKinds.Phone.NUMBER,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID
};
使用CommonDataKinds点出来

图片:
Uri:MediaStore.Images.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA};

音频:
Uri:MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.SIZE};

视频:
Uri:MediaStore.Video.Media.EXTERNAL_CONTENT_URI
String str[] = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATA};

短信:
Uri:(Uri.parse(“content://sms/”)
String[] cols={“address”,”type”,”body”,”date”};

通话记录:
Uri:CallLog.Calls.CONTENT_URI
String[] cols={
CallLog.Calls.NUMBER,//电话号码
CallLog.Calls.CACHED_NAME,//联系人名
CallLog.Calls.TYPE,//通话类型:1:已接,2:已拨,3:未接
CallLog.Calls.DATE,//通话日期时间
CallLog.Calls.DURATION//通话时长
};

常用的系统权限<uses-permission android:name="android.permission.INTERNET"/>访问网络<uses-permission android:name="android.permission.CALL_PHONE"/>   拨打电话<uses-permission android:name="android.permission.SEND_SMS"/>发送信息<uses-permission android:name="android.permission.READ_CONTACTS"/>读取联系人<uses-permission android:name="android.permission.READ_SMS"/>读取信息 <uses-permission android:name="android.permission.RECORD_AUDIO"/>录制声音<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>读取手机状态<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 对外存进行读写

下面我们进行演示部分上面的操作

package com.example.fang.myapplication;import android.database.Cursor;import android.provider.ContactsContract;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    Button button;    String TAG = "TAG";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        button = (Button) findViewById(R.id.select);        button.setOnClickListener(this);    }    @Override    public void onClick(View v) {        String[] column = {"_id", "display_name", "has_phone_number"};//查询联系人        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, column, null, null, null);        if (cursor != null) {            while (cursor.moveToNext()) {                Log.d(TAG, "id-----------------------" + cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts._ID)));                Log.d(TAG, "display_name-------------" + cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));                Log.d(TAG, "has_phone_number---------" + cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)));//代表有没有号码1代表有0代表无            }        }    }}

这里写图片描述
其他的查询也一样,就不演示了,上面是一些基本的常量,直接用就是了

原创粉丝点击