Android -----数据共享ContentProvider

Android Studio中ContentProvider实现:数据共享机制 在Android系统中,不同的应用程序通常运行在各自独立的沙箱环境中,这意味着它们之间的数据访问受到限制。ContentProvider作为Android提供的一种重要组件,旨在解决不同应用程序之间的数据共享问题。本文的目的是详细介绍在Android Studio中如何使用ContentProvider实现数据共享机制,范围涵盖了ContentProvider的基本概念、实现步骤、实际应用场景以及相关的开发工具和资源。 阅读详情

AAndroid中内置了SQLite,但是对于数据库操作这块,非常的麻烦.其实可以试用第3方的数据库持久化框架对之进行结构上调整, 摆脱了访问数据库操作的细节,不用再去写复杂的SQL语句.虽然这样会在数据库操作上损失一点性能,但基于xxxx对数据库操作不频繁性能要求不高可以使用,所带来的好处即使有一个良好的统一的数据库操作以及降低代码维护成本.然而,SQLite的数据库只能有本程序访问数据。但为了不同的程序间可以共享数据,Android 有给我们提供了ContentProvider,只需要声明权限,是不同程序间的数据共享提供了可能。

 

对于使用ContentProvider的第一步我们需要继承ContentProvider,实现并重写ContentProvider搜提供的方法。ContentProvider 所提供的发法有:用于外部删除数据 int delete(Uri uri, String selection, String[] selectionArgs), Uri insert(Uri uri, ContentValues values), 用于外部查询Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder),用于外部更新数据int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs),boolean onCreate()方法ContentProvider在其它程序第一次访问时创建 ,返回当前Uri所代表的类型String getType(Uri uri)此函数,如果ContentProvider是自己定义的必须实现。

 

在第二不是会用到Android提供的另一个辅助类ContentUris,在下述的代码中使用ContentUris工具类构造添加数据后这条记录的Uri,ContentUris类用于获取Uri路径后面的ID部分。它有两个有用的方法。

(1)withAppendedID(uri,id),用于为路径加上ID部分。

(2)parseId(id)方法用于从路径中获取ID部分。

主要代码演示:

package com.itcast.utils;

import android.net.Uri;
import android.provider.BaseColumns;

public class Person
{

  //ContentProvider的uri
    public static final String    AUTHORITY    = "com.google.provider.person";

    private Person(){}

    // 定义基本字段
    public static final class Informations implements BaseColumns
    {
        private Informations(){}

        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/persons");

 

 

package com.itcast.database;

import com.itcast.utils.Person.Informations;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper
{
  // 数据库名
    private static final String DATABASE_NAME = "person.db";
    private static final int   DATABASE_VERSION    = 1;
    // 表名
    public static final String TABLE_NAME = "persons";
    //创建表SQL语句
    private static final String CREATE_TABLE="CREATE TABLE "
                                                        + TABLE_NAME
                                                        + " (" + Informations._ID
                                                        + " INTEGER PRIMARY KEY,"
                                                        + Informations.NAME
                                                        + " varcahr(10),"
                                                        + Informations.SEX
                                                        + " varchar(2),"
                                                        + Informations.CREATEDDATE
                                                        + " INTEGER,"
                                                        + Informations.MODIFIEDDATE
                                                        + " INTEGER" + ");";


  //构造函数-创建数据库
    DatabaseHelper(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    //创建表
    @Override
    public void onCreate(SQLiteDatabase db)
    {
        db.execSQL(CREATE_TABLE);
    }
    //更新数据库
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        db.execSQL("DROP TABLE IF EXISTS persons");
        onCreate(db);
    }
}

 

        // 新的MIME类型-多个
        public static final String CONTENT_TYPE  = "vnd.android.cursor.dir/vnd.google.person";

        // 新的MIME类型-单个
        public static final String CONTENT_ITEM_TYPE  = "vnd.android.cursor.item/vnd.google.person";

        public static final String  DEFAULT_SORT_ORDER    = "modified DESC";

        //字段
        public static final String    NAME  = "name";
        public static final String    SEX  = "sex";
      
        public static final String    CREATEDDATE  = "created";
        public static final String    MODIFIEDDATE  = "modified";
    }

}

 

package com.itcast.database;

import java.util.HashMap;

