Android四大组件之ContentProvider

【AAAI2025】【小目标检测】FBRT-YOLO:更快速、更优的实时航拍图像检测方法 FBRT-YOLO是一种新型实时航拍图像检测方法,针对小目标检测的精度与效率平衡问题提出创新解决方案。该方法通过两个轻量级模块显著提升性能:特征互补映射模块(FCM)将浅层空间位置信息深度整合至网络深层,缓解信息失衡;多核感知单元(MKP)采用多尺度卷积增强多目标感知能力。实验表明,在VisDrone、UAVDT和AI-TOD数据集上,FBRT-YOLO在检测精度和速度方面均优于现有实时检测器,特别适用于资源受限的飞行设备。该模型通过精简网络结构,在保持高性能的同时降低了计算负担,为航拍实时检测提供了高效解 阅读详情

Android四大组件之ContentProvider

ContentProvider

安卓应用程序默认是无法获取到其他程序的数据,这是安卓安全学的基石(沙盒原理)。但是经常我们需要给其他应用分享数据,内容提供者就是一个这种可以分享数据给其他应用的接口。
可以简单的理解为,内容提供者就是一个可以在不同应用程序间共享数据的组件,相当于一个中间人,一个程序把数据暴露给这个中间人,另一个则通过这个中间人获取相应的数据.

