Android组件之contentProvider

先上文档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-permission
android: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代表无
            }
        }
    }
}

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

猜你喜欢

转载自blog.csdn.net/qq_37657081/article/details/78532006
今日推荐