- 浏览: 331863 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
xuanyuanxiaoxue:
...
Android - LayoutInflater -
柴兴博:
不错 多谢
Android 悬浮Activity并可拖动(访悬浮歌词) -
di1984HIT:
写的很好,我收藏一下。
java之动态代理模式(JDK和cglib) -
chinacssnj:
待测试,明天测,测试的结果发给大家
网络开发上传文件到服务器 -
fx_199182:
...
Android之MediaPlayer
Android是如何实现应用程序之间数据共享的?一个应用程序可以将自己的数据完全暴露出去,外界更本看不到,也不用看到这个应用程序暴露的数据是如何存储的,或者是使用数据库还是使用文件,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和这个程序里的数据打交道,例如:添加(insert)、删除(delete)、查询(query)、修改(update),当然需要一定的权限才可以。
如何将应用程序的数据暴露出去? Android提供了ContentProvider,一个程序可以通过实现一个Content provider的抽象接口将自己的数据完全暴露出去,而且Content providers是以类似数据库中表的方式将数据暴露。Content providers存储和检索数据,通过它可以让所有的应用程序访问到,这也是应用程序之间唯一共享数据的方法。要想使应用程序的数据公开化,可通过2种方法:创建一个属于你自己的Content provider或者将你的数据添加到一个已经存在的Content provider中,前提是有相同数据类型并且有写入Content provider的权限,对于Content Provider,最重要的就是数据模型(data model) 和 URI。
1.数据模型
Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。
2.URI
URI,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(data set)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。
在几乎所有的Content Provider 的操作中都会用到URI,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。
首先来介绍如何访问Content Provider中的数据,访问 Content Provider中的数据主要通过ContentResolver对象,ContentResolver类提供了成员方法可以用来对Content Provider 中的数据进行查询、插入、修改和删除等操作。 以查询为例,查询一个 Content Provider 需要掌握如下的信息。
唯一标识Content Provider 的URI
需要访问的数据字段名称。
该数据字段的数据类型
提示: 如果需要访问特定的某条数据记录,只需该记录的ID 即可。
查询Content Provider的方法有两个:ContentResolver的query() 和 Activity 对象的 managedQuery(),二者接收的参数均相同,返回的都是Cursor 对象,唯一不同的是 使用managedQuery 方法可以让Activity 来管理 Cursor 的生命周期。
被管理的Cursor 会在 Activity进入暂停状态的时候调用自己的 deactivate 方法自行卸载,而在Activity回到运行状态时会调用自己的requery 方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象想被Activity管理,可以调用Activity的 startManagingCursor方法来实现。
Android应用程序可以使用文件或SqlLite数据库来存储数据。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标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在<provider> 元素的 authorities属性中说明:
<provider name=”.TransportationProvider” authorities=”com.example.transportationprovider” . . . >
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. |
下面利用实例做进一步说明:
1:NotePad
package com.yarin.android.Examples_06_07; import android.net.Uri; import android.provider.BaseColumns; public class NotePad { //ContentProvider的uri public static final String AUTHORITY = "com.google.provider.NotePad"; private NotePad(){} // 定义基本字段 public static final class Notes implements BaseColumns { private Notes(){} public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes"); // 新的MIME类型-多个 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note"; // 新的MIME类型-单个 public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note"; public static final String DEFAULT_SORT_ORDER = "modified DESC"; //字段 public static final String TITLE = "title"; public static final String NOTE = "note"; public static final String CREATEDDATE = "created"; public static final String MODIFIEDDATE = "modified"; } }
2:NotePadProvider
package com.yarin.android.Examples_06_07; import java.util.HashMap; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.Context; import android.content.UriMatcher; import android.content.res.Resources; import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; import com.yarin.android.Examples_06_07.NotePad.Notes; public class NotePadProvider extends ContentProvider { private static final String TAG = "NotePadProvider"; // 数据库名 private static final String DATABASE_NAME = "note_pad.db"; private static final int DATABASE_VERSION = 2; // 表名 private static final String NOTES_TABLE_NAME = "notes"; private static HashMap<String, String> sNotesProjectionMap; private static final int NOTES = 1; private static final int NOTE_ID = 2; private static final UriMatcher sUriMatcher; private DatabaseHelper mOpenHelper; //创建表SQL语句 private static final String CREATE_TABLE="CREATE TABLE " + NOTES_TABLE_NAME + " (" + Notes._ID + " INTEGER PRIMARY KEY," + Notes.TITLE + " TEXT," + Notes.NOTE + " TEXT," + Notes.CREATEDDATE + " INTEGER," + Notes.MODIFIEDDATE + " INTEGER" + ");"; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES); sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID); sNotesProjectionMap = new HashMap<String, String>(); sNotesProjectionMap.put(Notes._ID, Notes._ID); sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE); sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE); sNotesProjectionMap.put(Notes.CREATEDDATE, Notes.CREATEDDATE); sNotesProjectionMap.put(Notes.MODIFIEDDATE, Notes.MODIFIEDDATE); } private static class DatabaseHelper extends SQLiteOpenHelper { //构造函数-创建数据库 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 notes"); onCreate(db); } } @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 NOTES: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); break; case NOTE_ID: qb.setTables(NOTES_TABLE_NAME); qb.setProjectionMap(sNotesProjectionMap); qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } String orderBy; if (TextUtils.isEmpty(sortOrder)) { orderBy = NotePad.Notes.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 String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITEM_TYPE; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override //插入数据库 public Uri insert(Uri uri, ContentValues initialValues) { if (sUriMatcher.match(uri) != NOTES) { 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(NotePad.Notes.CREATEDDATE) == false) { values.put(NotePad.Notes.CREATEDDATE, now); } if (values.containsKey(NotePad.Notes.MODIFIEDDATE) == false) { values.put(NotePad.Notes.MODIFIEDDATE, now); } if (values.containsKey(NotePad.Notes.TITLE) == false) { Resources r = Resources.getSystem(); values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled)); } if (values.containsKey(NotePad.Notes.NOTE) == false) { values.put(NotePad.Notes.NOTE, ""); } SQLiteDatabase db = mOpenHelper.getWritableDatabase(); long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values); if (rowId > 0) { Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(noteUri, null); return noteUri; } throw new SQLException("Failed to insert row into " + uri); } @Override //删除数据 public int delete(Uri uri, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count = db.delete(NOTES_TABLE_NAME, where, whereArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(NOTES_TABLE_NAME, Notes._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 int update(Uri uri, ContentValues values, String where, String[] whereArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count = db.update(NOTES_TABLE_NAME, values, where, whereArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs); break; default: throw new IllegalArgumentException("Unknown URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }
3:Activity01
package com.yarin.android.Examples_06_07; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.Gravity; import android.widget.Toast; public class Activity01 extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /* 插入数据 */ ContentValues values = new ContentValues(); values.put(NotePad.Notes.TITLE, "title1"); values.put(NotePad.Notes.NOTE, "NOTENOTE1"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); values.clear(); values.put(NotePad.Notes.TITLE, "title2"); values.put(NotePad.Notes.NOTE, "NOTENOTE2"); getContentResolver().insert(NotePad.Notes.CONTENT_URI, values); /* 显示 */ displayNote(); } private void displayNote() { String columns[] = new String[] { NotePad.Notes._ID, NotePad.Notes.TITLE, NotePad.Notes.NOTE, NotePad.Notes.CREATEDDATE, NotePad.Notes.MODIFIEDDATE }; Uri myUri = NotePad.Notes.CONTENT_URI; Cursor cur = managedQuery(myUri, columns, null, null, null); if (cur.moveToFirst()) { String id = null; String title = null; do { id = cur.getString(cur.getColumnIndex(NotePad.Notes._ID)); title = cur.getString(cur.getColumnIndex(NotePad.Notes.TITLE)); Toast toast=Toast.makeText(this, "TITLE:"+id + "NOTE:" + title, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 40); toast.show(); } while (cur.moveToNext()); } } }
4:AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yarin.android.Examples_06_07" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name="NotePadProvider" android:authorities="com.google.provider.NotePad"/> <activity android:name=".Activity01" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> <intent-filter> <data android:mimeType="vnd.android.cursor.dir/vnd.google.note"/> </intent-filter> <intent-filter> <data android:mimeType="vnd.android.cursor.item/vnd.google.note"/> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="5"/> </manifest>
部分内容摘自:http://java-admin.iteye.com/blog/803394
发表评论
-
Android中AsyncTask的简单用法
2012-01-13 16:00 1166在开发Android移动客户端的时候往往要使用多线程来进行操 ... -
Android应用的自动升级、更新模块的实现 .
2011-11-16 14:01 678http://www.eoeandroid.com/threa ... -
一个APK反编译利器Apktool
2011-11-16 13:54 1588一个APK反编译利器Apktool APK 本地化 ... -
自定义Android标题栏TitleBar布局
2011-11-14 14:13 1257很多网友发现自己Android程序的标题栏TitleBar区域 ... -
Android GPS获取地理位置 .
2011-11-14 14:11 859import android.app.Activity; i ... -
android ListView详解
2011-11-14 13:48 1059在android开发中ListView是比较常用的组件,它以列 ... -
Android源码地址
2011-11-12 19:14 1052http://blog.csdn.net/ilittleone ... -
android之File
2011-11-11 22:39 20091:Fileservice package cn.itcas ... -
Android知识补漏
2011-11-09 22:33 01:AndroidManifiest.xml < ... -
深入剖析Android消息机制
2011-11-09 14:13 967在Android中,线程内部或者线程之间进行信息交互时经常会使 ... -
Android之Handler详解(四)
2011-11-09 14:00 1292d、自己创建新的线程,然后在新线程中创建Looper,主线程调 ... -
Android之Handler详解(三)
2011-11-09 13:58 1370c、将消息队列绑定到子线程上,主线程只管通过Handl ... -
Android之Handler详解(二)
2011-11-09 13:54 1667二:sendMessage版本的Handl ... -
Android之Handler详解(一)
2011-11-09 13:22 2293一个Handler允许你发送和处理消息(Message)以及 ... -
关于StartActivityForResult方法的使用
2011-10-31 17:11 1106根据方法名可知 这个方法是要得到启动后的Activity返回的 ... -
Android 悬浮Activity并可拖动(访悬浮歌词)
2011-10-24 16:23 2106天天动听, 这款Android手机上的音乐播放器,相信不少朋友 ... -
Android GWES
2011-10-24 16:13 1199第八章 Android GWES 8.1 View Syst ... -
Android系统服务-WindowManager
2011-10-24 16:10 1448WindowManager是Android中一个重要的服务 ... -
http通信
2011-10-15 17:31 1099HTTP(HyperText Transfer Proto ... -
android网络与通信(三种网络接口简述 )
2011-10-15 17:27 1439标准Java接口 java.net.*提供与联网有关的类 ...
相关推荐
Android:Content Provider的使用。 1、Content Provider 简介 2、使用现成的Content Provider 3、定义自己的Content Provider 一、Content Provider 简介 我们说Android应用程序的四个核心组件是:Activity、...
在Android系统中,Content Provider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地共享数据。本文将深入探讨如何使用Content Provider组件来访问和操作Android设备上的通讯录,特别是针对...
**Android内容提供者(Content Provider)详解** 在Android系统中,数据共享是应用程序间交互的重要方式,而Android内容提供者(Content Provider)正是实现这一功能的关键组件。Content Provider作为Android四大...
MediaProvider是Android系统中用于管理媒体文件的Content Provider,而MediaScanner则是与之协同工作的一个后台服务,它负责扫描媒体文件并更新系统数据库。 首先,从AndroidManifest.xml文件的分析可知,...
3. **数据存储**:Android支持多种数据存储方式,包括Shared Preferences、SQLite数据库、文件系统和Content Provider。书中将深入讨论这些存储方式的适用场景、优缺点及使用方法。 4. **网络通信**:Android应用...
Android四大组件详解 Android 应用程序由一些零散的有联系的组件组成,通过一个工程 manifest 绑定在一起。在 manifest 中,描述了每一个组件以及组件的作用,其中有 6 个组件,它们是 Android 应用程序的基石: ...
### 四大组件详解:Activity、Service、Content Provider与Broadcast Receiver #### 一、Activity **定义:** Activity是Android应用程序中的四大基本组件之一,它代表一个屏幕界面,用户可以直接与其进行交互。每...
第8章 Android广播事件处理 Broadcast Receiver 第9章 Android中的数据存取 第10章 Content Provider 第11章 Android中的多媒体应用 第12章 Android中的图形图像 第13章 Android中的互联网应用 第14章 Android中的...
根据提供的标题“Android应用开发详解.pdf”以及描述“Android应用开发详解.pdf”,我们可以推断这份文档主要涵盖了关于Android平台上的应用程序开发的相关知识和技术。虽然提供的部分内容似乎并不包含具体的信息,...
基于Android FileProvider 属性配置详解及FileProvider多节点问题 Android FileProvider 是 Android 7.0 及更高版本中用于文件共享的组件,主要用于解决 Android 7.0 及更高版本中私有存储的限制问题。在 Android ...
根据提供的信息,“Android应用开发详解”这本书被描述为非常适合初学者的一本书籍,也是某位读者接触到的第一本关于Android开发的书籍。从标题和描述中我们可以推断出这本书主要介绍了Android应用开发的基础知识...
对于数据存储,Android提供了多种方式,包括Shared Preferences、SQLite数据库、文件系统和Content Provider。理解这些存储机制的优缺点,以及在何种场景下选择哪种方式,是提升应用性能的关键。 此外,你还会接触...
《Android应用开发详解》 作者:郭宏志 编著 内容简介 本书分为三个部分,包括基础篇、技术篇和应用篇。由浅入深地讲述了Android应用开发的方方面面。 第一篇 基础篇 第1章 Android概述 Android概述,讲述了...
此外,Android的系统服务,如Activity Manager、Window Manager、Content Provider等,都与底层接口有密切关系。理解这些服务的工作原理和调用方式,可以帮助开发者更好地实现系统级功能,例如权限管理、多任务调度...
**Android数据存储之FileProvider详解** 在Android应用开发中,数据存储是一个不可或缺的部分。FileProvider是一种特殊类型的ContentProvider,它允许应用程序安全地分享私有文件,如图片、视频或其他二进制数据,...
8. **内容提供者(Content Provider)**:内容提供者是Android中用于共享数据的机制,允许不同应用之间读写数据。例如,联系人应用就是通过内容提供者暴露其数据供其他应用访问。 9. **多线程与AsyncTask**:...
【Android课程:Content Provider详解】 在安卓开发中,Content Provider是一个至关重要的组件,它是四大组件之一,负责在应用程序之间共享数据。本课程将深入探讨Content Provider的原理与实践,帮助开发者掌握这...
第10章:可能讲解了Android中的内容提供者(Content Provider),它是Android四大组件之一,用于在不同应用间共享数据。这章可能包含如何创建和使用Content Provider的步骤。 第5章:这章可能涵盖Android的生命周期...