四大组件之---ContentProvider(内容提供者)

一、ContentProvider应用场景:

我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据, 比如 手机联系人,短信等!我们想对这些数据进行读取或者修改,这就需要用到ContentProvider了! 我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用 到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!、

二、ContentProvider概念讲解

2.1 ContentProvider的URI:

 

 主要分三个部分:scheme, authority and path。scheme表示上图中的content://, authority表示B部分,path表示C和D部分。

A部分:表示是一个Android内容URI,说明由ContentProvider控制数据,该部分是固定形式,不可 更改的。

B部分:是URI的授权部分,是唯一标识符,用来定位ContentProvider。格式一般是自定义 ContentProvider类的完全限定名称,注册时需要用到,如: com.example.transportationprovider

C部分和D部分:是每个ContentProvider内部的路径部分,C和D部分称为路径片段,C部分指向一个对 象集合,一般用表的名字,如:/trains表示一个笔记集合;D部分指向特定的记录, 如:/trains/122表示id为122的单条记录,如果没有指定D部分,则返回全部记录。

2.2 使用系统提供的ContentProvider(比如通讯录信息)

打开模拟器的file exploer/data/data/com.android.providers.contacts/databases/contact2.db 导 出后使用SQLite图形工具查看,三个核心的表:raw_contact表,data表,mimetypes表(具体请见上篇博客,这篇主要介绍自定义ContentProvider)

2.3 自定义ContentProvider

我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用到 ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!

 

 

 

 三、代码实现

1、在分享数据的app中创建一个类,继承ContentProvider

实现对应的方法,也可以不实现,默认空实现,按需进行重写。

onCreate() 只执行一次,用于初始化Provider

insert() 插入 delete()删除 update()更新 qurey()查询 

getType() 获得ContentProvider数据的MIMI类型

public class NameContentProvider extends ContentProvider {

    //初始化一些常量
    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    private DBOpenHelper dbOpenHelper;

    //为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
    static {
        matcher.addURI("com.ttit.providers.myprovider", "test", 1);
    }

    @Override
    public boolean onCreate() {
        dbOpenHelper = new DBOpenHelper(this.getContext(), "test.db", null, 1);
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        switch (matcher.match(uri)) {
            //把数据库打开放到里面是想证明uri匹配完成
            case 1:
                SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
                long rowId = db.insert("test", null, values);
                if (rowId > 0) {
                    //在前面已有的Uri后面追加ID
                    Uri nameUri = ContentUris.withAppendedId(uri, rowId);
                    //通知数据已经发生改变
                    getContext().getContentResolver().notifyChange(nameUri, null);
                    return nameUri;
                }
        }
        return null;
    }

    @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;
    }

}

2、在AndroidManifest.xml对ContentProvider进行注册

<!-- 属性依次为:全限定类名,用于匹配的URI,是否共享数据 -->
        <provider
            android:name="com.ttit.core.provider.NameContentProvider"
            android:authorities="com.ttit.providers.myprovider"
            android:exported="true" />

3、使用UriMatchar,完成对uri的匹配

 //1、初始化一些常量,UriMatcher
    private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    private DBOpenHelper dbOpenHelper;

//2、为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
//匹配返回标识码1,不匹配返回-1
    static {
        matcher.addURI("com.ttit.providers.myprovider", "test", 1);
    }

//3、在下面需要匹配uri地方使用match方法
   @Override
    public Uri insert(Uri uri, ContentValues values) {
        switch (matcher.match(uri)) {
            //把数据库打开放到里面是想证明uri匹配完成
            case 1:
                SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
                long rowId = db.insert("test", null, values);
                if (rowId > 0) {
                    //在前面已有的Uri后面追加ID
                    Uri nameUri = ContentUris.withAppendedId(uri, rowId);
                    //通知数据已经发生改变
                    getContext().getContentResolver().notifyChange(nameUri, null);
                    return nameUri;
                }
        }
        return null;
    }

4、ContentProvider2Activity.java代码

在另一个工程中,调用getContentResolve()方法获得resolve对象,再调用对应的操作方法即可

public class ContentProvider2Activity extends AppCompatActivity {
    private Button btninsert;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.cp_layout2);
        btninsert = (Button) findViewById(R.id.btninsert);
        //读取contentprovider 数据
        final ContentResolver resolver = this.getContentResolver();
        btninsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ContentValues values = new ContentValues();
                values.put("name", "测试");
                Uri uri = Uri.parse("content://com.ttit.providers.myprovider/test");
                resolver.insert(uri, values);
                Toast.makeText(getApplicationContext(), "数据插入成功", Toast.LENGTH_SHORT).show();
            }
        });

    }
}

其他代码

cp_layout2.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">
    <Button
        android:id="@+id/btninsert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="插入"/>

</LinearLayout>
DBOpenHelper.java
public class DBOpenHelper extends SQLiteOpenHelper {

    final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";

    public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
                        int version) {
        super(context, name, null, 1);
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

  

posted @ 2021-03-27 16:39  恋人星  阅读(384)  评论(0编辑  收藏  举报