zoukankan      html  css  js  c++  java
  • 四大组件之---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
    
        }
    
    }
    

      

  • 相关阅读:
    这是阿里技术专家对 SRE 和稳定性保障的理解
    阿里四年技术 TL 的得失总结:如何做好技术 Team Leader
    深度 | 阿里云蒋江伟:什么是真正的云原生?
    亲历者说 | 完整记录一年多考拉海购的云原生之路
    Seata RPC 模块的重构之路
    对容器镜像的思考和讨论
    20 行代码:Serverless 架构下用 Python 轻松搞定图像分类和预测
    怎么提升写代码的能力
    云原生 DevOps 的 5 步升级路径
    dubbo-go 白话文 | 从零搭建 dubbogo 和 dubbo 的简单用例
  • 原文地址:https://www.cnblogs.com/ljstudy/p/14586155.html
Copyright © 2011-2022 走看看