下面的这张图片能更直观的显示:
Image

  • ContentProvider中的getContext和AndroidTestCast中的getContext方法一样,都是一个模拟的上下文,必须在该类初始化之后才会调用setContext方法将context设置成自己的成员变量中记录,
    所以对于获取getContext的时候只能放在方法内,不能放到成员位置,因为在成员上时是null,而在方法内调用时该类就会已经初始化完了

  • ContentProvider中的query()后不能关闭数据库,因为其他的应用在调用该query方法时需要继续使用该返回值Cursor,所以不能关闭数据库,因为数据库关闭之后Cursor就不能用了,
    Cursor中保存的数据其实是数据库的一个引用,如果数据库关了Cursor就不能找到里面的数据了,Cursor.close()只是释放·Cursor·用到的资源。说到这里就多数一句
    According to Dianne Hackborn (Android framework engineer) there is no need to close the database in a content provider.以为内容提供者是因为进程启动时便加载,之后就一直存在,当进程销毁
    释放资源时会去关闭数据库。

  • 如果数据是SQLiteDatabase,表中必须有一个_id的列,用来表示每条记录的唯一性。

    1. 继承ContentProvider,并实现相应的方法。

      public class NoteProvider extends ContentProvider {
          private static final int NOTES = 1;
          private static final int NOTE_ID = 2;
      
          public static final String AUTHORITY = "com.charon.demo.provider.noteprovider";
          public static final String TABLE_NAME = "note";
          // 定义一个名为`CONTENT_URI`必须为其指定一个唯一的字符串值,最好的方案是以类的全名称
          public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
      
          // 声明一个路径的检查者,参数为Uri不匹配时的返回值
          // 虽然是中间人,但也不能谁要数据我们都给,所以要检查下,只有符合我们要求的人,我们才会给他数据。
          private static UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
      
          private NoteSQLiteOpenHelper mSQLiteOpenHelper;
          private SQLiteDatabase mSQLiteDatabase;
      
          static {
              // 建立匹配规则,例如发现路径为ccom.charon.demo.provider.noteprovider/note/1表示要操作note表中id为1的记录
              sUriMatcher.addURI(AUTHORITY, TABLE_NAME, NOTES);
              sUriMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", NOTE_ID);
          }
      
          /**
           * Implement this to initialize your content provider on startup.
           * This method is called for all registered content providers on the
           * application main thread at application launch time.  It must not perform
           * lengthy operations, or application startup will be delayed.
           * <p/>
           * <p>You should defer nontrivial initialization (such as opening,
           * upgrading, and scanning databases) until the content provider is used
           * (via {@link #query}, {@link #insert}, etc).  Deferred initialization
           * keeps application startup fast, avoids unnecessary work if the provider
           * turns out not to be needed, and stops database errors (such as a full
           * disk) from halting application launch.
           * <p/>
           * <p>If you use SQLite, {@link android.database.sqlite.SQLiteOpenHelper}
           * is a helpful utility class that makes it easy to manage databases,
           * and will automatically defer opening until first use.  If you do use
           * SQLiteOpenHelper, make sure to avoid calling
           * {@link android.database.sqlite.SQLiteOpenHelper#getReadableDatabase} or
           * {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase}
           * from this method.  (Instead, override
           * {@link android.database.sqlite.SQLiteOpenHelper#onOpen} to initialize the
           * database when it is first opened.)
           *
           * @return true if the provider was successfully loaded, false otherwise
           */
          @Override
          public boolean onCreate() {
              mSQLiteOpenHelper = new NoteSQLiteOpenHelper(getContext());
              return true;
          }
      
          /**
           * 内容提供者暴露的查询的方法.
           */
          @Override
          public Cursor query(Uri uri, String[] projection, String selection,
                              String[] selectionArgs, String sortOrder) {
              mSQLiteDatabase = mSQLiteOpenHelper.getReadableDatabase();
              Cursor cursor;
              // 1.重要的事情 ,检查 uri的路径.
              switch (sUriMatcher.match(uri)) {
                  case NOTES:
                      break;
                  case NOTE_ID:
                      String id = uri.getLastPathSegment();
                      if (TextUtils.isEmpty(selection)) {
                          selection = selection + "_id = " + id;
                      } else {
                          selection = selection + " and " + "_id = " + id;
                      }
                      break;
                  default:
                      throw new IllegalArgumentException("UnKnown Uri" + uri);
                      break;
              }
              cursor = mSQLiteDatabase.query(TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
              if (cursor != null) {
                  cursor.setNotificationUri(getContext().getContentResolver(), uri);
              }
              return cursor;
          }
      
          /**
           * Implement this to handle requests for the MIME type of the data at the
           * given URI.  The returned MIME type should start with
           * <code>vnd.android.cursor.item</code> for a single record,
           * or <code>vnd.android.cursor.dir/</code> for multiple items.
           * This method can be called from multiple threads, as described in
           * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html#Threads">Processes
           * and Threads</a>.
           * <p/>
           * <p>Note that there are no permissions needed for an application to
           * access this information; if your content provider requires read and/or
           * write permissions, or is not exported, all applications can still call
           * this method regardless of their access permissions.  This allows them
           * to retrieve the MIME type for a URI when dispatching intents.
           *
           * @param uri the URI to query.
           * @return a MIME type string, or {@code null} if there is no type.
           */
          @Override
          public String getType(Uri uri) {
              // 注释说的很清楚了,下面是常用的格式
              // 单个记录的IMEI类型 vnd.android.cursor.item/vnd.<yourcompanyname>.<contenttype>
              // 多个记录的IMEI类型 vnd.android.cursor.dir/vnd.<yourcompanyname>.<contenttype>
              switch (sUriMatcher.match(uri)) {
                  case NOTE_ID:
                      // 如果uri为 content://com.charon.demo.noteprovider/note/1
                      return "vnd.android.cursor.item/vnd.charon.note";
                  case NOTES:
                      return "vnd.android.cursor.dir/vnd.charon.note";
                  default:
                      return null;
              }
      
              // 这个MIME类型的作用是要匹配AndroidManifest.xml文件<activity>标签下<intent-filter>标签的子标签<data>的属性android:mimeType。
              // 如果不一致,则会导致对应的Activity无法启动。
          }
      
          @Override
          public Uri insert(Uri uri, ContentValues values) {
              mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase();
              switch (sUriMatcher.match(uri)) {
                  case NOTES:
                      break;
      
                  case NOTE_ID:
                      break;
      
                  default:
                      throw new IllegalArgumentException("UnKnown Uri" + uri);
                      break;
              }
      
              long rowId = mSQLiteDatabase.insert(TABLE_NAME, null, values);
              if (rowId > 0) {
                  Uri noteUri = ContentUris.withAppendedId(CONTENT_URI, rowId);
                  getContext().getContentResolver().notifyChange(noteUri, null);
                  return noteUri;
              }
      
              return null;
          }
      
          @Override
          public int delete(Uri uri, String selection, String[] selectionArgs) {
              mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase();
              switch (sUriMatcher.match(uri)) {
                  case NOTES:
                      break;
      
                  case NOTE_ID:
                      String id = uri.getLastPathSegment();
                      if (TextUtils.isEmpty(selection)) {
                          selection = selection + "_id = " + id;
                      } else {
                          selection = selection + " and " + "_id = " + id;
                      }
                      break;
      
                  default:
                      throw new IllegalArgumentException("UnKnown Uri" + uri);
                      break;
              }
              int count = mSQLiteDatabase.delete(TABLE_NAME, selection, selectionArgs);
              getContext().getContentResolver().notifyChange(uri, null);
              return count;
          }
      
          @Override
          public int update(Uri uri, ContentValues values, String selection,
                            String[] selectionArgs) {
              switch (sUriMatcher.match(uri)) {
                  case NOTES:
      
                      break;
      
                  case NOTE_ID:
      
                      break;
      
                  default:
                      throw new IllegalArgumentException("UnKnown Uri" + uri);
                      break;
              }
      
              mSQLiteDatabase = mSQLiteOpenHelper.getWritableDatabase();
              int update = mSQLiteDatabase.update(TABLE_NAME, values, selection, selectionArgs);
              return update;
          }
    2. 在清单文件中进行注册,并且指定其authorities

      <provider
          android:name="com.charon.demo.provider.NoteProvider"
          android:authorities="com.charon.demo.provider.noteprovider" >
    3. 使用内容提供者获取数据,使用ContentResolver去操作ContentProvider, ContentResolver用于管理ContentProvider实例,
      并且可实现找到指定的ContentProvider并获取里面的数据

      public void query(View view){
          //得到内容提供者的解析器  中间人
          ContentResolver resolver = getContentResolver();
          Cursor cursor = resolver.query(NoteProvider.CONTENT_URI, null, null, null, null);
          while(cursor.moveToNext()){
              String name = cursor.getString(cursor.getColumnIndex("name"));
              int id = cursor.getInt(cursor.getColumnIndex("id"));
              float money = cursor.getFloat(cursor.getColumnIndex("money"));
              System.out.println("id="+id+",name="+name+",money="+money);
          }
          cursor.close();
      }
      public void insert(View view){
          ContentResolver resolver = getContentResolver();
          ContentValues values = new ContentValues();
          values.put("name", "买洗头膏");
          values.put("money", 22.58f);
          resolver.insert(NoteProvider.CONTENT_URI, values);
      }
      public void update(View view){
          ContentResolver resolver = getContentResolver();
          ContentValues values = new ContentValues();
          values.put("name", "买洗头膏");
          values.put("money", 42.58f);
          resolver.update(NoteProvider.CONTENT_URI, values, "name=?", new String[]{"买洗头膏"});
      }
      public void delete(View view){
          ContentResolver resolver = getContentResolver();
          resolver.delete(NoteProvider.CONTENT_URI, "name=?", new String[]{"买洗头膏"});
      }

内容观察者

内容观察者的原理:
How a content provider actually stores its data under the covers is up to its designer. But all content providers implement a common interface for
querying the provider and returning results — as well as for adding, altering, and deleting data.
It's an interface that clients use indirectly, most generally through ContentResolver objects.
You get a ContentResolver by calling getContentResolver() from within the implementation of an Activity or other application component:
You can then use the ContentResolver's methods to interact with whatever content providers you're interested in.

  1. 一方使用内容观察者去观察变化

        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ContentResolver resolver = getContentResolver();
        resolver.registerContentObserver(NoteProvider.CONTENT_URI, true, new NoteObserver(new Handler()));
    
    }
    
    private class NoteObserver extends ContentObserver {
    
        public NoteObserver(Handler handler) {
            super(handler);
    
        }
        //当观察到数据发生变化的时候  会执行onchange方法.
        @Override
        public void onChange(boolean selfChange) {
            super.onChange(selfChange);
            Log.i(TAG,"发现有新的短信产生了...");
            //1.利用内容提供者  中间人 获取用户的短信数据.
            ContentResolver resolver  = getContentResolver();
            // .. 重新查询
            cursor = ...;
            cursor.close();
        }
    }
  2. 一方在发生变化的时候去发送改变的消息
    对于一些系统的内容提供者内部都实现了该步骤,如果是自己写程序想要暴露就必须要加上该代码。

    getContext().getContentResolver().notifyChange(uri, null);

  • 邮箱 :charon.chui@gmail.com
  • Good Luck!
基于 OpenCVSharp 的晶圆缺口自动检测与旋正方案 在半导体制造过程中,晶圆(Wafer)需要精确定位才能进行后续加工。每个晶圆边缘都有一个特定的缺口,这个缺口就像 "箭头" 一样,帮助机器确定晶圆的方向。我们的任务就是通过摄像头拍摄的图片,自动找到这个缺口的位置,计算出需要旋转多少角度才能让晶圆对准正确方向。简单来说,这个技术就像给晶圆 "找方向",确保它在生产线上始终保持正确的姿态。 阅读详情

相关推荐

WPS Office 2026免费安装指南:AI办公与安全使用全解析

办公软件作为数字化办公的核心工具,其基本原理是通过文档处理、数据计算和演示展示等功能模块满足用户日常办公需求。随着人工智能技术的发展,现代办公软件逐步集成AI能力,通过自然语言处理和数据分析算法提升工作效率。在技术价值层面,优秀的办公软件不仅需要保持格式兼容性和跨平台同步能力,更要注重用户数据安全防护。从应用场景来看,无论是个人文档编辑、企业报表分析还是团队协作演示,办公软件都发挥着关键作用。WPS Office 2026作为国产办公软件代表,深度融合AI助手功能,支持智能写作和数据分析,同时通过官方免费策

weixin_30599769的博客 738

【Android】安卓四大组件之ContentProvider知识总结

统一资源标识符(URI)是一种用于标识资源的字符串。它可以是一个网址、文件路径、或其他形式的资源定位符。在Android中,URI通常用于访问内容提供者(Content Provider)提供的数据。获取设备上存储的所有图片获取设备上所有联系人信息获取ID为45的单个联系人信息在Java中,可以通过Uri.parse方法将字符串URI转换为Uri对象。

Patrick_yuxuan的博客 2454

Frida实战:SSL Pinning绕过技术全解析

本文详细解析了如何使用Frida工具绕过SSL Pinning技术,包括环境搭建、四种实战绕过方案及常见问题排查指南。通过具体代码示例和实战经验,帮助安全研究人员快速掌握SSL Pinning绕过技术,适用于金融类App的安全测试场景。

weixin_42530732的博客 188

安卓四大组件之ContentProvider

ContentProvider 四大组件之一 内容提供者的作用:把私有数据暴露给其他应用,通常,是把私有数据库的数据暴露给其他应用 短信数据库 sms表 body:短信内容 date:短信时间 address:对方号码 type:发送还是接收 联系人数据库 raw_contacts表 contact_id:联系人id data表:存放联系人的详细的信息,每行数据是单独的...

sd821128的博客 4912

Zemax操作33--5倍激光扩束器

5倍扩束

lzy750750的博客 2934

【Docker】从零构建达梦DM8轻量级服务镜像:实战与优化

本文详细介绍了从零开始构建达梦DM8轻量级Docker镜像的完整实战流程。通过分析传统安装方式的痛点,阐述了使用Docker封装数据库的优势,并重点讲解了如何利用静默安装、精简组件、多阶段构建等优化技巧,打造一个体积小巧、启动迅速、配置灵活的DM8服务镜像,助力实现开发、测试与部署的环境一致性与高效性。

ooo22的博客 520

【Android】安卓四大组件之内容提供者(ContentProvider):从基础到进阶

ContentProvider 是 Android 系统中实现跨应用数据共享的核心组件,通过统一的 URI 接口和权限控制机制,提供了安全、高效的数据共享方案。在使用时,需要注意权限管理、性能优化和安全防护,合理选择使用场景,避免过度使用导致的复杂性。掌握 ContentProvider 的原理和实现方式,对于开发高质量的 Android 应用至关重要。

m0_59734531的博客 1338

C#实现网络寻路(附完整源码)

C#实现网络寻路(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 426

Android——四大组件ContentProvider

文章目录AndroidAndroid四大组件——ContentProvider1 简介2 ContentProvider配置2.1 ContentResolver类2.2 ContentProvider类3 Uri的使用4 数据读取 Android 安卓开发者指南:https://developer.android.google.cn/guide Android常用四大组件: 1.Activity 2.Service 3.Content provider 4.Broadcast receiver Andro

weixin_45044097的博客 333

LPDDR5 学习笔记01:功能概述

LPDDR5/LPDDR5X SDRAM设备采用8/16DQ通道架构,支持2Gb-32Gb容量。通过CK命令时钟和更快的WCK数据时钟协同工作,7个CA引脚传输控制信息,支持2:1或4:1的WCK:CK比例。设备提供BG/8B/16B三种存储模式选择,分别支持不同数据速率(最高8.533Gbps)和突发长度。采用0.5V VDDQ电源电压,实现高速双倍数据速率传输,并通过差分WCK时钟完成数据采样。读写采用突发访问机制,需先激活命令再执行读写操作。新型LPDDR5X仅支持BG和16B模式,优化了高速性能。

一只豌豆象的博客 2205

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

安卓四大组件——ContentProvider

安卓四大组件——ContentProvider通常每个应用都是独立的进程,应用创建出的数据文件只能被自身访问,其他应用无权访问。当我们需要将自身数据公布出来,让其他应用访问时,就需要使用ContentProvider组件。当我们需要访问ContentProvider共享的数据时,需要使用ContentResolver对象。也就是说ContentProvider是与ContentResolver配合使

深海大菠萝 1994

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Android 四大组件——ContentProvider(内容提供者)

摘要:ContentProvider是Android四大组件之一,用于实现应用间数据共享。文章详细介绍了ContentProvider的架构与工作原理,包括核心组件ContentResolver、Uri、Cursor等。重点讲解了创建ContentProvider的步骤:定义子类、实现数据库帮助类、实现CRUD方法以及在清单文件中注册。同时介绍了如何使用ContentResolver访问其他应用的数据,如读取短信和联系人等系统数据,以及通过ContentObserver监听数据变化。文章提供了完整的代码示例

indeedes的博客 905

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【Android】四大组件之ContentProvider

ContentProvider就是用来共享和管理数据的组件。

贫道绝缘子的博客 3439

安卓四大组件之一——ContentProvider

使用安卓四大组件之一——contentprovider的方法类进行数据获取及两个app之间的程序调用

qq_53850212的博客 1436

【Android】四大组件之 ContentProvider

前言 ContentProvider 是 Android 的四大组件之一,有时候我们需要操作其他应用程序的一些数据,就会用到 ContentProvider。 ContentProvider 用于管理 Android 以结构化方式存放的数据,以相对安全的方式封装数据并提供简易的处理机制和统一的访问接口供其他程序调用。 Android 为常见的一些数据提供了默认的 ContentProvider(包括音频、视频、图片和通讯录等)。 要实现与其他的 ContentProvider 通信首先要查找到对应的 Co

yang553566463的博客 3105

Android 四大组件之ContentProvider

Android 四大组件之ContentProvider 本文由 Luzhuo 编写,转发请保留该信息. 原文: http://blog.youkuaiyun.com/Rozol/article/details/79606186 内容提供者 (提供数据给第三方应用访问) 四大组件(Activity / BroadcastReceiver / Service / ContentPr...

Luzhuo 的博客 470

Android 四大组件基础(Activity/Service/BroadcastReceiver/ContentProvider)工控场景用法

Android四大组件在工控场景中的应用与手机开发有显著差异。工控开发以Service为核心,负责后台数据采集(串口/Modbus)、设备监控等关键任务,需通过前台Service保证持续运行。Activity主要用于全屏数据显示和参数配置,需禁用旋转和返回键退出。BroadcastReceiver实现开机自启、外设状态监听等功能。ContentProvider则用于多应用间共享传感器数据。工控开发强调稳定性,四大组件需针对工业环境特殊配置,如固定屏幕方向、防进程回收等。

爱片闲串,爱钓鱼,爱中医,爱分享 534

Android四大组件—ContentProvider

Android四大组件—ContentProvider ContentProvider 是 Android四大组件之一,Android提供了五种数据存储技术(其他的四种分别是:SharedPreferences、IO、SQLite、网络)。这五种技术都能由ContentProvider提供的方法按统一的代码格式存取。这种以一致性的方法操作多样性的数据源与面向对象的多态异曲同工。   An

plxy_001的博客 724

delphi XE Android四大组件ContentProvider:delphi XE可调用的Android ContentProvider有哪些?

delphi XE Android四大组件ContentProvider:delphi XE可调用的Android ContentProvider有哪些? delphi XE用Android SDK方法开发App(二) 运用Android四大组件之ContentProvider unit Androidapi.JNI.Provider; interface uses Andro...

pulledup的博客 1708

android内容提供者_Android四大组件之ContentProvider

前言Hi,大家好,我们又双叒叕见面啦,为了让大家快速的学习Android知识,我们每天都在更新文章,相信小伙伴们已经开始眼熟我们了!这一期我们讲解ContentProvider(内容提供者)相关知识,他也是我们近期更新的Android四大组件中最后一个。话不多说,让我们赶紧开始学习吧~简介ContentProvider是Android系统中为开发者专门提供的不同应用间进行数据共享的组件,其提供了一...

weixin_39996750的博客 117

Android四大组件—ContentProvider详解

一、ContentProvider 介绍 定义 ContentProvider是Android四大组件之一,其本质上是一个标准化的数据管道,它屏蔽了底层的数据管理和服务等细节,以标准化的方式在Android 应用间共享数据、数据交互,跨进程通信。 原理 ContentProvider的底层是采用 Android中的Binder机制 具体请看文章图文详解 Android Binder跨进程通信的原理 特点 虽然使用其他方法也可以对外共享数据,但数据访问方式会因数据存储的方式而不同,如:采用文件方.

shipingxue的专栏 771

Android四大组件之ContentProvider知多少

前言:文中全面讲解了ContentProvider,从说明、用法讲解到原理分析,如果各位码友发现问题欢迎指正。 目录结构: 1.简介。 Android的数据存储方式总共有五种,分别是:SharedPreferences、网络存储、文件存储、外储存储、SQLite,但是一般这些存储都只是在同一个应用程序中数据的共享,如果需要操作其他应用程序的一些数据,例如媒体库、通讯录等,该怎么...

leisurelhz的博客 3077
上一篇: Android动画
下一篇: Android四大组件之Service
CharonChui
博客等级 码龄12年 66粉丝 134原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值