android四大组件之ContentProvider(二)
ContentProvider学习笔记
上一章节我们编写了自定义的一个StudentProvider,他提供了两种供外界访问数据的方式,content://come.demo.sqlite.studentprovider/t_student和content://come.demo.sqlite.studentprovider/t_student/#,这一章我们将讲解其他应用程序将如何来访问StudentProvider中的数据。
1、ContentResolver类介绍
我们知道StudentProvider继承了ContentProvider类,并实现了insert(),update(),delete(),query(),getType()等方法,同样的ContentResolver这个类也提供了insert(),update(),delete(),query()方法,当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法
ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values):该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs):该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs):该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder):该方法用于从ContentProvider中获取数据。
2、实例:对数据库表t_student的增删改查操作
(1)布局文件main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/btnAdd1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入数据1"
/> <Button
android:id="@+id/btnAdd2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="插入数据2"
/> <Button
android:id="@+id/btnSearch1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据1"
/> <Button
android:id="@+id/btnSearch2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="查询数据2"
/> <Button
android:id="@+id/btnUpdate1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="修改数据1"
/> <Button
android:id="@+id/btnUpdate2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="修改数据2"
/> <Button
android:id="@+id/btnDelete1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="删除数据1"
/> <Button
android:id="@+id/btnDelete2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="删除数据2"
/> </LinearLayout>
(2)MainActivity来实现具体的操作
package com.demo.contentprovider; import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast; /**
* 使用ContentResolver实现对数据库表t_student的操作
* @author yinbenyang
*/
public class MainActivity extends Activity { private Button btnAdd1, btnAdd2, btnSearch1, btnSearch2, btnUpdate1,
btnUpdate2, btnDelete1, btnDelete2; //匹配content://come.demo.sqlite.studentprovider/t_student路径
private static final int ONE = 1;
//匹配content://come.demo.sqlite.studentprovider/t_student/
private static final int TWO = 2;
//日志输出
private static final String TAG = "ContentProvider";
//定义的一个Uri,这个是StudentProvider提供的一个内容提供者
private static String CONTENT_URI = "content://come.demo.sqlite.studentprovider/t_student"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnAdd1 = (Button) findViewById(R.id.btnAdd1);
btnAdd2 = (Button) findViewById(R.id.btnAdd2);
btnUpdate1 = (Button) findViewById(R.id.btnUpdate1);
btnUpdate2 = (Button) findViewById(R.id.btnUpdate2);
btnSearch1 = (Button) findViewById(R.id.btnSearch1);
btnSearch2 = (Button) findViewById(R.id.btnSearch2);
btnDelete1 = (Button) findViewById(R.id.btnDelete1);
btnDelete2 = (Button) findViewById(R.id.btnDelete2); btnAdd1.setOnClickListener(listener);
btnAdd2.setOnClickListener(listener);
btnUpdate1.setOnClickListener(listener);
btnUpdate2.setOnClickListener(listener);
btnSearch1.setOnClickListener(listener);
btnSearch2.setOnClickListener(listener);
btnDelete1.setOnClickListener(listener);
btnDelete2.setOnClickListener(listener);
} private OnClickListener listener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnAdd1:
add(ONE);
break;
case R.id.btnAdd2:
add(TWO);
break;
case R.id.btnUpdate1:
update(ONE);
break;
case R.id.btnUpdate2:
update(TWO);
break;
case R.id.btnDelete1:
delete(ONE);
break;
case R.id.btnDelete2:
delete(TWO);
break;
case R.id.btnSearch1:
search(ONE);
break;
case R.id.btnSearch2:
search(TWO);
break;
default:
break;
}
}
}; // 查询数据
private void search(int type) {
ContentResolver resolver = getContentResolver();
Uri url = null;
// 指定查询的列名
String projection[] = new String[] { "sid", "sname", "age" };
// 查询的条件
String selection = "";
// 查询条件的参数值
String[] selectionArgs = null;
// 指定是否排序以及使用排序是时的排序规则
String sortOrder = "";
// 查询结果为一个Cursor
Cursor cursor = null;
switch (type) {
case ONE:
// parse方法通过传入一个字符串来构造一个Uri对象
url = Uri.parse(CONTENT_URI);
selection = "sid < ?";
selectionArgs = new String[] { "3" };
cursor = resolver.query(url, projection, selection, selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
Log.i(TAG,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2));
Toast.makeText(
this,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2), Toast.LENGTH_SHORT)
.show();
}
break;
case TWO:
// 此时指定查询id为1的学生信息
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
selection = null;
cursor = resolver.query(url, projection, selection, selectionArgs,
sortOrder);
while (cursor.moveToNext()) {
Log.i(TAG,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2));
Toast.makeText(
this,
"sid=" + cursor.getInt(0) + ",sname="
+ cursor.getString(1) + ",age="
+ cursor.getShort(2), Toast.LENGTH_SHORT)
.show();
}
break;
default:
break;
}
} // 删除数据
private void delete(int type) {
ContentResolver resolver = getContentResolver();
Uri url = null;
String where = "";
String[] selectionArgs = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
// 指定删除id为1,2的学生信息
where = "sid in(?,?)";
selectionArgs = new String[] { "1", "2" };
resolver.delete(url, where, selectionArgs);
break;
case TWO:
// 指定删除id为3的学生信息
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),3);
Log.i(TAG, "url:" + url);
where = null;
resolver.delete(url, where, selectionArgs);
break;
default:
break;
}
} // 修改数据
private void update(int type) {
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
Uri url = null;
String where = "";
String[] selectionArgs = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
values.put("sname", "update1");
values.put("age", 22);
where = "sid = ?"; // 指定更新语句的条件(此时若不指定则是更新全部的数据)
selectionArgs = new String[] { "1" }; // 指定占位符的数值
Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
break;
case TWO:
// 此时的Uri中包含了需要更新数据的id,所以不再需要指定更新语句的条件和参数值
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),2);
values.put("sname", "update2");
values.put("age", 22);
where = null;
Log.i(TAG, resolver.update(url, values, where, selectionArgs) + "");
break;
default:
break;
}
} // 插入数据
private void add(int type) {
ContentResolver resolver = getContentResolver();
ContentValues values = new ContentValues();
values.put("sname", "zhaobenshan");
values.put("age", 23);
Uri url = null;
switch (type) {
case ONE:
url = Uri.parse(CONTENT_URI);
// insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
Log.i(TAG, resolver.insert(url, values).toString());
break;
case TWO:
/**
* 这个构造一个Uri为:content://com.demo.contentprovider.studentprovider/
* t_student/1,然后插入,实际上新插入的一条数据的id并不会为1,
* 因为已经存在为1的数据了,所以这个和上面的写法一样,生成的数据的id为2
*/
url = ContentUris.withAppendedId(Uri.parse(CONTENT_URI),1);
// insert()方法返回一个Uri对象,这个对象是新插入的数据的Uri
Log.i(TAG, resolver.insert(url, values).toString());
break;
default:
break;
}
}
}
页面显示的布局效果:

