android学习日记13--数据存储之ContentProvide
2014-03-08 14:27
441 查看
3、ContentProvider
数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。ContentProvider实现多应用程序间的数据共享类
一般利用ContentProvider为需要共享的数据定义一个URI(统一资源定位符)
然后其他程序通过Context获得ContentResolver并将数据的URI传入即可
Android已为一些常用的数据创建ContentProvider,这些ContentProvider位于
android.provider包下,常用的就是手机上联系人信息,但是要取得相应的权限自己的应用程序才能访问
具体设置是在AndroidManifest.xml
对于ContentProvide重要的是数据模型和URI
数据模型:ContentProvide为所需要的数据创建表,每行代表一条记录,每条记录有唯一的'_ID'标识
URI:每个ContentProvide对外提供一个URI来标识自己的数据集
URI特点:
1、无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据
2、URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的类名(数据路径)。例如;"content://com.example.contentprovide.myprovider"
3、如果URI中包含表示需要获取的记录的_ID;则就返回该id对应的数据,如果没有_ID,就表示返回全部
举个例子,如:
所有联系人的URI: content://contacts/people
某个联系人的URI: content://contacts/people/5
具体使用步骤:
1、在当前应用程序中定义一个ContentProvider
这里为了演示方便只实现创建和查询两个简单的方法
2、在当前应用程序的AndroidManifest.xml中注册此ContentProvider
3、其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据
日志打印:
上面MyProvider代码和应用程序MainActivity代码不放在同一个包下是想说明ContentProvider不同程序间的数据共享,
但是注册获取权限那段代码要放在调用的程序包里。
其实通过代码可以看出为了共享数据库.可以让数据库披上ContentProvider外衣,主要还是通过SQLiteDatabase去操作数据库。
当然对于已封装的共享数据。我们只要设置获取权限,通过ContentResolver就可以直接调用。
4、获取系统的联系人、媒体库信息
对于系统程序的联系人、多媒体等信息可通过指定的Uri来获取。
数据附录是获取本地联系人信息代码:
5、监听ContentProvider的数据改变
随着ContentProvider的共享数据可能发生改变,要提供给有使用该共享数据的相应,具体步骤如下:
1).在ContentProvider类的insert\update\delete方法加入this.getContext().getContentResolver().notifyChange(URI,null);
其中URI表示监听的URI
null表示发送消息给任何人;
2).在访问者的类中调用如下方法:
context.getContentResolver().registerContentObserver(uri,true,new ContentObserver(new Handler()));
3).创建内部类继承ContentObserver并重写下面两个方法:
(1)带有Handler的构造函数;
(2)public void onChange(boolean selfChange); 此函数在内容提供者发出改变信号时就会被调用
参数selfChange为如果是自己改变的原因,则为true;如果不是自己改变的,则为false;
数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。ContentProvider实现多应用程序间的数据共享类
一般利用ContentProvider为需要共享的数据定义一个URI(统一资源定位符)
然后其他程序通过Context获得ContentResolver并将数据的URI传入即可
Android已为一些常用的数据创建ContentProvider,这些ContentProvider位于
android.provider包下,常用的就是手机上联系人信息,但是要取得相应的权限自己的应用程序才能访问
具体设置是在AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS" />
对于ContentProvide重要的是数据模型和URI
数据模型:ContentProvide为所需要的数据创建表,每行代表一条记录,每条记录有唯一的'_ID'标识
URI:每个ContentProvide对外提供一个URI来标识自己的数据集
URI特点:
1、无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据
2、URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的类名(数据路径)。例如;"content://com.example.contentprovide.myprovider"
3、如果URI中包含表示需要获取的记录的_ID;则就返回该id对应的数据,如果没有_ID,就表示返回全部
举个例子,如:
所有联系人的URI: content://contacts/people
某个联系人的URI: content://contacts/people/5
具体使用步骤:
1、在当前应用程序中定义一个ContentProvider
public class MyProvider extends ContentProvider { @Override public int delete(Uri arg0, String arg1, String[] arg2) { // TODO Auto-generated method stub return 0; } @Override public String getType(Uri arg0) { // TODO Auto-generated method stub return null; } @Override public Uri insert(Uri arg0, ContentValues arg1) { // TODO Auto-generated method stub return null; } // 创建数据库,建表和插入数据 @Override public boolean onCreate() { // TODO Auto-generated method stub SQLiteDatabase db =this.getContext().openOrCreateDatabase("mydb.db", Context.MODE_PRIVATE, null); db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)"); ContentValues values =new ContentValues(); values.put("name", "Hello ContentProvider!"); db.insert("tab", "_id", values); db.close(); return true; } // 查询 @Override public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3, String arg4) { // TODO Auto-generated method stub SQLiteDatabase db =this.getContext().openOrCreateDatabase("mydb.db", Context.MODE_PRIVATE, null); Cursor c = db.query("tab", null, null, null, null, null,null); return c; } @Override public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) { // TODO Auto-generated method stub return 0; }
这里为了演示方便只实现创建和查询两个简单的方法
2、在当前应用程序的AndroidManifest.xml中注册此ContentProvider
<provider android:name=".MyProvider" android:authorities="com.example.contentprovider.MyProvider"/>
3、其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取当前context Context context = MainActivity.this; // 得到ContentResolver对象 ContentResolver resolver = context.getContentResolver(); // uri格式 "content://"、数据的路径、标示ID(可选) Uri uri = Uri.parse("content://com.example.contentprovider.MyProvider"); Cursor c = resolver.query(uri, null, null, null, null); // 打印获取数据 c.moveToFirst(); for(int i=0; i<c.getCount(); i++){ int index = c.getColumnIndexOrThrow("name"); String src = c.getString(index); Log.d("", src); c.moveToNext(); } }
日志打印:
上面MyProvider代码和应用程序MainActivity代码不放在同一个包下是想说明ContentProvider不同程序间的数据共享,
但是注册获取权限那段代码要放在调用的程序包里。
其实通过代码可以看出为了共享数据库.可以让数据库披上ContentProvider外衣,主要还是通过SQLiteDatabase去操作数据库。
当然对于已封装的共享数据。我们只要设置获取权限,通过ContentResolver就可以直接调用。
4、获取系统的联系人、媒体库信息
对于系统程序的联系人、多媒体等信息可通过指定的Uri来获取。
数据附录是获取本地联系人信息代码:
public String getContactInfo(){ String result=""; ContentResolver resolver=getContentResolver(); //查询联系人 Cursor cursor=resolver.query(Contacts.CONTENT_URI, null, null, null, null); int idIndex=cursor.getColumnIndex(Contacts._ID); // 取得联系人名字 (显示出来的名字),实际内容在 ContactsContract.Contacts中 int nameIndex=cursor.getColumnIndex(Contacts.DISPLAY_NAME); for (cursor.moveToFirst();(!cursor.isAfterLast());cursor.moveToNext()) { //获取联系人ID String contactId =cursor.getString(idIndex); result=result+contactId+"\t\t\t"; result=result+cursor.getString(nameIndex)+"\t\t\t"; // 根据联系人ID查询对应的电话号码 Cursor phoneNumbers = resolver.query(CommonDataKinds.Phone.CONTENT_URI, null, CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null); // 取得电话号码(可能存在多个号码) while (phoneNumbers.moveToNext()) { String strPhoneNumber = phoneNumbers.getString(phoneNumbers.getColumnIndex(CommonDataKinds.Phone.NUMBER)); result=result+strPhoneNumber+"\t\t\t"; } phoneNumbers.close(); // 根据联系人ID查询对应的email Cursor emails = resolver.query(CommonDataKinds.Email.CONTENT_URI, null, CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null); // 取得email(可能存在多个email) while (emails.moveToNext()) { String strEmail = emails.getString(emails.getColumnIndex(CommonDataKinds.Email.DATA)); result=result+strEmail+"\t\t\t"; } emails.close(); result=result+"\n"; } cursor.close(); return result; }
5、监听ContentProvider的数据改变
随着ContentProvider的共享数据可能发生改变,要提供给有使用该共享数据的相应,具体步骤如下:
1).在ContentProvider类的insert\update\delete方法加入this.getContext().getContentResolver().notifyChange(URI,null);
其中URI表示监听的URI
null表示发送消息给任何人;
2).在访问者的类中调用如下方法:
context.getContentResolver().registerContentObserver(uri,true,new ContentObserver(new Handler()));
3).创建内部类继承ContentObserver并重写下面两个方法:
(1)带有Handler的构造函数;
(2)public void onChange(boolean selfChange); 此函数在内容提供者发出改变信号时就会被调用
参数selfChange为如果是自己改变的原因,则为true;如果不是自己改变的,则为false;
相关文章推荐
- android学习日记13--数据存储之File存储
- android学习日记13--数据存储之SharedPreference
- android学习日记13--数据存储之SQLite
- Android学习日记——数据存储5部曲之SharedPreferences
- Android学习历程13-Android 数据存储
- Android学习13——数据存储之SharedPreference
- android成长日记 11.详细学习了数据存储相关基础知识
- Android学习日记——数据存储5部曲之文件存储
- Itcast_android学习_数据存储于访问:SharedPreferences
- Android学习路线(二十六)Android数据存储
- Android学习(13)-跨程序共享数据
- Android成长日记-数据存储之SharedPreferences
- 【Android】数据存储数据库SQLite(之前有看到的一篇关于SQLite文章,简单明了、覆盖较全面适合学习)
- 【原创Android游戏】--猜数字游戏V1.1 --数据存储,Intent,SimpleAdapter的学习与应用
- Android 学习第17课,使用文件的数据存储(4种存储模式)
- Android基础学习__第2天__数据的存储与访问
- Android网络与数据存储_学习笔记_第五周
- android数据存储中的文件存储学习记录
- android学习---SQLite方式存储数据
- Android 学习笔记14:数据存储