Android是如何实现应用程序之间数据共享的?一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和这个程序里的数据打交道,例如:添加(insert)、删除(delete)、查询(query)、修改(update),当然需要一定的权限才可以。

如何将应用程序的数据暴露出去? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限。

如何通过一套标准及统一的接口获取其他应用程序暴露的数据?Android提供了ContentResolver,外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据。

当前篇主要说明,如何获取其它应用程序共享的数据,比如获取Android 手机电话薄中的信息。

什么是URI?

在学习如何获取ContentResolver前,有个名词是必须了解的:URI。URI是网络资源的定义,在Android中赋予其更广阔的含义。

将其分为A,B,C,D 4个部分:

A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的;

B:URI的标识,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的  类名。这个标识在 元素的 authorities属性中说明:

C:路径,Content Provider使用这些路径来确定当前需要生什么类型的数据,URI中可能不包括路径,也可能包括多个;

D:如果URI中包含,表示需要获取的记录的ID;如果没有ID,就表示返回全部;

由于URI通常比较长,而且有时候容易出错,切难以理解。所以,在Android当中定义了一些辅助类,并且定义了一些常量来代替这些长字符串,例如:People.CONTENT_URI

ContentResolver 介绍说明

看完这些介绍,大家一定就明白了,ContentResolver是通过URI来查询ContentProvider中提供的数据。除了URI以外,还必须知道需要获取的数据段的名称,以及此数据段的数据类型。如果你需要获取一个特定的记录,你就必须知道当前记录的ID,也就是URI中D部分。

前面也提到了Content providers是以类似数据库中表的方式将数据暴露出去,那么ContentResolver也将采用类似数据库的操作来从Content providers中获取数据。现在简要介绍ContentResolver的主要接口,如下:

返回值

函数声明

final Uri

insert(Uri url, ContentValues values)Inserts a row into a table at the given URL.

final int

delete(Uri url, String where, String[] selectionArgs)Deletes row(s) specified by a content URI.

final Cursor

query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)Query the given URI, returning a Cursor over the result set.

final int

update(Uri uri, ContentValues values, String where, String[] selectionArgs)Update row(s) in a content URI.

看到这里,是否感觉与数据库的操作基本一样的?就是这样的,详细解析请参考了 Android SQLite解析 中的说明,不在此详细说明。

最后一个问题:如何获取ContentResolver?调用getContentResolver (),例如:ContentResolver cr = getContentResolver();

知道ContentResolver是通过ContentProvider来获取其他与应用程序共享的数据,那么ContentResolver与ContentProvider的接口应该差不多的。

其中ContentProvider负责

* 组织应用程序的数据;

* 向其他应用程序提供数据;

ContentResolver则负责

* 获取ContentProvider提供的数据;

* 修改/添加/删除更新数据等;

ContentProvider 是如何向外界提供数据的?

Android提供了ContentProvider,一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProviders是以类似数据库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URI来表示外界需要访问的“数据库”。至于如何从URI中识别出外界需要的是哪个“数据库”,这就是Android底层需要做的事情了,不在此详细说。简要分析下ContentProvider向外界提供数据操作的接口:

这些操作与数据库的操作基本上完全一样,在此不详细说,具体的解析可以参考 Android Sqlite解析 中的详细说明。需要特殊说明的地方是URI:

在URI的D部分可能包含一个_ID ,这个应该出现在SQL语句中的,可以以种特殊的方式出现,这就要求我们在提供数据的时候,需要来额外关注这个特殊的信息。Android  SDK推荐的方法是:在提供数据表字段中包含一个ID,在创建表时INTEGER PRIMARY KEY AUTOINCREMENT标识此ID字段。

ContentProvider 是如何组织数据的?

组织数据主要包括:存储数据,读取数据,以数据库的方式暴露数据。数据的存储需要根据设计的需求,选择合适的存储结构,首选数据库,当然也可以选择本地其他文件,甚至可以是网络上的数据。数据的读取,以数据库的方式暴露数据这就要求,无论数据是如何存储的,数据最后必须以数据的方式访问。

可能还有2个问题,是需要关注的。

