ContentProvider


前言:

  • Android四大组件之一,称为内容提供者。有时候需要在应用程序之间共享数据,这时内容提供者变得非常有用。

  • ContenProvider需要在AndroidManifest.xml中注册,一旦提供CP,不论应用启动与否,都可被操作

  • Content Provider以Uri的形式对外提供数据,并且是单例模式

数据共享

  • 当作为数据提供方,则需要提供ContentProvider
  • 当作为数据接收方,则通过ContectResolver来操作
创建ContentProvider
  • 继承类ContentProvider
  • 定义访问内容的Uri
  • 准备数据
  • 在AndroidManifest.xml中注册
Uri讲解

COntentResolver通过uri(统一资源定位符)来定位自己要访问的数据

Uri举例:content://org.edu.provider/words

  • content://这部分是Android固定的
  • org.edu.provider 这部分是ContentProvider中的authority
  • words 资源部份

Uri提供静态方法parse()来实现将字符串给转换为Uri

  • Uri uri = Uri.parse("content://org.edu.provider/words");

操作Uri的工具类

  • UriMatcher

    • // 构造方法,UrMatcher.NO_MATCH表示不匹配任何路径的返回码
      UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
      // 用于注册两个Uri
      match.addURI("org.providers.prods", "words", 1);
      match.addURI("org.providers.prods", "words/#", 2);
      //返回1
      matcher.match(Uri.parse("content://org.providers.prods/words");
      //返回2
      matcher.match(Uri.parse("content://org.providers.prods/word/5");
      
      
  • ContentUris工具类

    • with Append Id(uri,id):为路径uri加上id部分

    • parseId(uri):从指定Uri解析出所包含的Id值

    • Uri uri = Uri.parse("content://org.providers.prods/word");
      Uri resultUri = ContentUris.withAppendedId(uri,5);
      
      //返回5
      Long id = ContentUris.parseId(resultUri);
      
ContentResolver简介
  • 获取ContentResolvercontext.getContentResolver
  • 通过ContentResolver操作数据
insert(uri,values);
delete(uri,where,selectionargs);
update(uri,values,where,selectionargs);

/**
*uri:ContentProvider的Uri
*projection:要返回的内容(列)
*/
query(uri,projection,selection,selectionargs,order);
系统中的ContentProvider

Android系统中会给应用提供一些开放的数据,采用CP的形式

  • 通过ContentResolver访问系统CP的步骤:
    • 调用Activity中的ContentResolver获取CR对象
    • 调用CR中的query等方法获取数据
  • ContentProvider访问通话记录
    • 通话记录的Uri:CallLog.Calls.CONTENT_URI
public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        visitCP();
    }

    @SuppressLint("Range")
    private void visitCP() {
        
        Cursor cur = getContentResolver().query(
                CallLog.Calls.CONTENT_URI, null, null, null, null);
        if(cur != null && cur.moveToFirst()) {
            do{
                String str = cur.getString(cur.getColumnIndex(
                        CallLog.Calls.NUMBER));
                Log.e("Name", str);
            }while (cur.moveToNext());
        }else {
            Log.i("TAG","空值");
        }
    }
}
自定义的ContentProvider
  • 创建ContentProvider

    /**
     * 自定义ContentProvider
     * 继承ContentProvider类,实现该类的方法
     */
    public class StudentProvider extends ContentProvider {
        @Override
        public boolean onCreate() {
            return false;
        }
    
        @Nullable
        @Override
        public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
            return null;
        }
    
        @Nullable
        @Override
        public String getType(@NonNull Uri uri) {
            return null;
        }
    
        @Nullable
        @Override
        public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
            return null;
        }
    
        @Override
        public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    }
    
  • 配置ContentProvider

    <provider          android:authorities="com.tanghua.contentprovider.demo1.StudentProvider"
                android:name=".demo1.StudentProvider"
                android:exported="true"/>
    
    • authorities:指定CP对应的Uri,相当于分配了一个域名
    • name:CP的实现类的类名
    • exported:是否允许CP被其他应用调用
  • 使用ContentReslover调用方法

    Uri uri = Uri.parse("content://com.tanghua.contentprovider.demo1.StudentProvider");
    findViewById(R.id.btn_insert).setOnClickListener(view -> {
        ContentResolver resolver = getContentResolver();
        ContentValues values = new ContentValues();
        values.put("name","李四");
        resolver.insert(uri,values);
    });CP工具类
    
CP工具类

为了确定ContentProvider匹配的Uri,使用Urimatcher工具类

  • void add URI(authority, path, code);
  • int match(uri)

为了操作Uri,Android使用ContentUris工具类

  • withAppendedId(uri,id)
  • parseId(uri)
监听Contentprovider的数据
  • 通过ContentObserver进行CP数据修改的监听

    • 自定义类继承ContentObserver类,重写onChange方法

    • 通过ContentReslover想Uri注册ContentObserver监听器

      /**
      *uri:该监听器所监听的CP的uri
      *notifyForDescendents:布尔类型,子Uri数据改变时是否出发
      *observer:监听器实例
      */
      registerContentObserver(uri,notifyForDescendents,observer)
      
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值