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接口,应用程序可以无需直接与底层数据存储打交道,就实现数据的共享。 阅读详情

相关推荐

保姆级教程:手把手教你从NASA Earthdata免费下载ASTER L2地表温度数据(附shp文件拖拽技巧)

本文提供了一份详细的ASTER L2地表温度数据下载指南,涵盖从NASA Earthdata注册、数据定位到shp文件拖拽技巧的全流程。特别针对新手常见问题如邮箱选择、密码设置、云量筛选等给出实用解决方案,帮助用户高效获取遥感数据并避免常见陷阱。

weixin_42662605的博客 425

浅谈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

【机械视觉】C#+VisionPro实战:位深图(CogImage8Grey)与Bitmap互转技巧及工业检测应用

本文详细介绍了在工业检测中如何使用C#和VisionPro实现位深图(CogImage8Grey)与Bitmap的高效互转技巧。通过实战代码示例和工业应用案例,帮助开发者解决图像处理中的常见问题,提升检测精度和系统性能,适用于半导体、汽车零部件等高精度检测场景。

weixin_29250573的博客 186

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

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

王涛的博客 5727

Mininet 2.2.1 图形可视化界面使用注意事项

前言 关于mininet的安装,网上教程不少,大致可以参考以下这篇文章: https://blog.youkuaiyun.com/linyixiao88/article/details/65651390 安装的时候,也可以不必根据上面这篇文章这么麻烦,直接sudo apt-get install mininet,即可。 Mininet可视化 Mininet 2.2.0以上版本内置了...

裕东方的博客 4191

GB28181安防平台未授权访问漏洞:原理、复现与修复指南

未授权访问漏洞是Web安全中常见的访问控制缺陷,其本质在于应用在提供对敏感功能或数据的访问前,未能对请求者的身份和权限进行充分验证。从技术原理上看,这类漏洞常源于拦截器配置错误、安全注解遗漏或自定义校验逻辑缺陷,导致本应受保护的API接口被意外暴露。在工程实践中,此类漏洞危害巨大,攻击者无需登录即可直接访问系统核心接口,可能引发敏感信息泄露、权限提升甚至系统接管。尤其在安防监控、物联网管理平台等场景中,一旦涉及用户管理接口(如`/api/user/**`),风险会急剧放大。本文以GB28181视频监控管理平

weixin_30271335的博客 439

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

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

文科程序猿 1115

控制障碍函数(Control Barrier Function,CBF) 一、定义

介绍控制障碍函数

Lyajpunov的博客 2万+

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

ArcGIS中如何计算多个点到特定线的最短距离

现有一个点图层和一个面图层,怎么来计算这些点到这个面图层,两个面的公共边的最短直线距离呢? 1.首先得将两个图层都转为 投影坐标系 打开工具箱-数据管理工具-要素-面转线 ​ ​ 2.将面图层设为输入要素 注意要将“识别和存储面邻域信息”勾选 ​ 3.面转线成功后 打开线属性表,线图层拥有了 LEFT_FID和RIGHT_FID两个字段 ​ 4.按属性选择,表达式中输入 “LEFT_FID”<>-1 即可选出两个面的公共边 ​再将选...

GIS蒲公英的博客 6715

RAG效果调优清单(命中率提升3倍)

本文提出了一套工程可落地的RAG(检索增强生成)模型组合方案,强调通过最优组合实现效果、成本和扩展性的平衡。核心架构包括Embedding模型、向量数据库检索、Rerank模型和LLM生成四个环节,推荐了四种具体组合方案:本地最优性价比(bge+reranker+Qwen 7B)、效果优先(bge-large+reranker+14B模型)、高并发(轻量模型+vLLM)和中英混合(多语言模型)。文章指出Embedding决定检索下限,Rerank提升准确率上限,LLM影响最终体验,并提供了不同场景的优化策略

刘一说的IT专栏 523

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

VSS shielding线可以floating吗?

shielding vss不打孔,就相当于dummy metal,如果周围有其他干扰线,他们影响了这段dummy metal,这段dummy metal仍然会对目标线产生干扰,bug的是,工具知道这段dummy是vss,那么计算寄生的时候仍然把它当vss,就有可能噪声没有完全消除,而用户又看不见。而真正接地的线,相当于一直是0,就不会对目标线产生干扰,一般加shield是在route之前,这时候shield能尽量覆盖目标线,等到绕线后再加就会出现shield只覆盖到一部分目标线的情况。

m0_61544122的博客 6638

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

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

w风雨无阻w的专栏 1851

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

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

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

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

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

2501_93564530的博客 1461

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

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

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

1176

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

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

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、付费专栏及课程。

余额充值