1. ContentProvider是什么时候创建的,是谁创建的?访问某个应用程序共享的数据,是否需要启动这个应用程序?这个问题在 Android SDK中没有明确说明,但是从数据共享的角度出发,ContentProvider应该是Android在系统启动时就创建了,否则就谈不上数据共享了。这就要求在AndroidManifest.XML中使用元素明确定义。

2. 可能会有多个程序同时通过ContentResolver访问一个ContentProvider,会不会导致像数据库那样的“脏数据”?这个问题一方面需要数据库访问的同步,尤其是数据写入的同步,在AndroidManifest.XML中定义ContentProvider的时候,需要考虑是元素multiprocess属性的值;另外一方面Android在ContentResolver中提供了 notifyChange()接口,在数据改变时会通知其他ContentObserver,这个地方应该使用了观察者模式,在 ContentResolver中应该有一些类似register,unregister的接口。

至此,已经对ContentProvider提供了比较全面的分析,至于如何创建ContentProvider,可通过2种方法:创建一个属于你自己的ContentProvider或者将你的数据添加到一个已经存在的ContentProvider中,当然前提是有相同数据类型并且有写入 Content provider的权限。在Android SDK的sample中提供的 Notepad具体实例 中去看源代码!

制作ContentResolver实例

以上就完全介绍了如何获取、使用ContentResolver,启动Eclipes,制作一个完整的实例如下:

打开showcontent.java,修改如下:

package moandroid.showcontact;

import android.app.ListActivity;

import android.database.Cursor;

import android.os.Bundle;

import android.provider.Contacts.Phones;

import android.widget.ListAdapter;

import android.widget.SimpleCursorAdapter;

public class showcontact extends ListActivity {

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);

startManagingCursor(c);

ListAdapter adapter = new SimpleCursorAdapter(this,

android.R.layout.simple_list_item_2, c,

new String[] { Phones.NAME, Phones.NUMBER },

new int[] { android.R.id.text1, android.R.id.text2 });

setListAdapter(adapter);

}

}

然后在AndroidManifest.XML中元素前增加如下许可:

最后运行程序,在模拟器启动后,单击Menu返回到Home界面,打开Contacts选择Contacts标签页,添加2个联系人信息。返回到Home,选择moandroid.showcontact运行,刚添加的2个联系人信息将显示在界面上,如下:

总结说明

ContentResolver的使用极大的方便了应用程序之间共享数据,如何将应用程序的数据完全暴露给给他应用程序使用了

android中ContentResolver的使用

使用ContentResolver增删改查电话本信息,详细代码如下:

import android.app.ListActivity;

import android.content.ContentValues;

import android.database.Cursor;

import android.os.Bundle;

import android.provider.Contacts.People;

import android.support.v4.widget.SimpleCursorAdapter;

import android.widget.ListAdapter;

public class MainActivity extends ListActivity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

insert("tester1");

update("tester2", new String(People.NAME + "='tester1'"));

delete(new String(People.NAME + "='tester2'"));

select();

}

/*

* 向联系人列表中插入新的联系人

* @param name The value of People.NAME

*/

public void insert(String name) {

ContentValues ct = new ContentValues();

ct.put(People.NAME, name);

getContentResolver().insert(People.CONTENT_URI, ct);

}

/*

* 更新手机中指定的联系人

* @param name A new name for People.NAME

* @param where The update requirement.

*/

public void update(String name, String where) {

ContentValues ct = new ContentValues();

ct.put(People.NAME, name);

getContentResolver().update(People.CONTENT_URI, ct, where, null);

}

/*

* 删除手机中指定的联系人

* @param where The delete requirement.

*/

public void delete(String where) {

getContentResolver().delete(People.CONTENT_URI, where, null);

}

// 查找所有联系人

public void select() {

Cursor cursor = getContentResolver().query(People.CONTENT_URI,

new String[] { People._ID, People.NAME }, null, null, null);

ListAdapter adapter = new SimpleCursorAdapter(this,

android.R.layout.simple_list_item_1, cursor,

new String[] { People.NAME }, new int[] { android.R.id.text1 });

setListAdapter(adapter);

}

}

AndroidManifest.xml中添加如下权限:

