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(二)的更多相关文章

  1. Android 四大组件之" ContentProvider "

    前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...

  2. 【Android开发日记】之入门篇(九)——Android四大组件之ContentProvider

    数据源组件ContentProvider与其他组件不同,数据源组件并不包括特定的功能逻辑.它只是负责为应用提供数据访问的接口.Android内置的许多数据都是使用ContentProvider形式,供 ...

  3. Android四大组件之——ContentProvider(一)

    Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...

  4. 初学android:四大组件之contentprovider

    一.ContentProvider的概念ContentProvider:为存储和获取数据提供统一的接口.可以在不同的应用程序之间共享数据.Android已经为常见的一些数据提供了默认的ContentP ...

  5. android四大组件之ContentProvider(一)

    ContentProvider学习笔记 1. ContentProvider基本概念 ContentProvider向我们提供了我们在应用程序之间共享数据的一种机制,虽然采用文件和SharedPref ...

  6. Android四大组件之contentProvider

    Activity,Service,broadcast and Contentprovider android 4 大组件. ContentProvider:使用: public class Image ...

  7. Android四大组件之ContentProvider(二)读取设备上的图片、音频和视频

    Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,通过Content Provider的方式提供给用户.当设备开机或者有SD卡插拔等事件发生时, ...

  8. Android四大组件之——ContentProvider(二)

    Content Resolver介绍: 开发者文档中这么定义的: This class provides applications access to the content model. 这个类为应 ...

  9. Android 四大组件之四(ContentProvider)

    ContentProvider调用关系: ContentProvider(数据提供者)是应用程序之间共享数据的一种接口机制,是一种更为高级的数据共享方法. ContentProvider可以指定需要共 ...

随机推荐

  1. intellij中编译报错: The packaging for this project did not assign a file to the build artifact

    原因是run configuration -> maven -> preject name -> Parameters -> command line中是install:ins ...

  2. Unsupported major.minor version 51.0解决

    http://blog.csdn.net/justdb/article/details/7850212 解决:项目------>右键------>属性------>Java Comp ...

  3. SqlParameter设定value为0却变成null

    直接MSDN:http://msdn.microsoft.com/zh-cn/library/0881fz2y(VS.80).aspx 当在 value 参数中指定 Object 时,SqlDbTyp ...

  4. javascript 特殊的一些知识

    基础知识 1.注释/**/ 块注释,与正则表达式有冲突,不安全. 2.js数字类型只有一个,即为64位的浮动值 3.NaN是一个数值,他不能产生正常结果的运算结果.NaN不等于任何值,包括它自己.is ...

  5. 项目二(业务GO)——跨域上传图片(请求接口)

    之前,就听过“跨域上传”图片的问题,只是疏于研究,也就一再搁置,直至今天再次遇见这个不能避免的“坑”,才不得不思考一下,怎么“跨域上传”图片或者文件? 问题来源: 何为“跨域”? ——就是给你一个接口 ...

  6. iOS开发多线程篇—NSOperation简单介绍

    iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现 ...

  7. bzoj3730:震波

    题意:给一棵树,只有点权无边权, ,每次询问求以一个点为中心,半径为k的全职和. 考虑动态树分治.我们对于每个点(点分树)维护两个树状数组.两个树状数组都以距离为下标,权值为内容.第一个树状数组维护子 ...

  8. C++编程优化心得(持续更新)

    1. 对齐原则.比如64位总线,每次寻址读取8B.编程时注意变量地址,尽量消耗总线最少的寻址次数.堆内存申请时,系统严格按照对齐原则分配,故而使用时候也尽量不要跨寻址边界. 2. 需要的时候,可为了效 ...

  9. 二模 (15)day1

    第一题: 题目大意: 有两个长度为N的序列A和B,在A和B中各任取一个数相加可以得到N2个和,求这N2个和中最小的N个. 解题过程: 1.这题是刘汝佳<<训练指南>>上的一道经 ...

  10. HTTP 304

    304 的标准解释是:Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档).服务器告诉客户,原来缓冲的 ...