import com.itcast.utils.Person;
import com.itcast.utils.Person.Informations;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

public class PersonContentProvider extends ContentProvider
{

 private static HashMap<String, String> sPersonProjectionMap;
 private static final int PERSON = 1;
 private static final int PERSON_ID = 2;
 private static final UriMatcher sUriMatcher ;
 private DatabaseHelper mOpenHelper;

 static
 {
  sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  sUriMatcher.addURI(Person.AUTHORITY, "persons", PERSON);
  sUriMatcher.addURI(Person.AUTHORITY, "persons/#", PERSON_ID);

  sPersonProjectionMap = new HashMap<String, String>();
  sPersonProjectionMap.put(Informations._ID, Informations._ID);
  sPersonProjectionMap.put(Informations.NAME, Informations.NAME);
  sPersonProjectionMap.put(Informations.SEX, Informations.SEX);
  sPersonProjectionMap.put(Informations.CREATEDDATE,
    Informations.CREATEDDATE);
  sPersonProjectionMap.put(Informations.MODIFIEDDATE, Informations.MODIFIEDDATE);
 }

 @Override
 public int delete(Uri uri, String where, String[] whereArgs)
 {
   SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         int count;
         switch (sUriMatcher.match(uri))
         {
             case PERSON:
                 count = db.delete(mOpenHelper.TABLE_NAME, where, whereArgs);
                 break;

             case PERSON_ID:
                 String noteId = uri.getPathSegments().get(1);
                 count = db.delete(mOpenHelper.TABLE_NAME, Informations._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                 break;

             default:
                 throw new IllegalArgumentException("Unknown URI " + uri);
         }
         getContext().getContentResolver().notifyChange(uri, null);
         return count;
 }

  // 如果有自定义类型,必须实现该方法
 @Override
 public String getType(Uri uri)
 {

  switch (sUriMatcher.match(uri))
        {
            case PERSON:
                return Informations.CONTENT_TYPE;

            case PERSON_ID:
                return Informations.CONTENT_ITEM_TYPE;

            default:
                throw new IllegalArgumentException("Unknown URI " + uri);
        }

 }
    //插入数据库

 @Override
 public Uri insert(Uri uri, ContentValues initialValues)
 {

   if (sUriMatcher.match(uri) != PERSON)
         {
             throw new IllegalArgumentException("Unknown URI " + uri);
         }
         ContentValues values;
         if (initialValues != null)
         {
             values = new ContentValues(initialValues);
         }
         else
         {
             values = new ContentValues();
         }
         Long now = Long.valueOf(System.currentTimeMillis());

         if (values.containsKey(Informations.CREATEDDATE) == false)
         {
             values.put(Informations.CREATEDDATE, now);
         }
         if (values.containsKey(Informations.MODIFIEDDATE) == false)
         {
             values.put(Informations.MODIFIEDDATE, now);
         }
//         if (values.containsKey(Informations.NAME) == false)
//         {
//             Resources r = Resources.getSystem();
//             values.put(Informations.NAME, r.getString(android.R.string.untitled));
//         }
         if (values.containsKey(Informations.SEX) == false)
         {
             values.put(Informations.SEX, "");
         }
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         long rowId = db.insert(mOpenHelper.TABLE_NAME, Informations.NAME, values);
         if (rowId > 0)
         {
             Uri noteUri = ContentUris.withAppendedId(Informations.CONTENT_URI, rowId);
             getContext().getContentResolver().notifyChange(noteUri, null);
             return noteUri;
         }
         throw new SQLException("Failed to insert row into " + uri);

 }

 @Override
 public boolean onCreate()
 {

  mOpenHelper = new DatabaseHelper(getContext());
  return true;
 }

 @Override
 public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder)
 {
   SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
  
   switch (sUriMatcher.match(uri))
  {
  case PERSON:
   qb.setTables(mOpenHelper.TABLE_NAME);
    qb.setProjectionMap(sPersonProjectionMap);
   break;

  case PERSON_ID:
   qb.setTables(mOpenHelper.TABLE_NAME);
    qb.setProjectionMap(sPersonProjectionMap);
    qb.appendWhere(PERSON_ID+ "=" + uri.getPathSegments().get(1));
   break;
   default:
             throw new IllegalArgumentException("Unknown URI " + uri);
  }
   String orderBy;
         if (TextUtils.isEmpty(sortOrder))
         {
             orderBy = Person.Informations.DEFAULT_SORT_ORDER;
         }
         else
         {
             orderBy = sortOrder;
         }
         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
         c.setNotificationUri(getContext().getContentResolver(), uri);
         return c;

 }

