实例:使用ContentProvider共享生词本数据

  1. 配置ContentProvider

只要为<application…/>元素添加<provider…/>子元素即可配置ContentProvider

<provider
            android:authorities="com.myapplication.dictprovider"
            android:name=".DictProvider"
            android:exported="true"/>
  1. 定义工具类

在工具类中定义一些简单的常量,告诉其他应用程序,访问该ContentProvider的一些常用入口
Words.java

import android.net.Uri;
import android.provider.BaseColumns;

public final class Words {
    //定义该ContentProvider的Authorities
    public static final String AUTHORITY = "com.myapplication.dictprovider";

    //定义一个静态类,定义该ContentProvider所包含数据列的列名
    public static final class Word implements BaseColumns {
        //定义Content所允许操作的三个数据列
        public final static String _ID = "_id";
        public final static String WORD = "word";
        public final static String DETAIL = "detail";
        //定义该Content提供服务的两个uri
        public final static Uri DICT_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/words");
        public final static Uri WORD_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/word");
    }
}
  1. 开发ContentProvider子类

重写其中的增、删、改、查等方法
DictProcider.java

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class DictProvider extends ContentProvider {
    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    private static final int WORDS = 1;
    private static final int WORD = 2;
    private MyDatabaseHelper dbOpenHelper;

    static {
        //为UriMatcher注册两个Uri
        matcher.addURI(Words.AUTHORITY, "words", WORDS);
        matcher.addURI(Words.AUTHORITY, "word/#", WORD);
    }

    @Override
    public boolean onCreate() {
        dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1);
        return true;
    }

    //执行查询方法,该方法返回查询得到的cursor的值
    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        switch (matcher.match(uri)) {
            //如果URI参数代表操作全部数据项
            case WORDS:
                //执行查询
                return db.query("dict", projection, selection, selectionArgs, null, null, sortOrder);
            //如果uri参数代表操作指定数据项
            case WORD:
                //解析出想查询的记录ID
                long id = ContentUris.parseId(uri);
                String whereClause = Words.Word._ID + "=" + id;
                //如果原来的where子句存在,拼接where子句
                if (selection != null && !"".equals(selection)) {
                    whereClause = whereClause + "and" + selection;
                }
                return db.query("dict", projection, whereClause, selectionArgs, null, null, sortOrder);
            default:
                try {
                    throw new IllegalAccessException("未知uri:" + uri);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

    @Nullable
    //该方法的返回值代表了该contentProvider所提供数据的MIME类型
    @Override
    public String getType(@NonNull Uri uri) {
        switch (matcher.match(uri)) {
            //如果操作的数据为多项记录
            case WORDS:
                return "vnd:android.cursor.dir/org.crazyit.dict";
            //如果操作的数据为单项记录
            case WORD:
                return "vnd:android.cursor.item/org.crazyit.dict";
            default:
                try {
                    throw new IllegalAccessException("未知URI:" + uri);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

    //实现插入的方法,该方法返回新插入的记录的uri
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        //获得数据库实例
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        switch (matcher.match(uri)) {
            case WORDS:
                long rowId = db.insert("dict", Words.Word._ID, values);
                //如果成功插入返回uri
                if (rowId > 0) {
                    //在已有的uri后面追加id
                    Uri wordUri = ContentUris.withAppendedId(uri, rowId);
                    //通知数据已经改变
                    getContext().getContentResolver().notifyChange(wordUri, null);
                    return wordUri;
                }
                break;
            default:
                try {
                    throw new IllegalAccessException("未知URI:" + uri);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
        }
        return null;
    }

    //实现删除方法,该方法返回被删除的记录条数
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        //记录删除的数据行数
        int num = 0;
        switch (matcher.match(uri)) {
            case WORDS:
                num = db.delete("dict", selection, selectionArgs);
                break;
            case WORD:
                long id = ContentUris.parseId(uri);
                String whereClause = Words.Word._ID + "=" + id;
                //如果原来的where子句存在,拼接where子句
                if (selection != null && !"".equals(selection)) {
                    whereClause = whereClause + "and" + selection;
                }
                num = db.delete("dict", whereClause, selectionArgs);
                break;
            default:
                try {
                    throw new IllegalAccessException("未知URI:" + uri);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return num;
    }

    //实现更新方法,该方法应该返回被更新的记录条数
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
        SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
        //记录修改的数据数
        int num = 0;
        switch (matcher.match(uri)) {
            case WORDS:
                num = db.update("dict", values, selection, selectionArgs);
                break;
            case WORD:
                long id = ContentUris.parseId(uri);
                String whereClause = Words.Word._ID + "=" + id;
                //如果原来的where子句存在,拼接where子句
                if (selection != null && !"".equals(selection)) {
                    whereClause = whereClause + "and" + selection;
                }
                num = db.update("dict", values, whereClause, selectionArgs);
                break;
            default:
                try {
                    throw new IllegalAccessException("未知URI:" + uri);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
        }
        //通知数据已经改变
        getContext().getContentResolver().notifyChange(uri, null);
        return num;
    }
}
  1. 通过ContentResolver来操作生词本中的数据

DictResolver.java

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class DictResolver extends Activity {
    ContentResolver contentResolver;
    Button insert=null;
    Button search=null;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dict);
        contentResolver=getContentResolver();
        insert=(Button) findViewById(R.id.insert);
        search=(Button) findViewById(R.id.search);
        insert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String word=((EditText)findViewById(R.id.word)).getText().toString();
                String detail=((EditText)findViewById(R.id.detail)).getText().toString();
                //插入生词记录
                ContentValues values=new ContentValues();
                values.put(Words.Word.WORD,word);
                values.put(Words.Word.DETAIL,detail);
                contentResolver.insert(Words.Word.DICT_CONTENT_URI,values);
                //显示提示信息
                Toast.makeText(DictResolver.this,"添加生词成功",Toast.LENGTH_SHORT).show();
            }
        });
        search.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String key=((EditText)findViewById(R.id.key)).getText().toString();
                //执行查询
                Cursor cursor=contentResolver.query(Words.Word.DICT_CONTENT_URI,null,"word like ? or detail like ?",new String[]{"%"+key+"%","%"+key+"%"},null);
                Bundle bundle=new Bundle();
                bundle.putSerializable("data",convertCursorToList(cursor));
                //创建一个Intent
                Intent intent=new Intent(DictResolver.this,ResultActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }
    private ArrayList<Map<String,String>> convertCursorToList(Cursor cursor){
        ArrayList<Map<String,String>> result=new ArrayList<>();
        while (cursor.moveToNext()){
            //将结果集中的数据存入ArrayList中
            Map<String,String> map=new HashMap<>();
            map.put(Words.Word.WORD,cursor.getString(1));
            map.put(Words.Word.DETAIL,cursor.getString(2));
            result.add(map);
        }
        return result;
    }
}
  1. 配置文件

dict.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/word"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/detail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/insert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="插入" />

    <EditText
        android:id="@+id/key"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/search"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="查询" />
</LinearLayout>

result.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/show"/>
</LinearLayout>

line.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/my_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <EditText
        android:id="@+id/my_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值