ContentProvider与ContentResolver

news2024/12/24 22:01:41

目录:

  • 一、什么是ContentProvider:
  • 二、如何使用ContentProvider:
    • 第一步.创建类继承ContentProvider:
    • 第二步.注册ContentProvider:
  • 三、URI:
    • 1.常用方法:
    • 2.解析URI:
      • (1)UriMatcher解析URI:
      • (2)ContentUris解析URI:
  • 四、什么是ContentResolver:
  • 五、如何使用ContentResolver:
    • 第一步:获取ContentResolver对象
    • 第二步:使用ContentResolver对象进行增删查改
  • 六、ContentObserve监听器:
    • 第一步:设置ContentProvider发送通知
    • 第二步:创建类并继承ContentObserver类
    • 第三步:ContentResolver中开启监听:

一、什么是ContentProvider:

当我们想允许自己的应用数据被别的应用进行读取操作,可以让自己的APP实现ContentProvider类,同时注册一个URI,然后其他应用只要使用ContentResolver访问指定URI就可以操作我们APP里的数据了。

二、如何使用ContentProvider:

ContentProvider为数据定义一个URI,其他程序想要操作本数据时,只需要获得一个ContentResolver对象并传入相应的URI,即可操作本URI下的数据。
在这里插入图片描述

第一步.创建类继承ContentProvider:

需要重写onCreate( )、delete( )、getType( )、insert( )、query( )、update( )方法。
其中增删查改方法可以用来操作本应用的SQLite数据库。

package com.example.myapplication2;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

public class MyContentProvider extends ContentProvider{
    /*创建ContentProvider时调用,其他应用程序第一次访问ContentProvider时,该ContentProvider会被创建出来,立即回调该方法
     */
    @Override
    public boolean onCreate() {
        return false;

    }
    /*根据传入的URI查询指定条件下的数据
            projection:要查询的列名
            selection:where子句的内容
            selectionArgs:selection中对应的参数
            sortOrder:排序规则
     */
    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
        return null;
    }
    /*用于返回指定URI代表的数据的MIME类型
     */
    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }
    /*根据传入的URI插入contentValues对应的数据
     */
    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
        return null;
    }
    /*根据传入的URI删除where条件匹配的所有数据
     */
    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }
    /*根据传入的URI更新更新where条件匹配的数据为contentValues
     */
    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }
}

第二步.注册ContentProvider:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication"
        tools:targetApi="31">
        <!--属性依次为:全限定类名,用于匹配的URI,是否允许其他应用通过ContentResolver修改本应用的数据-->
        <provider
            android:name="com.example.myapplication.MyContentProvider"
            android:authorities="uri.mycontentprovider"
            android:exported="true"/>
    </application>
</manifest>

三、URI:

1.常用方法:

//字符串转URI
Uri uri = Uri.parse("uri.mycontentprovider");
//获取uri中数据部分存入一个List中
List<String> segments = uri.getPathSegments();

2.解析URI:

不同URI代表着不同的操作,所以当ContentProvider接收到URI时,我们需要解析URI才能知道该条URI想进行什么操作。

(1)UriMatcher解析URI:

UriMatcher类用于匹配Uri。当应用程序通过URI访问ContentProvider时,UriMatcher用于检查URI是否符合我们预先定义好的若干条规则,如果符合某条规则,则可使用该URI,返回该条规则的匹配码。