 @Override
 public int update(Uri uri, ContentValues values, String where, String[] whereArgs)
 {
     SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         int count;
         switch (sUriMatcher.match(uri))
         {
             case PERSON:
                 count = db.update(mOpenHelper.TABLE_NAME, values, where, whereArgs);
                 break;

             case PERSON_ID:
                 String noteId = uri.getPathSegments().get(1);
                 count = db.update(mOpenHelper.TABLE_NAME, values, Person.Informations._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
                 break;

             default:
                 throw new IllegalArgumentException("Unknown URI " + uri);
         }
         getContext().getContentResolver().notifyChange(uri, null);
         return count;

 }

}

 

这里是ContentProvider的主要代码,剩下的就是自己写要调用的部分。

掌握ContentProvider以实现Android应用间的数据共享 ContentProvider是Android平台上用于管理数据访问的一套机制,它封装了数据,使不同应用程序之间可以通过统一的接口来访问和操作数据。与传统数据库操作不同的是,ContentProvider通过URI(统一资源标识符)来定位数据类型,并允许应用程序通过特定的方法执行CRUD(创建、读取、更新、删除)操作。ContentProvider提供了一种进程间通信的方式,通过ContentResolver接口,应用程序可以无需直接与底层数据存储打交道,就实现数据的共享。 阅读详情

相关推荐

【一文读懂】NTN(非地面网络)技术介绍

NTN,即非地面网络,是指利用卫星、高空平台(如无人机、平流层气球等)等非地面通信基础设施来实现全球通信覆盖的网络。在5G时代,NTN主要基于5G标准,特别是5G NR(New Radio)技术,通过卫星通信扩展地面网络的覆盖范围和服务能力。NTN技术的出现和发展,为全球通信带来了新的可能性和挑战。通过不断的技术创新和标准化推进,NTN有望在未来发挥更加重要的作用,为全球用户提供无处不在的通信服务。随着6G时代的到来,我们有理由相信NTN技术将迎来更加广阔的发展前景。

u011376987的博客 1万+

浅谈android系统应用中的数据共享

ContentProvider package com.example.myapplication; import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.content.UriMatcher; import android.da

分享技术与经验的博客 2965

涨薪技术|Kubernetes(k8s)环境部署实战

这两者都是在/etc/docker/daemon.json里修改的,所以我们一起配置了就好了,首先执行下述命令编辑daemon.json:​​​​​​​。安装完成后,可以使用以下命令来查看dashboard访问的端口号​​​​​​​。网络插件CNI也是以容器的方式进行启动​​​​​​​。安装完成后可以检查是否拉取了对应的容器​​​​​​​。再使用以下命令进行安装:​​​​​​​。打开后输入以下内容:​​​​​​​。安装1.19.0版本​​​​​​​。修改IP地址:​​​​​​​。

m0_60889254的博客 1086

Android基础篇-四大组件之使用ContentProvider实现数据共享

ContendProvider是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentReslover根据Uri去访问操作指定数据因为ContendProvider是四大组件之一,所以也需要在清单文件配置:<!--下面配置中name属性指定ContentProvider类, authoriti

王涛的博客 5727

Unity集成阿里Qwen2.5-Omni全模态大模型实战:语音交互与多模态AI开发指南

本文详细介绍了在Unity中集成阿里Qwen2.5-Omni全模态大模型的实战指南。通过C#脚本开发,实现语音交互、图像分析等多模态AI功能,涵盖API调用、音频处理、流式响应解析等核心步骤,为游戏、虚拟人等Unity应用提供沉浸式智能交互解决方案。

weixin_29005499的博客 316

ElementUI中的el-table解决宽度问题 - 根据内容自动撑开

在使用element-ui中,会发现表格组件el-table在未指定宽度情况下,会自动计算并给表格宽度赋值。但实际开发中,有时需要根据内容实际长度自动撑开显示,由内容的多少而决定表格的宽度,而不是默认宽度为100%。在默认情况下表格宽度为100%显示,并且列项未指定宽度情况下,剩余部分会平均分配宽度,本案例实际需求是由内容自动撑开显示。componentUpdated

觉醒法师的专栏 1万+

Android开源框架集合分享-数据库

