热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

android内容提供者ContentProvider

内容提供者Android四大组件之一应用的数据库是不允许其他应用访问的内容提供者的作用就是让别的应用访问到你的私有数据自定义内容提供者,继承ContentProvi

内容提供者
  • Android四大组件之一
  • 应用的数据库是不允许其他应用访问的
  • 内容提供者的作用就是让别的应用访问到你的私有数据
  • 自定义内容提供者,继承ContentProvider类,重写增删改查方法,在方法中写增删改查数据库的代码,举例增方法

一般不需要自定义,原因是我们一般是拿第三方提供的数据,跟广播类似

@Override
public Uri insert(Uri uri, ContentValues values) {db.insert("person", null, values);return uri;
}

  • 在清单文件中定义内容提供者的标签,注意必须要有authorities属性,这是内容提供者的主机名,功能类似地址

<provider android:name&#61;"com.xxx.contentprovider.PersonProvider"android:authorities&#61;"com.xxx.person"android:exported&#61;"true">provider>

  • 创建一个其他应用&#xff0c;访问自定义的内容提供者&#xff0c;实现对数据库的插入操作

public void click(View v){//得到内容分解器对象ContentResolver cr &#61; getContentResolver();ContentValues cv &#61; new ContentValues();cv.put("name", "小方");cv.put("phone", 138856);cv.put("money", 3000);//url:内容提供者的主机名cr.insert(Uri.parse("content://com.xxx.person"), cv);
}

UriMatcher


  • 用于判断一条uri跟指定的多条uri中的哪条匹配
  • 添加匹配规则

//创建uri匹配器
UriMatcher um &#61; new UriMatcher(UriMatcher.NO_MATCH);{
//指定多条uri
um.addURI("com.xxx.person", "person", PERSON_CODE);
um.addURI("com.xxx.person", "company", COMPANY_CODE);
//#号可以代表任意数字
um.addURI("com.xxx.person", "person/#", QUERY_ONE_PERSON_CODE);
* 通过Uri匹配器可以实现操作不同的表
}&#64;Override
public Uri insert(Uri uri, ContentValues values) {if(um.match(uri) &#61;&#61; PERSON_CODE){db.insert("person", null, values);}else if(um.match(uri) &#61;&#61; COMPANY_CODE){db.insert("company", null, values);}else{throw new IllegalArgumentException();}return uri;
}

  • 如果路径中带有数字&#xff0c;把数字提取出来的api

int id &#61; (int) ContentUris.parseId(uri);



短信数据库
  • 只需要关注sms表
  • 只需要关注4个字段
    • body&#xff1a;短信内容
    • address:短信的发件人或收件人号码&#xff08;跟你聊天那哥们的号码&#xff09;
    • date&#xff1a;短信时间
    • type&#xff1a;1为收到&#xff0c;2为发送

读取系统短信&#xff0c;首先查询源码获得短信数据库内容提供者的主机名和路径&#xff0c;然后访问内容提供者

ContentResolver cr &#61; getContentResolver();
Cursor c &#61; cr.query(Uri.parse("content://sms"), new String[]{"body", "date", "address", "type"}, null, null, null);
while(c.moveToNext()){String body &#61; c.getString(0);String date &#61; c.getString(1);String address &#61; c.getString(2);String type &#61; c.getString(3);System.out.println(body&#43;";" &#43; date &#43; ";" &#43; address &#43; ";" &#43; type);
}

插入系统短信

ContentResolver cr &#61; getContentResolver();
ContentValues cv &#61; new ContentValues();
cv.put("body", "您尾号为XXXX的招行储蓄卡收到转账1,000,000人民币");
cv.put("address", 95555);
cv.put("type", 1);
cv.put("date", System.currentTimeMillis());
cr.insert(Uri.parse("content://sms"), cv);

  • 插入查询系统短信需要注册权限



联系人数据库
  • raw_contacts表&#xff1a;
    • contact_id&#xff1a;联系人id
  • data表&#xff1a;联系人的具体信息&#xff0c;一个信息占一行
    • data1&#xff1a;信息的具体内容
    • raw_contact_id&#xff1a;联系人id&#xff0c;描述信息属于哪个联系人
    • mimetype_id&#xff1a;描述信息是属于什么类型
  • mimetypes表&#xff1a;通过mimetype_id到该表查看具体类型

读取联系人


  • 先查询raw_contacts表拿到联系人id

Cursor cursor &#61; cr.query(Uri.parse("content://com.android.contacts/raw_contacts"), new String[]{"contact_id"}, null, null, null);

  • 然后拿着联系人id去data表查询属于该联系人的信息

Cursor c &#61; cr.query(Uri.parse("content://com.android.contacts/data"), new String[]{"data1", "mimetype"}, "raw_contact_id &#61; ?", new String[]{contactId}, null);

  • 得到data1字段的值&#xff0c;就是联系人的信息&#xff0c;通过mimetype判断是什么类型的信息

while(c.moveToNext()){String data1 &#61; c.getString(0);String mimetype &#61; c.getString(1);if("vnd.android.cursor.item/email_v2".equals(mimetype)){contact.setEmail(data1);}else if("vnd.android.cursor.item/name".equals(mimetype)){contact.setName(data1);}else if("vnd.android.cursor.item/phone_v2".equals(mimetype)){contact.setPhone(data1);}
}

插入联系人


  • 先查询raw_contacts表&#xff0c;确定新的联系人的id应该是多少
  • 把确定的联系人id插入raw_contacts表

cv.put("contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/raw_contacts"), cv);

  • 在data表插入数据
    • 插3个字段&#xff1a;data1、mimetype、raw_contact_id

