Android内容提供器

目标:A程序提供外部访问接口
B程序通过这个接口来访问A程序上面的数据(增删查改)
因为所有的增删查改操作都是需要匹配到想的内容URI格式才能进行的,而我们在写接口的时候自然不会在其添加隐私数据,所以这部分数据无法被外部程序访问到。
下面上实例(A程序)
1、新建类去继承ContentProvider来创建一个自己的内容提供器,ContentProvider中有6个抽象方法,我们在使用子类集成的时候需要重写这6个方法,在A程序新建DatabaseProvider继承自ContentProvider:
2、借助UriMatcher这个类实现匹配内容URI的功能。
3、getType()这个方法比较陌生,该方法用于获取URI对象所对应的MIME类型。
4、AndroidManifest中添加provider

<provider
            android:authorities="com.superxingyun.mydatabasehelper.provider"
            android:name="com.superxingyun.mydatabasehelper.DatabaseProvider"
            android:exported="true"/>

DatabaseProvider.class:

package com.superxingyun.mydatabasehelper;

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.Nullable;

/*
 * Created by 月满轩尼诗 on 2016/10/21.
 */

public class DatabaseProvider 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.superxingyun.mydatabasehelper.provider";

    private  static UriMatcher uriMatcher;
    private MyDatabaseHelper dbHelper;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
        uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
        uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR);
        uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new MyDatabaseHelper(getContext(), "BookStore,db", null, 2);
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
        //查询数据
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                cursor = db.query("Book", strings, s, strings1, null, null, s1);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                cursor = db.query("Book", strings1, "id = ?", new String[]{bookId}, null, null, s1);
                break;
            case CATEGORY_DIR:
                cursor = db.query("Category", strings, s, strings1, null, null, s1);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                cursor = db.query("Category", strings, "id = ?", new String[] { categoryId }, null, null, s1);
                break;
        }
        return cursor;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                return "vnd.android.cursor.dir/vnd.com.superxingyun.mydatabasehelper.provider.book";
            case BOOK_ITEM:
                return "vnd.android.cursor.item/vnd.com.superxingyun.mydatabasehelper.provider.book";
            case CATEGORY_DIR:
                return "vnd.android.cursor.dir/vnd.com.superxingyun.mydatabasehelper.provider.category";
            case CATEGORY_ITEM:
                return "vnd.android.cursor.item/vnd.com.superxingyun.mydatabasehelper.provider.category";
        }

        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        //添加数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uri1 = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
            case BOOK_ITEM:
                long newBookId = db.insert("Book", null, contentValues);
                uri1 = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
                break;

            case CATEGORY_DIR:
            case CATEGORY_ITEM:
                long newCategoryId = db.insert("Category", null, contentValues);
                uri1 = Uri.parse("content://" + AUTHORITY + "/category/" +newCategoryId);
                break;
            default:
                break;
        }
        return uri1;
    }

    @Override
    public int delete(Uri uri, String s, String[] strings) {
        //删除数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                deletedRows = db.delete("Book", s, strings);
                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", s, strings);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                deletedRows = db.delete("Category", "id = ?", new String[] { categoryId });
                break;
            default:
                break;
        }

        return deletedRows;
    }

    @Override
    public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
        //更新数据
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                updatedRows = db.update("Book", contentValues, s, strings);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                updatedRows = db.update("Book", contentValues, "id = ?", new String[] { bookId });
                break;
            case CATEGORY_DIR:
                updatedRows = db.update("Category", contentValues, s ,strings);
                break;
            case CATEGORY_ITEM:
                String categoryId = uri.getPathSegments().get(1);
                updatedRows = db.update("Category", contentValues, "id = ?", new String[] { categoryId });
                break;
        }

        return updatedRows;
    }
}

B程序:
MainActivity.class:

package com.superxingyun.providertest;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    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(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //添加数据
                Uri uri = Uri.parse("content://com.superxingyun.mydatabasehelper.provider/book");
                ContentValues values = new ContentValues();
                values.put("name", "A Clash of Kings");
                values.put("author", "George Martin");
                values.put("pages", 1040);
                values.put("price", 22.85);
                Uri newUri = getContentResolver().insert(uri, values);
                newId = newUri.getPathSegments().get(1);
            }
        });
        Button queryData = (Button) findViewById(R.id.query_data);
        queryData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //查询数据
                Uri uri = Uri.parse("content://com.superxingyun.mydatabasehelper.provider/book");
                Cursor cursor = getContentResolver().query(uri, 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"));
                        Log.d("MainActivity", "book name is:" + name);
                        Log.d("MainActivity", "book author is:" + author);
                        Log.d("MainActivity", "book pages is:" + pages);
                        Log.d("MainActivity", "book price is:" + price);
                    }
                    //关闭游标
                    cursor.close();
                }
            }
        });
        Button updateData = (Button) findViewById(R.id.update_data);
        updateData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //更新数据
                Uri uri = Uri.parse("content://com.superxingyun.mydatabasehelper.provider/book/" + newId);
                ContentValues values = new ContentValues();
                values.put("name", "A Storm of Swords");
                values.put("pages", 1216);
                values.put("price", 24.05);
                getContentResolver().update(uri, values, null, null);
            }
        });
        Button deleteData = (Button) findViewById(R.id.deldet_data);
        deleteData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //删除数据
                Uri uri = Uri.parse("content://com.superxingyun.mydatabasehelper.provider/book/" + newId);
                getContentResolver().delete(uri, null, null);
            }
        });
    }
}

界面是4个按钮,分别是对之前A程序的数据进行增删查改,每个按钮的逻辑也在代码里面了。下面运行,程序B(在此之前需要将程序A在模拟器上先删除,以免残留数据造成干扰,但是记得在运行一下A程序,不然手机上没有A程序,B在访问接口的时候会报错,当时我就遇到了这个问题)。点击add按钮时,回想book表中添加一行数据,此时在点击query按钮就会将数据打印出来
这里写图片描述
然后我们再次点击update按钮,在点击查询,发现出具发生了变化,说明更新数据也完成了
这里写图片描述
最后,点击delete这一条数据就会被删除,点击查询也不会出现任何内容,这里有同学或许会有疑惑,是如何知道是哪一条数据呢,会不会删除所有的数据呀,其实在开始的时候我们定义了一个newId这个字符串常量再做更新、删除数据操作时有指定。在插入数据时newId = newUri.getPathSegments().get(1);,因为insert方法会返回一个Uri对象,这个对象中包含了刚刚增加的这条数据的id然后通过这个方法给他取出来,在之后的内容URI
Uri uri = Uri.parse(“content://com.superxingyun.mydatabasehelper.provider/book/” + newId);
后面的尾部添加了一个id,二这个id正是我们添加数据的时候返回的那一条数据所对应的 id,因为有了这个所有更新和删除就只有这一条数据受到影响,book表中其他的数据不会受到影响。
现在,任何一个程序都可以访问我们A程序中的数据了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值