android学习笔记54——ContentProvider
ContentProvider
ContentProvider用于实现数据共享.
ContentProvider是不同应用程序之间进行数据交换的标准API,其以某种Uri的形式对外提供数据,允许其他应用程序访问或修改数据;
其他应用程序使用ContentResolver根据Uri去访问操作指定数据。
注意:ContentProvider为android四大组件之一,需要在AndroidMainfest.xml中做配置处理。
如果把ContentProvider当做一个网站,那么完成的开发一个ContentProvider的操作步骤如下:
1.定义自己的ContentProvider类,该类需要继承android提供的ContentProvider基类;
2.向android系统注册这个“网站”,也就是在AndroidMainfest.xml文件中注册这个ContentProvider——就像注册Activity一样。注册ContentProvider需要为其绑定一个URL.
注意:
向android系统中注册ContentProvider只要在<application.../>元素中添加子元素即可,如下所示:
当我们向android系统注册了ContentProvider之后,其他应用程序就可通过Uri来访问DictProvider所暴露的数据了。
那么DictPovider到底如何暴露其提供的数据?
==》
由于应用程序对数据的操作无非就是CRUD,因此DictProvider除了需要继承ContentProvider之外,还需要提供如下几个方法:
public boolean onCreate() |
该方法在ContentProvider创建后被调用,当其他应用程序第一次访问ContentProvider时,该ContentProvider会被创建出来, 并立即回调该onCreate() |
public Uri insert(Uri uri,ContentValues values) | 根据Uri插入values对应的数据 |
public int delete(Uri uri,String selection,String[] selecttionArgs) | 根据Uri删除select条件所匹配的所有记录 |
publc int update(Uri uri,ContentValues values,String selection,Sting[] selecttionArgs) | 根据Uri修改select条件所匹配的所有记录 |
public Cursor query(Uri uri,Sting[] projection,String selection,Sting[] selectionArgs,String sortOrder) | 根据Uri查询select条件所匹配的所有记录,其中projection就是一个列名列表,表明只选择出指定的列的数据列 |
public String getType(Uri uri) | 该方法用于返回当前Uri所代表的数据的MIME类型。如果该Uri对应数据可能包括多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么返回MIME类型字符串应该以vnd.android.cursor.item/开头 |
Uri简介
网页URL,如:https://www.baidu.com/s?tn=baidutop...
1.http://——URL协议部分,只要通过HTTP协议来访问网站,该部分为固定信息;
2.www.baidu.com——网站域名部分,只要通过http协议来访问网站,该部分总是固定信息;
3.s?tn=baidutop...——网站资源部分, 当访问者需要访问不同资源时,这个部分是动态改变的。
Android Uri因此类似,如下:
content://org.crazyit.providers.dictprovider/words
其也可分为三个部分:
1.content://,这个不是android规定的,是固定的;
2.org.crazyit.providers.dictprovider,这个部分就是ContentProvider的authority.系统就是由这个部分来找到操作那个ContentProvider.只要访问指定的ContentProvider,这个部分就是固定的;
3.words,资源部分或者说是数据部分,当访问者需要访问不同资源时,这个部分是动态改变的。
注意:
需要指出的是,Android的Uri所能表达的功能更丰富,还可以支持如下Uri:
content://org.crazyit.providers.dictprovider/words/2——此时需要访问的资源为words/2,其意味着访问words数据中ID为2的记录的word字段。
content://org.crazyit.providers.dictprovider/words——访问全部数据;
大部分使用ContentProvider所操作的数据都来自于数据库,但有时候这些数据也可以来自于文件、XML或网络等其他存储方式,此时支持的Uri也可改为如下形式:
content://org.crazyit.providers.dictprovider/word/detail/——代表操作word节点下的detail节点;
为了将一个字符串转换成Uri,Android提供的Uri工具类提供了parse()静态方法,转换方式如下:
Uri uri = Uri.parse("content://org.crazyit.providers.dictprovider/words/2");
使用ContentResolver操作数据
ContentProvider相当于一个“网站”,它的作用是暴露可供操作的数据;
其他程序则通过ContentResolver来操作ContentProvider所暴露的数据;ContentResolver相当于HttpClient.
Content提供了如下方法来获取ContentResolver对象:getContentResolver().
获取ContentResolver对象成功后,可通过如下方法操作数据:
insert(Uri uri,ContentValues values) | 向Uri对应的ContentProvider中插入values对应的数据 |
delete(Uri uri,String where,Sting[] selectionArgs) | 删除uri对应的ContentProvider中where提交匹配的数据 |
update(Uri uri,ContentValues values,String where,String[] selectionArgs) | 更新uri对应的ContentProvider中where提交匹配的数据 |
query(Uri uri,Sting[] projection,String selection,String[] selectionArgs,String sortOrder) | 查询Uri对应的ContentProvider中where提交匹配的数据 |
注意:一般来说,ContentProvider是单实例模式的,当多个应用程序通过ContentResolver来操作ContentProvider提供的数据时,ContentResolver
调用的数据操作将会委托给同一个ContentProvider处理。
操作系统的ContentProvider
使用ContentProvider操作数据的操作步骤:
1.调用Activity的ContentResolver()获取ContentResolver对象
2.根据需要调用ContentResolver的insert()、delete()、update()、query方法操作数据即可
注意:操作系统提供的ContentResolver,需要了解其对应的ContentProvider对应的Uri.
使用ContentProvider管理联系人
Android系统提供了Contacts应用程序来管理联系人,而且Android系统还为联系人管理提供了ContentProvider,这就运行其他应用程序以ContentResolver来管理联系人数据。
Android系统对联系人管理ContentProvider的几个Uri如下:
ContactsContact.Contacts.CONTENT_URI | 管理联系人的Uri |
ContactsContact.CommonDataKinds.Phone.CONTENT_URI | 管理联系人的电话的Uri |
ContactsContact.CommonDataKinds.Email.CONTENT_URI | 管理联系人的邮箱的Uri |
实例如下:
布局文件main.xml==>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" > <Button
android:id="@+id/btnQuery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询" /> </LinearLayout> result.xml==>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <ExpandableListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:cacheColorHint="#00000000"
android:listSelector="#00000000" >
</ExpandableListView> </LinearLayout> AndroidMainfest.xml==>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> 代码实现==》
package com.example.myprovidercontent1; import java.util.ArrayList; import android.os.Bundle;
import android.provider.ContactsContract;
import android.app.Activity;
import android.app.AlertDialog;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AbsListView;
import android.widget.AbsListView.LayoutParams;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.TextView; public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); Button btnQuery = (Button) this.findViewById(R.id.btnQuery);
btnQuery.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
query(v);
}
});
} private void query(View v)
{
// 定义两个List封装系统联系人信息、指定联系人的电话号码、Email等...
final ArrayList<String> names = new ArrayList<String>();
final ArrayList<ArrayList<String>> details = new ArrayList<ArrayList<String>>();
// 使用ContentResolver查找联系人数据
Cursor cursor = this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
null, null, null, null);
// 遍历查询结果,获取系统中所有联系人
while (cursor.moveToNext())
{
// 联系人Id、名称
String contactId = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts._ID));
String name = cursor.getString(cursor
.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
names.add(name);
Log.i("swg", "name:" + name);
// 联系人电话号码
Cursor phones = this.getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId,
null, null);
final ArrayList<String> detail = new ArrayList<String>();
// 遍历查询结果,获取该联系人的多个 电话号码
while (phones.moveToNext())
{
String phoneNum = phones.getString(phones
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.i("swg", "电话号码:" + phoneNum);
detail.add("电话号码:" + phoneNum);
}
phones.close(); // 使用ContentResolver查询联系人Email
Cursor emails = this.getContentResolver()
.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null,
ContactsContract.CommonDataKinds.Email.CONTACT_ID + "=" + contactId,
null, null);
// 遍历查询结果,获取该联系人的多个Email地址
while (emails.moveToNext())
{
String emailAdd = emails.getString(emails
.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); Log.i("swg", "邮件地址:" + emailAdd);
detail.add("邮件地址:" + emailAdd);
}
emails.close(); details.add(detail);
}
cursor.close(); // 加载result.xml界面布局文件
View resultDialog = this.getLayoutInflater().inflate(R.layout.result, null);
ExpandableListView list = (ExpandableListView) resultDialog.findViewById(R.id.list);
// 创建一个ExpandableListAdapter对象
ExpandableListAdapter adapter = new ExpandableListAdapter()
{
@Override
public void unregisterDataSetObserver(DataSetObserver observer)
{
} @Override
public void registerDataSetObserver(DataSetObserver observer)
{
} @Override
public void onGroupExpanded(int groupPosition)
{
} @Override
public void onGroupCollapsed(int groupPosition)
{
} @Override
public boolean isEmpty()
{
return false;
} @Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return true;
} @Override
public boolean hasStableIds()
{
return true;
} // 该方法决定每个组选项的外观
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
ViewGroup parent)
{
TextView tv = getTextView();
tv.setText(getGroup(groupPosition).toString());
return tv;
} @Override
public long getGroupId(int groupPosition)
{
return groupPosition;
} @Override
public int getGroupCount()
{
// details
return names.size();
} @Override
public Object getGroup(int groupPosition)
{
// details
return names.get(groupPosition);
} @Override
public long getCombinedGroupId(long groupId)
{
return 0;
} @Override
public long getCombinedChildId(long groupId, long childId)
{
return 0;
} @Override
public int getChildrenCount(int groupPosition)
{
return details.get(groupPosition).size();
} private TextView getTextView()
{
AbsListView.LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
64);
TextView tv = new TextView(MainActivity.this);
tv.setLayoutParams(lp);
tv.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.LEFT);
tv.setPadding(36, 0, 0, 0);
tv.setTextSize(20);
return tv;
} // 该方法决定每个子项的外观
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
View convertView, ViewGroup parent)
{
TextView tv = getTextView();
tv.setText(getChild(groupPosition, childPosition).toString());
return tv;
} @Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
} @Override
public Object getChild(int groupPosition, int childPosition)
{
return details.get(groupPosition).get(childPosition);
} @Override
public boolean areAllItemsEnabled()
{
return false;
}
};
// 为ExpandableListView设置Adapter
list.setAdapter(adapter);
// 使用对话框来显示查询结果
new AlertDialog.Builder(MainActivity.this).setView(resultDialog)
.setPositiveButton("确定", null).show();
}
}
实例二、添加联系人
android学习笔记54——ContentProvider的更多相关文章
- Android 学习笔记之ContentProvider实现数据共享....
PS:最近听老师说打算让我参与企业的app制作,让我加快学习的进度...好吧,貌似下周还有考试...貌似实验室这个app也要做...暂时不管了...那就只能加快进度了,感觉略微的有点激动和紧张,总算是 ...
- Android学习笔记之ContentProvider
读取其他应用程序共享的数据 以下示例为读取联系人信息 package com.jiahemeikang.helloandroid; import com.jiahemikang.service.Ech ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- 【转】Pro Android学习笔记(七):了解Content Provider(下上)
我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
- android学习笔记36——使用原始XML文件
XML文件 android中使用XML文件,需要开发者手动创建res/xml文件夹. 实例如下: book.xml==> <?xml version="1.0" enc ...
- Android学习笔记之JSON数据解析
转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
随机推荐
- 调用天气预报webservice
<script src="jquery.js" type="text/javascript" charset="utf-8">& ...
- 安装solidity遇见的问题——unused variable 'returned'
在编译安装solidity的过程中遇见了一个很奇怪的问题 webthree-umbrella/libethereum/libethereum/Executive.cpp: In member func ...
- css\html布局及部分知识小分享~~~
近期发现和总结的知识跟大侠们分享,请大侠们多多评论指教一二? HTML 1.(1)body需设置页面默认字体大小 body{font-size:12px;} (2)IE6下png图片划过切换失效,建 ...
- 用Gen8服务器来学习虚拟化ESXI
虚拟化和云计算是这几年的热门技术,VMware公司是虚拟化的领头羊,小坦克我有幸在VMware从事这方面的测试工作. 本系列将会讲述我学习虚拟化的一些经历. 将会覆盖一些虚拟化产品: 比如:VMwar ...
- iOS开发UI篇—transframe属性(形变)
iOS开发UI篇—transframe属性(形变) 1. transform属性 在OC中,通过transform属性可以修改对象的平移.缩放比例和旋转角度 常用的创建transform结构体方法分两 ...
- 黑客长期摇号不中"黑"掉北京小客车摇号网
新闻链接:http://www.2cto.com/News/201310/248936.html 新闻时间:2013-10-11 新闻正文: 为发泄长期摇号不中的不满,同时也为自己研发的软件打广告,硕 ...
- [vijos P1524] 最小监视代价
历时四天(本周三至本周六),本人的第一道网络流题目终于通过了…虽然这么慢才搞懂很大程度是因为脑子笨,但是还是要吐槽一下: (1)选的这道题吧居然是无向图,对于初学者我表示呵呵,昨晚到现在一直在纠结怎么 ...
- CSS属性之 -- overflow
overflow可以实现隐藏超出对象内容,同时也有显示与隐藏滚动条的作用,overflow属性有四个值:visible (默认), hidden, scroll, 和auto.同样有两个overflo ...
- Android 微信UI 、点击操作
上一篇,我们介绍了微信界面的相关知识点.今天我们就来把微信的界面做出来. 首先我们新建一个layout-->LinearLayout-->weixin.xml 我们使用上中下线性布局,采用 ...
- OutputCache 如何使用本地缓存 【转】
注意!ASP.NET MVC 3 的一个 OutputCache 问题 在用 ASP.NET MVC 3 重写博客园网站首页时,特地留意了一下这个缓存问题,通过这篇博文分享一下. 在 ASP.NE ...