cv &#61; new ContentValues();
cv.put("data1", "赵六");
cv.put("mimetype", "vnd.android.cursor.item/name");
cv.put("raw_contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/data"), cv);cv &#61; new ContentValues();
cv.put("data1", "1596874");
cv.put("mimetype", "vnd.android.cursor.item/phone_v2");
cv.put("raw_contact_id", _id);
cr.insert(Uri.parse("content://com.android.contacts/data"), cv);



内容观察者
  • 当数据库数据改变时&#xff0c;内容提供者会发出通知&#xff0c;在内容提供者的uri上注册一个内容观察者&#xff0c;就可以收到数据改变的通知

cr.registerContentObserver(Uri.parse("content://sms"), true, new MyObserver(new Handler()));class MyObserver extends ContentObserver{public MyObserver(Handler handler) {super(handler);// TODO Auto-generated constructor stub}//内容观察者收到数据库发生改变的通知时&#xff0c;会调用此方法&#64;Overridepublic void onChange(boolean selfChange) {}}

  • 在内容提供者中发通知的代码

ContentResolver cr &#61; getContext().getContentResolver();
//发出通知&#xff0c;所有注册在这个uri上的内容观察者都可以收到通知
cr.notifyChange(uri, null);


推荐阅读
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • 本文介绍了一种自定义的Android圆形进度条视图,支持在进度条上显示数字,并在圆心位置展示文字内容。通过自定义绘图和组件组合的方式实现,详细展示了自定义View的开发流程和关键技术点。示例代码和效果展示将在文章末尾提供。 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • 本文深入解析了WCF Binding模型中的绑定元素,详细介绍了信道、信道管理器、信道监听器和信道工厂的概念与作用。从对象创建的角度来看,信道管理器负责信道的生成。具体而言,客户端的信道通过信道工厂进行实例化,而服务端则通过信道监听器来接收请求。文章还探讨了这些组件之间的交互机制及其在WCF通信中的重要性。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 在使用 Qt 进行 YUV420 图像渲染时,由于 Qt 本身不支持直接绘制 YUV 数据,因此需要借助 QOpenGLWidget 和 OpenGL 技术来实现。通过继承 QOpenGLWidget 类并重写其绘图方法,可以利用 GPU 的高效渲染能力,实现高质量的 YUV420 图像显示。此外,这种方法还能显著提高图像处理的性能和流畅性。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 卓盟科技:动态资源加载技术的兼容性优化与升级 | Android 开发者案例分享
    随着游戏内容日益复杂,资源加载过程已不仅仅是简单的进度显示,而是连接玩家与开发者的桥梁。玩家对快速加载的需求越来越高,这意味着开发者需要不断优化和提升动态资源加载技术的兼容性和性能。卓盟科技通过一系列的技术创新,不仅提高了加载速度,还确保了不同设备和系统的兼容性,为用户提供更加流畅的游戏体验。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • 本文探讨了如何在C#应用程序中通过选择ComboBox项从MySQL数据库中检索数据值。具体介绍了在事件处理方法 `comboBox2_SelectedIndexChanged` 中可能出现的常见错误,并提供了详细的解决方案和优化建议,以确保数据能够正确且高效地从数据库中读取并显示在界面上。此外,还讨论了连接字符串的配置、SQL查询语句的编写以及异常处理的最佳实践,帮助开发者避免常见的陷阱并提高代码的健壮性。 ... [详细]
  • REST与RPC:选择哪种API架构风格?
    在探讨REST与RPC这两种API架构风格的选择时,本文首先介绍了RPC(远程过程调用)的概念。RPC允许客户端通过网络调用远程服务器上的函数或方法,从而实现分布式系统的功能调用。相比之下,REST(Representational State Transfer)则基于资源的交互模型,通过HTTP协议进行数据传输和操作。本文将详细分析两种架构风格的特点、适用场景及其优缺点,帮助开发者根据具体需求做出合适的选择。 ... [详细]
author-avatar
cheer57_275
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有