而后我们还是利用命令去com.demo.sqlite.activity/database/data.db中查看t_student表
(1) 点击插入数据1或者插入数据2,查看数据:

(2)点击查询数据1,可以看到弹出了id为1和2的两条数据,点击查询数据2可以看到只弹出id为1的数据
(3)点击修改数据1将t_student表中sid为1的name改为update1,age改为22,点击修改数据2将sid为2的name改为update2,age改为22.

(4)点击删除数据1将id为1,2的学生信息删除:如图删除后只剩下id为3的学生信息

点击删除数据2将id为3的学生信息删除,如图,最后t_student表中已经没有学生信息了

后记:t_student表是SqliteDemo应用程序中的表数据,而现在通过ContentProviderDemo程序也可以实现对t_student表的操作,由此可见,我们的ContentProvider实现数据在应用程序间的共享了
android四大组件之ContentProvider(二)的更多相关文章
- Android 四大组件之" ContentProvider "
前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...
- 【Android开发日记】之入门篇(九)——Android四大组件之ContentProvider
数据源组件ContentProvider与其他组件不同,数据源组件并不包括特定的功能逻辑.它只是负责为应用提供数据访问的接口.Android内置的许多数据都是使用ContentProvider形式,供 ...
- Android四大组件之——ContentProvider(一)
Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...
- 初学android:四大组件之contentprovider
一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...
- android四大组件之ContentProvider(一)
ContentProvider学习笔记 1. ContentProvider基本概念 ContentProvider向我们提供了我们在应用程序之间共享数据的一种机制,虽然采用文件和SharedPref ...
- Android四大组件之contentProvider
Activity,Service,broadcast and Contentprovider android 4 大组件. ContentProvider:使用: public class Image ...
- Android四大组件之ContentProvider(二)读取设备上的图片、音频和视频
Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,通过Content Provider的方式提供给用户.当设备开机或者有SD卡插拔等事件发生时, ...
- Android四大组件之——ContentProvider(二)
Content Resolver介绍: 开发者文档中这么定义的: This class provides applications access to the content model. 这个类为应 ...
- Android 四大组件之四(ContentProvider)
ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...
随机推荐
- zabbix3.0.4 部署之四 (LNAP > PHP安装)
1.安装依赖 安装epel-release源 安装 libiconv-1.14.tar.gz (这个还有个devl包) libmcrypt-2.5.8.tar.gz mhash-0.9.9.9. ...
- 【转】 strcpy和memcpy的区别
strcpy和memcpy都是标准C库函数,它们有下面的特点.strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符. 已知strcpy函 ...
- Spring中映射Mongodb中注解的解释
spring-data-mongodb中的实体映射是通过MongoMappingConverter这个类实现的.它可以通过注释把java类转换为mongodb的文档. 它有以下几种注释: @Id - ...
- Find a point on a 'line' between two Vector3
Find a point on a 'line' between two Vector3http://forum.unity3d.com/threads/find-a-point-on-a-line- ...
- 转载-Web API 入门
An Introduction to ASP.NET Web API 目前感觉最好的Web API入门教程 HTTP状态码 Web API 强势入门指南 Install Mongodb Getting ...
- Android开发--FrameLayout的应用
1.简介 frameLayout为框架布局,该布局的特点为层层覆盖,即最先放置的部件位于最下层,最后放置的部件位于最上层. 2.构建 如图所示,该视图中有五个TextView.其中,tv1放置在最底层 ...
- iOS开发拓展篇—CoreLocation定位服务
iOS开发拓展篇—CoreLocation定位服务 一.简单说明 1.CLLocationManager CLLocationManager的常用操作和属性 开始用户定位- (void)startUp ...
- [vijos P1391] 想越狱的小杉
考前最后一题,竟然是第一次码SPFA,虽然这个算法早有耳闻,甚至在闻所未闻之前自己有过一个类似的想法,说白了就是广搜啊,但是敲起来还是第一次啊,而且这还不是真正意义上的SPFA. 完全按照自己想法来码 ...
- python import其他文件夹下的模块
模块的路径不在默认搜索路径中,需要在sys.path中添加 import syssys.path.append('需要模块的文件夹路径')
- HDU 3854 Glorious Array(树状数组)
题意:给一些结点,每个结点是黑色或白色,并有一个权值.定义两个结点之间的距离为两个结点之间结点的最小权值当两个结点异色时,否则距离为无穷大.给出两种操作,一种是将某个结点改变颜色,另一个操作是询问当前 ...