- 浏览: 1698156 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (159)
- android 2D (13)
- android 控件 (12)
- android UI (16)
- android 动画 (5)
- android 线程 (3)
- android 数据存储 (15)
- android 基础 (13)
- android xml解析 (1)
- android 多媒体开发 (4)
- android 服务 (4)
- android 安全 (1)
- android WebKit以及相关 (3)
- android 电话 (2)
- android 首选项 (5)
- java基础 (16)
- java 多线程 (1)
- java IO (7)
- android工具使用篇 (1)
- android素材资源区 (1)
- android教程资源区 (1)
- java_android异常记录 (5)
- android问题记录 (1)
- android 推荐资源 (1)
- android 源码篇 (3)
- android SDK (2)
- Google Map For Android (2)
- android 项目问题 (2)
- git (0)
- android API 变化 (1)
- MyEclipse (2)
- Swing组件 (1)
- 活法 (0)
- 其它 (2)
- linux (7)
- 菜鸟的java学习笔记 (0)
- 网络 (0)
- 健康 (1)
- Eclipse在Ubuntu下无法双击启动解决办法 (1)
最新评论
-
tydyz:
引用
android SQLiteOpenHelper使用示例 -
tydyz:
[color=red][/color]
android SQLiteOpenHelper使用示例 -
tydyz:
[flash=200,200][flash=200,200][ ...
android SQLiteOpenHelper使用示例 -
梁家大丫头:
写的还不错,不过不是我需要的。
android 理解和使用自定义权限 -
love_java_cc:
牛逼,太齐全了,收藏
MyEclipse 快捷键大全
我们大家都知道让自己的数据和其它应用程序共享有两种方式:创建自己的Content Provider (即继承自Content Provider的子类) 或者是将自己的数据添加到已有的Content Provider中去,后者需要保证现有的Content Provider和自己的数据类型相同并且具有该 Content Provider的写入的权限。
如果需要创建一个Content Provider,则需要进行的工作主要分为以下3个步骤。
(1) 建立数据的存储系统
数据的存储系统可以由开发人员任意决定,一般来讲,大多数的Content Provider都通过Android的文件存储系统或SQLite 数据库建立自己的数据存储系统。
(2)扩展 ContentProvider类
开发一个继承自ContentProvider类的 子类代码来扩展 ContentProvider类,在这个步骤主要的工作是将要共享的数据包装并以ContentResolver 和 Cursor对象能够访问到的形式对外展示。具体来说需要实现ContentProvider 类中的6个抽象方法。
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):将查询的数据以Cursor 对象的形式返回。
Uri insert(Uri uri, ContentValues values):向 Content Provider中插入新数据记录,ContentValues 为数据记录的列名和列值映射。
int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):更新Content Provider中已存在的数据记录。
int delete(Uri uri, String selection, String[] selectionArgs):从Content Provider中删除数据记录。
String getType(Uri uri):返回Content Provider中的数据( MIME )类型。
boolean onCreate():当 Content Provider 启动时被调用。
以上方法将会在ContentResolver 对象中调用,所以很好地实现这些抽象方法会为ContentResolver提供一个完善的外部接口。除了实现抽象方法外,还可以做一些提高可用性的工作。
定义一个 URI 类型的静态常量,命名为CONTENT_URI。 必须为该常量对象定义一个唯一的URI字符串,一般的做法是将 ContentProvider子类的全称类名作为URI字符串,如:
"content://wyf.wpf.MyProvider"。
定义每个字段的列名,如果采用的数据库存储系统为SQLite 数据库,数据表列名可以采用数据库中表的列名。不管数据表中有没有其他的唯一标识一个记录的字段,都应该定义一个"_id"字段 来唯一标识一个记录。模式使用 "INTEGER PRIMARY KEY AUTOINCREMENT" 自动更新 一般将这些列名字符串定义为静态常量, 如"_id"字段名定义为一个名为"_ID" 值为 "_id" 的静态字符串对象。
(3)在应用程序的AdnroidManifest.xml 文件中声明Content Provider组件。
创建好一个Content Provider必须要在应用程序的AndroidManifest.xml 中进行声明,否则该Content Provider对于 Android系统将是不可见的。如果有一个名为MyProvider的类扩展了 ContentProvider类,声明该组件的代码如下:
其中name属性为ContentProvider 子类的全称类名,authorities 属性唯一标识了一个ContentProvider。还可以通过 setReadPermission() 和 setWritePermission() 来设置其操作权限。当然也可以再上面的 xml中加入 android:readPermission 或者 android: writePermission属性来控制其权限。
注意:因为ContentProvider可能被不同的进程和线程调用,所以这些方法必须是线程安全的。
下边是一个例子修改了 SDK 中的 Notes例子。首先创建 ContentProvider 的 CONTENT_URI 和 一些字段数据,字段类可以继承自BaseColumns类,它包括了一些基本的字段,比如:_id等 代码如下:
NotePad类
然后我们需要来创建自己的 ContentProvider 类的 NotePadProvider,它包括了查询、添加、删除、更新等操作以及打开和创建数据库,代码如下:
NotePadProvider 类
下面我们要来创建一个Activity类,首先向其中插入两个数据,然后通过Toast来显示数据库中的数据。 运行效果如下:
代码 Activity01 类
最后不要忘记在AndroidManifest.xml文件中声明我们使用的ContentProvider,下面是我的
AndroidManifest.xml文件
源码在附件里
如果需要创建一个Content Provider,则需要进行的工作主要分为以下3个步骤。
(1) 建立数据的存储系统
数据的存储系统可以由开发人员任意决定,一般来讲,大多数的Content Provider都通过Android的文件存储系统或SQLite 数据库建立自己的数据存储系统。
(2)扩展 ContentProvider类
开发一个继承自ContentProvider类的 子类代码来扩展 ContentProvider类,在这个步骤主要的工作是将要共享的数据包装并以ContentResolver 和 Cursor对象能够访问到的形式对外展示。具体来说需要实现ContentProvider 类中的6个抽象方法。
Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):将查询的数据以Cursor 对象的形式返回。
Uri insert(Uri uri, ContentValues values):向 Content Provider中插入新数据记录,ContentValues 为数据记录的列名和列值映射。
int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):更新Content Provider中已存在的数据记录。
int delete(Uri uri, String selection, String[] selectionArgs):从Content Provider中删除数据记录。
String getType(Uri uri):返回Content Provider中的数据( MIME )类型。
boolean onCreate():当 Content Provider 启动时被调用。
以上方法将会在ContentResolver 对象中调用,所以很好地实现这些抽象方法会为ContentResolver提供一个完善的外部接口。除了实现抽象方法外,还可以做一些提高可用性的工作。
定义一个 URI 类型的静态常量,命名为CONTENT_URI。 必须为该常量对象定义一个唯一的URI字符串,一般的做法是将 ContentProvider子类的全称类名作为URI字符串,如:
"content://wyf.wpf.MyProvider"。
定义每个字段的列名,如果采用的数据库存储系统为SQLite 数据库,数据表列名可以采用数据库中表的列名。不管数据表中有没有其他的唯一标识一个记录的字段,都应该定义一个"_id"字段 来唯一标识一个记录。模式使用 "INTEGER PRIMARY KEY AUTOINCREMENT" 自动更新 一般将这些列名字符串定义为静态常量, 如"_id"字段名定义为一个名为"_ID" 值为 "_id" 的静态字符串对象。
(3)在应用程序的AdnroidManifest.xml 文件中声明Content Provider组件。
创建好一个Content Provider必须要在应用程序的AndroidManifest.xml 中进行声明,否则该Content Provider对于 Android系统将是不可见的。如果有一个名为MyProvider的类扩展了 ContentProvider类,声明该组件的代码如下:
<provider name="wyf.wpf.MyProvider" authorities="wyf.wpf.myprovider" ...../> <!-- 为<provider>标记添加name、authorities属性-->
其中name属性为ContentProvider 子类的全称类名,authorities 属性唯一标识了一个ContentProvider。还可以通过 setReadPermission() 和 setWritePermission() 来设置其操作权限。当然也可以再上面的 xml中加入 android:readPermission 或者 android: writePermission属性来控制其权限。
注意:因为ContentProvider可能被不同的进程和线程调用,所以这些方法必须是线程安全的。
下边是一个例子修改了 SDK 中的 Notes例子。首先创建 ContentProvider 的 CONTENT_URI 和 一些字段数据,字段类可以继承自BaseColumns类,它包括了一些基本的字段,比如:_id等 代码如下:
NotePad类
package xiaohang.zhimeng; import android.net.Uri; import android.provider.BaseColumns; public class NotePad { //ContentProvider的uri public static final String AUTHORITY = "com.xh.google.provider.NotePad"; private NotePad(){} //定义基本字段 实现BaseColumns 这个接口里边已经定义了"_id"字段所以这里不用定义了 public static final class Notes implements BaseColumns{ private Notes(){} //Uri.parse 方法根据指定字符串创建一个 Uri 对象 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_ITME_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"; } }
然后我们需要来创建自己的 ContentProvider 类的 NotePadProvider,它包括了查询、添加、删除、更新等操作以及打开和创建数据库,代码如下:
NotePadProvider 类
package xiaohang.zhimeng; import java.util.HashMap; import xiaohang.zhimeng.NotePad.Notes; 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; 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 int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count = db.delete(NOTES_TABLE_NAME, selection, selectionArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException("Unnown URI" + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } //如果有自定类型,必须实现该方法 @Override public String getType(Uri uri) { switch (sUriMatcher.match(uri)) { case NOTES: return Notes.CONTENT_TYPE; case NOTE_ID: return Notes.CONTENT_ITME_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(java.lang.System.currentTimeMillis()); /** * contaisKey()我的理解就是判断传进来的那个ContentValues有没有相应的列值 * 因为我们的一个ContentValues对象 对应一条数据库的记录 * */ 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.unknownName)); } 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); } //当Content Provider启动时被调用 @Override public boolean onCreate() { mOpenHelper = new DatabaseHelper(getContext()); return true; } //查询操作 将查询的数据以 Cursor 对象的形式返回 @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; //返回true,如果字符串为空或0长度 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); //用来为Cursor对象注册一个观察数据变化的URI c.setNotificationUri(getContext().getContentResolver(), uri); return c; } //更新数据 @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { case NOTES: count = db.update(NOTES_TABLE_NAME, values, selection, selectionArgs); break; case NOTE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException("Unknow URI " + uri); } return count; } }
下面我们要来创建一个Activity类,首先向其中插入两个数据,然后通过Toast来显示数据库中的数据。 运行效果如下:
代码 Activity01 类
package xiaohang.zhimeng; 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 { @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 titile = null; do { id = cur.getString(cur.getColumnIndex(NotePad.Notes._ID)); titile = cur.getString(cur.getColumnIndex(NotePad.Notes.TITLE)); Toast toast = Toast.makeText(this, "TITILE:"+id + "\t" + "NOTE:" + titile, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP|Gravity.CENTER, 0, 40); toast.show(); } while (cur.moveToNext()); } } }
最后不要忘记在AndroidManifest.xml文件中声明我们使用的ContentProvider,下面是我的
AndroidManifest.xml文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xiaohang.zhimeng" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name="NotePadProvider" android:authorities="com.xh.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>
源码在附件里
评论
5 楼
u_xtian
2013-01-15
例子不错,如果你学会了怎么修改里面的错误就证明你已经学习到知识啦,其实楼主的文章已经说得很清楚的了,弄明白的话都可以自己写出来了
4 楼
Lee_Dewyze
2011-08-16
添加了readPermission之后其他程序如何去访问该ContentProvider呢??? 求真相
3 楼
zhangsheXIN_
2011-08-16
很怀疑楼主有没有试过,都是错啊
2 楼
byandby
2011-05-17
请 大家 注意 修改源码。。 谢谢 楼上 谢谢。。!!!
1 楼
say04
2011-02-28
写个评论真不容易,还得回答问题。
楼主的代码里有几处错误,有时间还是修改一下吧。
1 NotePad.java 中public static final String AUTHORITY 应该与AndroidManifest.xml文件中android:authorities一致。
2 NotePadProvider.java中的private static final String CREATE_TABLE"CREATE TABLE"应该在最后一个双引号前增加一个空格。
楼主的代码里有几处错误,有时间还是修改一下吧。
1 NotePad.java 中public static final String AUTHORITY 应该与AndroidManifest.xml文件中android:authorities一致。
2 NotePadProvider.java中的private static final String CREATE_TABLE"CREATE TABLE"应该在最后一个双引号前增加一个空格。
发表评论
-
android LiveFolder(活动文件夹) 完全解析
2011-05-20 23:12 5416如果大家对 ContentP ... -
android Preferences使用示例二
2010-12-09 14:54 16820Preperences 是一种应用程序内部轻量级的 ... -
android SQLiteOpenHelper使用示例
2010-12-08 01:08 51036我们大家都知道Android平台提供给我们一个数据库辅 ... -
android Content Provider的使用
2010-12-07 23:31 5705Content Provider 属于A ... -
android 读取Resources 和 Assets 中的文件
2010-12-07 15:50 33652在Android平台下,除了对应用程序的私有文件夹中的 ... -
android 私有文件夹 文件的写入与读取
2010-12-07 15:05 19925在介绍如何在Android平台下进行文件的读取之前, ... -
android SQLite使用SQLiteOpenHelper类对数据库进行操作
2010-12-07 13:58 103954一、 SQLite介绍 SQLite是android内置的一个 ... -
android SQLite数据库基本操作示例
2010-12-06 23:36 21227这个例子实现了一个完整的数据库操作示例。首先运行项 ... -
android SQLite编程详解
2010-12-05 18:51 8337SQLite 数据库功能非常强大,使用起来也非常方便 ... -
android SQLite简介
2010-12-05 00:05 2799一些概念性的东西 ... -
android 数据存储之 Network
2010-12-04 23:03 3464这篇文章演示2 ... -
android 数据存储之 Files
2010-12-04 18:43 3113Android中可以在设备本身的存储设备或者外接的 ... -
android 数据存储之 Shared Preferences
2010-12-04 12:22 7403Shared Preferences类似于我们常 ... -
android 数据存储初探
2010-12-04 00:02 1866一些概念性的 ...
相关推荐
综上所述,`content_provider_demo`项目涵盖了Content Provider的核心概念和使用方法,包括创建自定义Content Provider、使用UriMatcher、利用CursorLoader进行数据加载、通过ContentResolver进行数据交互以及权限...
"自定义Provider demo"是一个关于如何在Android中创建并使用自定义Content Provider的实例教程。这个教程特别适用于那些想要学习如何在不同应用间进行数据共享的开发者。 Content Provider是Android提供的一种机制...
**实现自定义Content Provider:** 如果你需要共享自定义的数据,可以创建自己的Content Provider。这需要实现ContentProvider类,并覆盖onCreate()、query()、insert()、update()、delete()等方法。 在上述代码...
这个毕业设计项目提供了一个实现这一功能的示例代码,帮助开发者深入理解Android图像处理和多选机制。 1. **Android图像选择框架** - Android系统提供了多种选择图片的API,如Intent ACTION_PICK或ACTION_GET_...
创建自定义Content Provider需要以下步骤: 1. 创建一个继承自`android.content.ContentProvider`的类。 2. 实现`onCreate()`方法,这是Content Provider初始化的地方,通常在这里建立数据库连接或进行其他初始化...
要创建自定义ContentProvider,首先需要创建一个新的Java类,继承自`android.content.ContentProvider`。在这个类中,需要重写以下几个关键方法: - `onCreate()`: 初始化方法,通常用于创建SQLite数据库或进行...
Sqlite.rar文件可能包含了一个名为PersonProvider的自定义Content Provider。PersonProvider通常会继承自ContentProvider类,并覆盖其关键方法,如query()、insert()、delete()、update()和getType(),以实现对...
7. **自定义Content Provider**:开发自定义Content Provider时,需要考虑如何设计数据模型,以及如何根据需求实现上述提到的方法。同时,要确保数据的安全性和稳定性。 8. **第三方库集成**:有些第三方库如...
3. **创建自定义Content Provider**:详细步骤可能包括定义Uri模式,实现ContentProvider类,覆写insert、delete、update、query等方法,以及创建对应的数据库操作。 4. **UriMatcher的使用**:讲解如何利用...
在压缩包中的源码中,开发者可以期待找到如何创建和实现一个自定义Content Provider的示例,以及如何在其他应用中通过ContentResolver进行数据操作的代码。通过分析和学习这些源码,可以加深对Content Provider工作...
7. **Content Providers**:通过实例学习如何实现和使用Content Provider来共享数据。 8. **Services**:探究后台服务的实现,以执行长时间运行的任务。 9. **Broadcast Receivers**:学习广播接收器的创建和注册,...
本示例将深入探讨如何在Android应用中使用SQLite数据库,包括数据库的设计、操作以及Content Provider的使用。 1. **SQLite数据库介绍** SQLite是一个开源的SQL数据库引擎,它不需单独的服务器进程,可以直接嵌入...
本示例DEMO旨在演示如何简单地使用Content Provider来实现应用间的数据共享。 Content Provider是Android系统提供的一种标准化方式,允许不同应用程序之间共享数据。它封装了对数据库的操作,提供了统一的接口,...
3. **Content Provider**:Content Provider用于在不同应用间共享数据,`ApiDemos`可能有如何创建和使用Content Provider的示例,展示如何读写SQLite数据库或访问外部存储。 4. **Broadcast Receiver**:广播接收器...
4. **数据存储**:Android提供了多种数据存储方式,如Shared Preferences(轻量级键值对存储)、SQLite数据库(结构化数据存储)、文件系统和Content Provider(用于跨应用共享数据)。这些方法在处理应用数据时各有...
开发自定义Content Provider需要实现ContentProvider类,定义Uri匹配规则和数据操作方法(如query(), insert(), update(), delete()等)。其他应用通过ContentResolver与Content Provider交互,通过Uri请求数据。 ...
开发者需要学习如何创建自定义Content Provider并实现Uri匹配规则。 除此之外,Android的网络编程是另一个重要的方面。在给定的“webservice”标签中,我们可以推断出这个压缩包可能包含有关与Web服务交互的示例。...
1. **创建Content Provider类**:自定义一个继承自`android.content.ContentProvider`的类,并实现必要的生命周期方法,如`onCreate()`、`query()`、`insert()`、`update()`和`delete()`。 2. **定义URI**:为...
在Android系统中,"给自己发假短信"实际上是一种模拟短信收发的过程,它不涉及到真正的网络通信,而是通过操作系统的内部机制,利用短信Content Provider来向短信数据库添加数据,从而在短信应用中显示出一条新的...