//第一步:创建URI
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);//常量UriMatcher.NO_MATCH表示Uri不匹配时的返回码
//第二步:设置URI匹配规则
matcher.addURI("uri.mycontentprovider", "studentall", 1);//查询所有学生记录,如果URI为:uri.mycontentprovider/studentall时会返回1
matcher.addURI("uri.mycontentprovider", "students/*", 2);//根据学号和姓名模糊查询获得多个记录。*是字符通配符,可以匹配任何字符
matcher.addURI("uri.mycontentprovider", "student/#", 3);//单个学生,需要根据studentid来判断,#是数字通配符,可以匹配任何数字,例如:将来可以匹配student/001,student/002等
matcher.addURI("uri.mycontentprovider", "insertstudent", 4);//插入学生
matcher.addURI("uri.mycontentprovider", "deletestudent/#", 5);//删除单个学生,需要根据studentid来判断,#将来调用时实参使用学号来代替
matcher.addURI("uri.mycontentprovider", "deleteallstudent", 6;//删除所有学生
matcher.addURI("uri.mycontentprovider", "updatestudent", 7);//修改学生信息
//第三步:在需要匹配的地方调用match()方法检查是否匹配
//点击”查询全部学生“按钮时,ContentResolver会执行query方法,发送URI,ContentProvider捕获到该URI后需要判断匹配规则是否符合,符合才执行查询操作
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        switch (matcher.match(Uri.parse("uri.mycontentprovider/studentall"))){
            //URI符合我们设置的匹配规则
            case 1:{
                //查询操作
            }
            //URI不匹配
            default:{
                break;
            }
        }    
    }
});

(2)ContentUris解析URI:

ContentUris类用于操作Uri路径后面的ID(唯一标识符)部分。

/*
public static Uri withAppendedId (Uri contentUri, long id):用于为路径加上ID部分。
*/
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://cn.itcast.provider.personprovider/person/10

/*
public static long parseId (Uri contentUri)该方法用于从路径中获取ID部分。
*/
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10

四、什么是ContentResolver:

当外部应用需要对ContentProvider中的数据进行增删改查操作时,可以使用ContentResolver类完成。

五、如何使用ContentResolver:

第一步:获取ContentResolver对象

通过Activity的静态方法获取ContentResolver对象。

ContentResolver resolver = this.getContentResolver();

第二步:使用ContentResolver对象进行增删查改

ContentResolver 类提供了与ContentProvider 类相同签名的四个方法,通过给这些方法提供ContentProvider的URI使得这些方法能够调用ContenProvider中与之对应的方法,并得到返回的结果。

ContentResolver resolver = this.getContentResolver();
/*根据传入的URI查询指定条件下的数据
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
*/
resolver.query(ContentProviderURI,SQL参数...);
/*根据传入的URI插入contentValues对应的数据
public Uri insert(Uri uri, ContentValues values)
*/
resolver.insert(ContentProviderURI,SQL参数...);
/*根据传入的URI删除where条件匹配的所有数据
public int delete(Uri uri, String selection, String[] selectionArgs)
*/
resolver.delete(ContentProviderURI,SQL参数...);
/*根据传入的URI更新更新where条件匹配的数据为contentValues
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
*/
resolver.update(ContentProviderURI,SQL参数...);

六、ContentObserve监听器:

用于监听ContentProvider中单个URI的数据的变化。

第一步:设置ContentProvider发送通知

在ContentProvide能使数据发生变化的方法中调用以下方法:

//该方法的作用是:通知注册在该URI:content://org.myapplication.studenttest/studentall上的监听器:该URI上的数据发生变化
this.getContext().getContentResolver().notifyChange(Uri.parse("content://org.myapplication.studenttest/studentall"), null);        

第二步:创建类并继承ContentObserver类

需要重写构造方法和onChange方法。

class MyContentObserve extends ContentObserver{
    /*
    当观察到Uri代表的数据发生变化时,会触发该方法
     */
    @Override
    public void onChange(boolean selfChange, @Nullable Uri uri) {

    }

    public MyContentObserve(Handler handler) {
        super(handler);
    }
}

第三步:ContentResolver中开启监听:

在需要进行监听的位置加入下面的代码,当该URI下的数据发生变化时,ContentProvider会发送通知,然后就会被下面的代码接收到通知,接收到通知后会调用MyContentObserve的onChange方法

//注册ContentObserver的监听器,当uri="content://org.myapplication.student/studentall"的数据有变化时,就触发,回调MyObserver对象的onChange(boolean selfChange, Uri uri)方法
contentResolver.registerContentObserver(Uri.parse("content://org.myapplication.studenttest/studentall"),true,new MyContentObserve(new Handler()));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/64006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android Gradle 学习笔记(二)环境安装

1. 官网安装 Gradle 安装地址&#xff1a;Gradle | Installation 最新的 Gradle 版本是 7.6&#xff0c; 需要 Java 8及以上的版本支持&#xff0c;官网有两种版本可下载&#xff1a; 二进制版本完全版本&#xff08;源码 文档&#xff09; 一般情况下&#xff0c;下载二进…

