ContentProvider内容提供者,跨进程访问方式

ContentProvider内容提供者,跨进程访问方式

我们都知道ContentProvider为四大组件之一,平时也很少使用它,也就访问通讯录的时候对它进行操作,最近出了一个需求,就是要自定义ContentProvider,我们写的一个sdk1要供sdk2调用它的一些信息,这个时候咋整呢?sdk存储信息在本地,然后sdk2用ContentProvider去访问就好:

第一步:在AndroidManifest里面吧你的继承ContentProvider的类注册一下,如下:这里写图片描述

第二步:AutonomicContentProvider extends ContentProvider,吧这个类写好,如下:

package com.robot.zhangyun.myapplication;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
/**
 * Created by Tumbler on 2016/9/22.
 */
public class AutonomicContentProvider extends ContentProvider {

    private static final String AUTONMIC_CONTENTPROVIDER_NAME="com.efrobot.provider.autonomic";
    //你在其他地方用provider的时候要传uri,就是这个,content://是固定的,AUTONMIC_CONTENTPROVIDER_NAME随便写,一般写包名,"/scene"是表名
     static final Uri CONTENT_URI=Uri.parse("content://"+AUTONMIC_CONTENTPROVIDER_NAME+"/scene");
    static final String _ID="_id";//表字段主键id

    private SQLiteDatabase sqLiteDatabase;
    private final String DATEBASE_NAME="autonomic"; //数据库的名字
    private final int DATEBASE_VERSION=1; //数据库版本

    static final int Scene = 1; //匹配用的,看gettype()方法
    static final int Scene_ID = 2;

    private static final UriMatcher uriMatcher;
    static{ //这个是用来匹配uri的,当我们用provider增删改查的时候,会传个uri,好像就是匹配这里的,scene是表名,随便写会报错
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTONMIC_CONTENTPROVIDER_NAME, "scene", Scene);//多个场景的url
        uriMatcher.addURI(AUTONMIC_CONTENTPROVIDER_NAME, "scene/#", Scene_ID);//某个场景
    }
   // 当provider启动的时候被调用,就是拿到SQLiteDatabase的对象的
    @Override
    public boolean onCreate() {
        sqLiteDatabase = DBHelper.getInstance(getContext(),DATEBASE_NAME,null,DATEBASE_VERSION).getWritableDatabase();
        return (sqLiteDatabase == null)? false:true;
    }

    //查询,用provider的时候,不是常常用个uri就得到一个Cursor,这里重写方法是为了提供给外部查询的方法的
    @Nullable
    @Override
    public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
        SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
        sqlBuilder.setTables(getType(uri));
        if (uriMatcher.match(uri) == Scene_ID)//如果
         sqlBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));
        Cursor c = sqlBuilder.query(sqLiteDatabase, strings, s, strings1, null, null, s1);
        c.setNotificationUri(getContext().getContentResolver(), uri);
        return c;
    }

    //这里的getType返回的也是表名,这个AutonomicContentProvider里面不一定只有一张表
    @Nullable
    @Override
    public String getType(Uri uri) {
        //返回给定的URI数据的MIME类型
        switch (uriMatcher.match(uri)){
            case Scene: //多个场景
                return "scene";
            case Scene_ID://某个场景
                return "scene";
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }
   //利用ContentValues插入时应该就是掉的这个方法,固定的写法,getType(uri)返回的是表名,插入基本都是一样的
   // 估计是因为我们的表名都不一样,所以把ContentProvider弄成一个抽象类让我们去继承,灵活应用的
    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues contentValues) {
        //---add a new scene---
        Log.e("插入",getType(uri));
        long rowID = sqLiteDatabase.insert(getType(uri), "", contentValues);
        if (rowID>0) {
            Uri _uri = ContentUris.withAppendedId(uri, rowID);
            getContext().getContentResolver().notifyChange(_uri, null);
            return _uri;
        }
        throw new SQLException("Failed to insert row into " + uri);
    }
    //删除的方法
    @Override
    public int delete(Uri uri, String s, String[] strings) {
        int count=0;
        switch (uriMatcher.match(uri)){
            case Scene:
                count = sqLiteDatabase.delete(getType(uri), s, strings);
                break;
            case Scene_ID:
                String id = uri.getPathSegments().get(1);
                count = sqLiteDatabase.delete(getType(uri), _ID + " = " + id + (!TextUtils.isEmpty(s) ? " AND (" + s + ')' : ""), strings);
                break;
            default: throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
    //修改数据的方法
    @Override
    public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
        int count = 0;
        switch (uriMatcher.match(uri)){
            case Scene:
                count = sqLiteDatabase.update(getType(uri), contentValues, s, strings);
                break;
            case Scene_ID:
                count = sqLiteDatabase.update(getType(uri), contentValues, _ID + " = " + uri.getPathSegments().get(1) + (!TextUtils.isEmpty(s) ? " AND (" + s + ')' : ""), strings);
                break;
            default: throw new IllegalArgumentException("Unknown URI " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return count;
    }
}

第三步,在其他app里面应用,如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

         /*插入数据*/
        ContentValues values = new ContentValues();
        values.put("outputname", "输出我要吃饭");//outputname,inputname为字段名
        values.put("inputname", "输入为我饿了");
        getContentResolver().insert(AutonomicContentProvider.CONTENT_URI, values);
        values.clear();
        values.put("outputname", "输出111");
        values.put("inputname", "输入2222");
        getContentResolver().insert(AutonomicContentProvider.CONTENT_URI, values);
        /*查询数据测试一下*/
        displayNote();

    }
    private void displayNote(){
        Uri myUri = AutonomicContentProvider.CONTENT_URI;
        Cursor cur = getContentResolver().query(myUri, null, null, null, null);
        if (cur.moveToFirst()) {
            String id = null;
            String inputname = null;
            String outputname = null;
            do {
                id = cur.getString(cur.getColumnIndex(AutonomicContentProvider._ID));
                inputname = cur.getString(cur.getColumnIndex( "inputname"));
                outputname = cur.getString(cur.getColumnIndex("outputname"));

                Toast toast = Toast.makeText(this, "TITILE:"+id + "\t" + "NOTE:" + inputname+"\t" +outputname, Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 40);
                toast.show();
            } while (cur.moveToNext());
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值