      上一次写到的图像加载,这次中间间隔的时间稍微长了一些,先对大家报个歉。说实话,差点把这个事情给忘了。亏得朋友的提醒,只顾整理忘记发了,真是罪过罪过。今天给大家分享的是在开源框架中的有关数据库的框架。      数据库这个东西了解后端的小伙伴都知道,对程序的来说是相当重要。因为数据是无价的,虽然现在有云存储,但是数据库这一关是躲不过去了。大家经常听到的mysql,sqlserver,DB...

文科程序猿 1115

使用阿里天池平台训练YOLO目标检测模型

YOLO算法是一种单阶段目标检测算法,由Joseph Redmon等人于2015年提出。与传统的两阶段检测算法相比,YOLO将目标检测问题转化为回归问题,直接预测边界框的位置和类别概率,大大提高了检测速度。YOLOv1: 首次提出YOLO的核心思想,将图像分割成网格,每个网格预测边界框和类别概率。YOLOv2: 引入了批量归一化、锚框等改进,提高了检测精度。YOLOv3: 采用多尺度预测,增强了对小目标的检测能力。

步子哥的博客 1091

Android 数据库操作

在数据库中保存了三个字段:id,name,url 首先实现数据库的操作类:代码如下[code="java"]import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDat...

jingzitakk66的专栏 192

万字长文:YOLOv5+RK3588 NPU多线程加速全攻略——从理论到部署的终极优化

RK3588 NPU多线程加速优化教程摘要 本教程深入讲解了如何利用线程池技术优化RK3588 NPU上的YOLO目标检测模型推理性能。RK3588内置3个NPU核心,理论算力达6TOPS,为多线程优化提供了硬件基础。教程详细解析了线程池的核心组件(任务队列、工作线程、同步机制)和实现架构,包括类设计、初始化流程、工作线程逻辑(任务获取、NPU推理、结果存储三个阶段)以及任务提交/获取机制。通过预分配模型实例、线程绑定、流量控制等优化手段,实现了从单线程28FPS到多线程120FPS的显著性能提升,为边缘A

LXY_LOVE36的博客 1101

YOLOv11改进,YOLOv11添加DCNv4可变性卷积(windows系统成功编译),二次创新C3k2结构,全网最详细教程

引入了可变形卷积 v4 (DCNv4),这是一种为广泛视觉应用设计的高效且有效的操作算子。DCNv4通过两项关键增强解决了其前身DCNv3的局限性:1. 移除空间聚合中的softmax归一化,以增强其动态特性和表达能力;2. 优化内存访问以最小化冗余操作,从而加速计算。这些改进使得DCNv4相比DCNv3显著加快了收敛速度,并且处理速度大幅提升,前向传播速度超过三倍。DCNv4在多个任务中表现出色,包括图像分类、实例和语义分割,特别是在图像生成方面表现突出。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 2666

Android ContentProvider 填删改查 实例