助力企业降本增效,「WorkPlus SE专业版」正式发布!

移动互联网时代&#xff0c;数字化成为了企业提质降本增效的价值路径。大中小型企业积极主动地借助各种在线办公产品&#xff0c;实现沟通协作和运营管理的优化升级。 随着企业规模的扩大和办公业态多样化发展&#xff0c;会面临着业务流程繁杂、数据利用率低、IT成本高、泄密…

RFID警用装备管理系统-公安警用装备管理可视化系统

一、方案背景 我国警用装备物资种类多、数量大、价值高&#xff0c;还包含枪支、弹药、爆炸物等需要重点监管的物资&#xff0c;在公安机关应对紧急情况、处理突发事件过程中发挥了极为重要的作用。但是&#xff0c;由于缺乏有效的信息化管理手段&#xff0c;还存在管理方式落后…

Tealium 分析

文章目录1.0 调用流程1.1 初始化流程1.2 发送数据流程2.0 Tealium 的设计2.1 总体设计2.1.1 Tealium Core2.1.2 Visitor2.1.3 Crash reporter2.1.4 Ad identifler2.1.5 Lifecycle2.1.6 Location2.1.7 InstallReferrer2.1.8 Hosteddatalayer2.1.8 Dispatcher2.2 网络设计2.3 本地…

黄菊华老师,Java Servlet毕业设计毕设辅导课(4):Servlet 实例

Servlet 实例 Servlet 是服务 HTTP 请求并实现 javax.servlet.Servlet 接口的 Java 类。Web 应用程序开发人员通常编写 Servlet 来扩展 javax.servlet.http.HttpServlet&#xff0c;并实现 Servlet 接口的抽象类专门用来处理 HTTP 请求。 Hello World 示例代码 下面是 Servl…

为什么工业设计公司价格这么高?

随着经济的不断增长&#xff0c;各种工业设计公司逐渐出现&#xff0c;但价格不同&#xff0c;有些价格高&#xff0c;有些价格低&#xff0c;让一些人到处比较价格&#xff0c;低价格压低别人的高价格。有些人会想&#xff0c;为什么工业设计公司在设计产品时价格这么高&#…

ORB-SLAM2 ---- Tracking::UpdateLastFrame函数

目录 1.函数作用 2.步骤 3.code 4.函数解释 4.1 利用参考关键帧更新上一帧在世界坐标系下的位姿 4.2 对于双目或rgbd相机&#xff0c;为上一帧生成新的临时地图点 1.函数作用 更新上一帧位姿&#xff0c;在上一帧中生成临时地图点。 单目情况&#xff1a;只计算了上一帧…

【富文本编辑器】简记功能:neditor上传操作时提交额外数据

目录 编辑器下载&#xff08;本文使用版本v2.1.19&#xff09; 功能需求 解决思路 相关代码 调用实例的html neditor.config.js&#xff08;搜索修改内容&#xff1a;/* 设置额外请求参数 */&#xff09; 完成&#xff0c;如有其它方法&#xff0c;欢迎一起讨论 编辑器下…

使用 Fluent Bit 实现云边统一可观测性

本文基于 KubeSphere 可观测性与边缘计算负责人霍秉杰在北美 KubeCon 的 Co-located event Open Observability Day 闪电演讲的内容进行整理。 整理人&#xff1a;米开朗基杨、大飞哥 Fluent Operator 简介 2019 年 1 月 21 日&#xff0c;KubeSphere 社区为了满足以云原生的方…

NX上配置TLD的环境---对opencv的版本没有要求

一、TLD工程编译及运行 1.1 源码下载 网上的TLD有两个版本&#xff0c;一个是Zdenek Kalal自己使用matlabvs混合编程实现的&#xff0c;另外一个是 arthurv利用c和opencv实现的。 我利用的是arthurv版本的Tracking-Learning-Detection 连接&#xff1a;https://github.com/al…

基于Android平台的手机安全卫士的设计与实现

