使用 自定义的 ContentProvider 进行应用间的数据交互(另一个APP对当前的应用数据进行修改,查询),getType()等内容的讲解

本博客内容

应用B 对 应用A的数据库数据进行插入和查询(其他操作简略不写)

bookProject 应用A

看一下目录结构

在这里插入图片描述

Book_TABLE.java

  • 关键点:private static final String BOOK_DB = "create table Book(id integer primary key autoincrement ,author text) ";
  • 这里面的 id 必须写
Book_TABLE extends SQLiteOpenHelper
// 创建表 此处内容省略

MainActivity.java

... //此处内容省略,添加一些数据到数据库就OK

MyProvider.java 代码中有注释。此代码部分结束后还有解释

public class MyProvider extends ContentProvider {

    public static final int BOOK_TABLE_DIR = 0;        // 判断 另一个应用的行为 是查询全部数据
    public static final int BOOK_TABLE_ITEM = 1;    //// 判断 另一个应用的行为 是查询单条

    private static UriMatcher uriMatcher;              // 进行 匹配工作 的类工具

// 静态代码块 
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.tnt.bookproject", "Book", BOOK_TABLE_DIR); // 要匹配 book 下所有的数据 == table1/*
        uriMatcher.addURI("com.example.tnt.bookproject", "Book/#", BOOK_TABLE_ITEM); // 要匹配 book 下任意一行的数据
    }

    private Book_TABLE book_table;
    private SQLiteDatabase db;

    // 初始化 内容提供器时启动, true 表示成功 false 表示失败 。
    @Override
    public boolean onCreate() {
        book_table = new Book_TABLE(getContext());
        db = book_table.getWritableDatabase();
        return true;
    }


    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_TABLE_DIR:
                // 查询 table1 下所有数据
                cursor = db.query("Book", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case BOOK_TABLE_ITEM:
                //查询 table1 下某条数据
                String book_ID = uri.getPathSegments().get(1); // 将权限之后的内容部分已 “/” 进行分割,0位置放 路径 ,1 位置放 id 了
                cursor = db.query("Book", projection, "id=?", new String[]{book_ID}, null, null, sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

  // 所有内容提供器都必须提供的方法,用于获取 Uri 对象对应的 MIME 类型。怎么写,下面是示例,此代码部分结束后,有讲解
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case BOOK_TABLE_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.tnt.bookproject.Book";
            case BOOK_TABLE_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.tnt.bookproject.Book";
        }
        return null;
    }


    // 插入成功后需返回一个 Uri 用于提示插入的 位置
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        Uri newUri;
        long newId =  db.insert("Book",null,values);
        newUri = Uri.parse("content://com.example.tnt.bookproject/Book/"+newId);
        return newUri;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }
}

关于 MyProvider 的内容讲解

  • getPathSegments() 方法 // 将 内容URI 权限之后的内容部分以 “/” 进行分割,放入一个数组里,0位置放 路径 ,1 位置放 id 了,在通过 selection 和 selectionArgs 参数进行约束就实现了查询单条数据功能
  • Uri.parse() 方法将 内容URI 解析成 Uri 对象
  • 务必实现 getType()里的操作
    实现方法
一个内容 URI 对应的 MIME 字符串主要有 3 部分组成。Android 对着 3 部分做了如下格式规定。
 1. 必须以 vnd 开头
 2. 如果内容 URI 以 路径结尾,则接 android.cursor.dir/ ,如果以 id 结尾,则接 andriod.cursor.item/ 
 3. 最后 接上 vnd.<authority>.path
 -  所以对于 content://com.example.tnt.bookproject/Book  这个内容URI,它所对应的 MIME 类型 就可以写成:
    vnd.android.cursor.dir/vnd.com.example.tnt.bookproject.Book 
 - 所以对于 content://com.example.tnt.bookproject/Book/1  这个内容URI,它所对应的 MIME 类型 就可以写成:
    vnd.android.cursor.item/vnd.com.example.tnt.bookproject.Book 

注册 AndroidManifest.xml

android:enabled //启用此内容提供器
android:exported=“true” // 外部应用可以使用此内容提供器

       <provider
            android:enabled="true"    
            android:exported="true"
            android:authorities="com.example.tnt.bookproject"
            android:name=".MyProvider"/>

OperatorProject 应用B (来操作 bookProject 的内容)

MainActivity.java (只实现了 插入和 查询操作)

   public void insertInfo(View view) {
        // 添加数据
        Uri uri = Uri.parse("content://com.example.tnt.bookproject/Book");
        
        ContentValues cv = new ContentValues();
        cv.put("author", "诸葛亮");
        
        Uri newUri = getContentResolver().insert(uri, cv); // ContentResolver 我理解的就是 ContentProvider 的应用之间沟通的桥梁
        String newID = newUri.getPathSegments().get(1);  // 获取插入数据后,表 生成的 id 位置。// 在定义表 Book 时,id 设置成了 自增
        
        Log.i(TAG, "insertInfo: " + newID);
    }

    public void queryInfo(View view) {
        // 查询数据
        Uri uri = Uri.parse("content://com.example.tnt.bookproject/Book");
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                Log.i(TAG, "queryInfo:查到的作者 " + cursor.getString(cursor.getColumnIndex("author")));
                Log.i(TAG, "queryInfo: 作者ID " + cursor.getString(cursor.getColumnIndex("id")));
            }
            cursor.close();
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_38340601/article/details/83240281