resolver android,Android ContentResolver使用说明相关推荐

  1. android contentresolver权限,Android ContentResolver使用说明(2)

    在Android ContentResolver使用说明(1)中,已经说明了Android是如何实现应用程序之间数据共享的,并详细解析了如何获取其他应用程序共享的数据.ContentProviders ...

  2. android的contentResolver,contentProvider简介(附带个获取手机联系人及头像实例)

    介绍 android中有个ContentProvider(内容提供者)还有个ContentResolver(内容解析者) 简单来说,contentProvider就是将自己app的数据库共享,使得其他 ...

  3. Bmob关联Android,Android使用Bmob后台数据

    需求:将手机联系人同步到第三方的后台,再从第三方的后台将联系人数据同步到其他手机. 准备工作: 8A9B2E00-EC1C-4D7C-92EC-5D558AF435DB.png 2.进入某应用创建表与 ...

  4. Android android.uid.system的应用调用安装apk失败

    背景 最近项目开发过程中用到安装apk的功能.把从服务器下载下来的apk安装到机器中.安装过程中遇到的问题记录一下. 问题 安装过程中提示解析软件包时出现问题. 说明:本文是针对运行的apk在Mani ...

  5. Android - Android Studio 解决访问被墙的问题

    Android - Android Studio 解决访问被墙的问题 参考文章: (1)Android - Android Studio 解决访问被墙的问题 (2)https://www.cnblog ...

  6. OpenCV2.4.9 For Android + Android Studio (with gradle)配置教程

    OpenCV2.4.9 For Android + Android Studio (with gradle)配置教程 10 回复 / 9501 浏览 本页底部本帖地址 4king2 年前 - 2014 ...

  7. [Android]Android端ORM框架——RapidORM(v2.1)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/6020412.html [Android]Android端ORM ...

  8. [Android] Android开发优化之——使用软引用和弱引用

    Java从JDK1.2版本开始,就把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期.这四种级别由高到低依次为:强引用.软引用.弱引用和虚引用. 这里重点介绍一下软引用和弱引用. 如 ...

  9. android Android项目构建过程

    今天,简单讲讲android studio如何把写好的工程打包成apk的. 平时开发过程中我们通过android studio编写完成android项目之后直接点击 Run 'app'就可以在buil ...

最新文章

  1. 自我评价中专计算机600作文,自我评价作文600字
  2. Pycham_python 安装 gherkin
  3. mysql 常用命令集_mysql 常用命令集锦[绝对精华]
  4. Spring Cloud笔记
  5. SpringCloud-Eureka-服务注册是如何发起的
  6. 1716: 棒棒糖(暴力破解+优化)
  7. python pandas stack和unstack函数
  8. Quartz 2 定时任务(一):基本使用指南
  9. 03. Java NIO Channel 通道
  10. MySQL基础day05_MySQL数据库的备份与恢复-1-MySQL 5.6
  11. 思维导图 XMind 闯关之路(第02关)插入各类符号
  12. 正则html标签sublime,sublimetext 使用正则表达式匹配中文
  13. The Simplest Classifier: Histogram Comparison (最简单的分类器:直方图比较)
  14. 一位营销总监的辞职信(非常经典)
  15. SQL语句按照姓名首字母排序
  16. android 蓝牙触控笔,FiftyThree 53 Paper pencil 电容笔蓝牙触控笔 上手试用
  17. 转龚文祥的一篇文章:对看起来很美的网站要保持审慎的乐观
  18. unity粒子实现烟雾效果
  19. PostgreSQL 之 流复制主备库切换
  20. 从施耐德的M262 谈PLC 处理器的演进

热门文章

  1. removeAttr() 方法从被选元素移除一个或多个属性。
  2. HI3516a w25q128 spi flash无法启动问题
  3. 【天光学术】文艺美学论文:美学视角下“隐秀”与“幽玄”的对比分析(节选)
  4. CSS文字描边和倒影
  5. python post请求参数为list_利用post向后台传递数组或者list参数
  6. 音乐网站评论功能自动化测试实践
  7. PPC挑战上网本 多普达Touch HD使用评测
  8. cf711E. ZS and The Birthday Paradox
  9. 中录国际 php,第四届公共卫生与预防医学国际学术会议(PHPM 2021)
  10. ABAP开发关键字总结