  ContentProvider 操作类 import java.util.Calendar; import java.util.HashMap; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValue...

weixin_34221775的博客 165

STM32F103 -- LIN从机通讯 -- 程序代码 -- 详细讲解版(2万字长文)

主要代码分为3个文件,usart文件是对GPIO端口和串口Lin模式的初始化,lin_buffer文件是对串口环形缓冲区的编写,lin_driver文件是Lin从机模式驱动代码。通过这三个文件的代码便可实现STM32F103的LIN从机通讯。

晴朗luo的博客 1万+

深入探索Android应用数据共享之ContentProvider

这样可以确保数据的安全性。ContentProvider是Android系统提供的一种在应用之间共享数据的机制,也是 Android 的四大组件之一,可见它在 Android 中的作用非同小可。例如,开发者可以结合Room或SQLite,将ContentProvider作为应用内部数据库的对外接口,为上层的ViewModel和UI层提供标准化的数据访问方式。ContentProvider 可以理解为 Android 应用对外开放的接口,只要是符合它所定义的 URI 格式的请求,均可以正常访问执行操作。

w风雨无阻w的专栏 1851

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

安卓 ContentProvider 详解:跨应用数据共享的核心方案

ContentProvider 是 Android 系统提供的一种跨进程数据共享机制,它允许一个应用(数据提供方)通过统一的接口向其他应用(数据使用方)暴露自己的数据,同时保证数据访问的安全性。下面通过一个完整案例,实现一个提供用户数据(基于 SQLite)的 ContentProvider,并演示如何跨应用访问。// 1. 定义常量// 唯一标识// 用户表Uri// 2. 初始化UriMatcherstatic {// 匹配用户集合// 匹配单个用户// 3. 数据库帮助类实例。

2501_93564530的博客 1461

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

安卓应用间的数据共享:ContentProvider、ContentResolver全解

全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓应用间的数据共享:ContentProvider、ContentResolver全解 ContentProvider用于应用程序向系统公开数据,ContentResolver用于查询这些数据。 Uri代表要操作的数据源,Android上可用的每种资源 - 图像、视频片段等都可以用Uri来表示。 URI一般由三部分组成:访问

1176

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Android读书笔记之ContentProvider实现数据共享

Android读书笔记之ContentProvider实现数据共享 一.ContentProvider简介 让一个应用程序直接去操作另一个应用程序所记录的数据,比如操作它所记录的SharedPreferences, 文件或数据库等。这种方式不仅比较麻烦,而且还存在严重的安全漏洞。 如何完整开发一个ContentProvider: 1.定义自己的ContentProvider类,该类需要继承Android提供的ContentProvider基类。 2.在AndroidManifest.xml文件中注册这个Co

Danny_llp的博客 1710

[安卓] 深度掌握Android ContentProvider:数据共享与安全管理

ContentProvider是Android中用于在不同应用程序之间共享数据的组件,它提供了一套标准化的接口,允许应用安全地访问其他应用的数据,同时保护数据的隐私和安全。数据封装:隐藏底层数据存储细节统一接口:提供标准的CRUD操作接口权限控制:通过权限机制保护数据安全数据共享:实现跨应用数据访问观察者模式:支持数据变化通知1. 数据库帮助类context,null,) {// 表名// 列名// 创建联系人表。

2301_77946674的博客 1333

Android学习19--使用ContentProvider实现数据共享

1、数据共享标准:ContentProvider简介 ContentProvider是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据:其它应用程序使用ContentResolver根据Uri去访问操作指定数据。 ContentProvider也是Android应用的四大组件之一,与Activity、Serv

lixj517990544的专栏 3517

Android学习总结之ContentProvider跨应用数据共享

ContentProvider的面试题和代码实战

2301_80329517的博客 1520

Android学习之 使用ContentProvider实现数据共享

ContentProvider的基本概念 : 1.ContentProvider为存储和读取数据提供了统一的接口 2.使用ContentProvider,使应用程序间可以实现数据共享 3.android内置的许多数据都是使用ContentProvider形式,供开发者调用的(如视频,音频,图片,通讯录,短信等) 一、 使用ContentProvider(内容

小吕丶Code阶区 2821

深入解析Android中ContentProvider数据共享原理

ContentProvider是Android四大组件之一,专门用于不同应用之间进行数据共享。它通过定义一个统一的接口,允许其他应用访问或修改其内部数据,而无需直接暴露数据存储的细节。这种设计模式不仅提高了数据的安全性,也增强了应用间的解耦性。ContentProvider的核心思想是将数据封装在一个抽象层中,对外提供标准的CRUD(创建、读取、更新、删除)操作接口。这些接口通过URI(统一资源标识符)来标识具体的数据集合,使得数据的访问更加灵活和动态。

534

Android数据共享之ContentProvider类

ContentProvider: 用于不同的应用程序之间实现“数据共享”功能。。 为了把自己程序的数据(一般是数据库)提供给其他应用程序,就通过ContentProvider提供的方法. ContentResolver: 数据调用者,ContentProvider将数据发布出来, 通过ContentResolver对象结合Uri进行调用。通过ContentResolver对象可以调用Content...

hdquan321的博客 328
上一篇: android 工程常见问题解决
下一篇: android 数据库操作
onlywaitforyou
博客等级 码龄15年 6粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值