目 录 第1章 引言 1 1.1 研究背景及意义 1 1.2 安全软件的现状 1 1.3 本文主要工作 2 1.4 本文的组织结构 2 第2章 Android的相关技术介绍及分析 3 2.1 搭建Android开发环境 3 2.1.1 搭建Ubuntu系统下Java开发环境 3 2.1.2 搭建Ubuntu系统下Android开发环境 3 2.2 Android项目目…

「企企通」完成Pre-D轮融资,加速采购供应链工业软件和 SaaS 网络生态构建

企企通作为领先的采购供应链工业软件和SaaS生态平台&#xff0c;在一年内再次宣布获得Pre-D轮融资&#xff0c;全年合计融资额达数亿元人民币&#xff0c;目前还有意向投资机构在进行&#xff0c;并开始启动IPO的筹备工作。本轮投资由华映资本独家投资。华映资本是企企通C2轮融…

flutter系列之:flutter中的变形金刚Transform

文章目录简介Transform简介Transform的使用总结简介 虽然我们在开发APP的过程中是以功能为主&#xff0c;但是有时候为了美观或者其他的特殊的需求&#xff0c;需要对组件进行一些变换。在Flutter中这种变换就叫做Transform。 flutter的强大之处在于&#xff0c;可以对所有的…

IBM MQ 通道

一&#xff0c;定义 通道是分布式队列管理器在IBM MQ MQI 客户端和IBM MQ服务器之间或两个IBM MQ服务器之间使用的逻辑通信链接。 通道是提供从一个队列管理器到另一个队列管理器的通信路径的对象。通道在分布式队列中用于将消息从一个队列管理器移动到另一个队列管理器&#x…

计算机网络-应用层详解(持续更新中)

应用层概述 应用层是解决通过应用进程的交互来实现特定网络应用的问题。 应用层是计算机网络体系结构的最顶层&#xff0c;是设计和建立计算机网络的最终目的&#xff0c;也是计算机网络中发展最快的部分。 早期基于文本的应用&#xff08;电子邮件、远程登录、文件传输、新…

百度联合行业头部企业新发5个行业大模型,大模型产业落地路径愈发清晰

本文已在【飞桨PaddlePaddle】公众号平台发布&#xff0c;详情请戳链接&#xff1a;百度联合行业头部企业新发5个行业大模型&#xff0c;大模型产业落地路径愈发清晰 11月30日&#xff0c;由深度学习技术与应用国家工程研究中心主办、飞桨承办的WAVE SUMMIT2022深度学习开发者…

WLAN AP安全策略中WPA认证与WPA2认证的差异

一、安全策略WPA认证&#xff08;PSK认证TKIP加密&#xff09;的案例 组网需求&#xff1a; 设备作为FAT AP&#xff0c;为用户提供WLAN服务&#xff0c;用户可以搜索到名为huawei的无线网络&#xff0c;采用的安全策略为WPA-PSK认证TKIP加密的方式。 组网图如下&#xff1a;…

3 内存访问

内存访问 1 字的存储 寄存器中&#xff1a;16位寄存器存一个字。高8位放高位字节&#xff0c;低8位当低位字节。 内存中&#xff1a;内存单元是字节单元&#xff0c;一个字要用2个连续的内存单元保存。低位字节保存在低地址内存单元&#xff0c;高位字节保存在高地址内存单元…

vmware上的centos8没有网络

目录一、先了解虚拟机的三种网络模式二、目前的网络模式和网络状况三、 解决网络不可用问题一、先了解虚拟机的三种网络模式 虚拟机的三种网络模式 二、目前的网络模式和网络状况 我的虚拟机网络配置 我们要将虚拟机和本机在同一个局域网络里才能入网 进入cmd输入ipconfig…

Java多线程之常用的相关方法总结(线程停止、线程休眠、线程礼让、线程优先级、守护线程等等)

Java多线程之相关常用方法一、线程方法二、线程停止1、思路2、样例三、线程休眠&#xff08;sleep&#xff09;1、思路2、样例四、线程礼让&#xff08;yield&#xff09;1、思路2、样例五、线程强制执行&#xff08;join&#xff09;1、思路2、样例六、观测线程状态1、相关概念…