ContentData类,提供数据常量:

/**
* 提供ContentProvider对外的各种常量,当外部数据需要访问的时候,就可以参考这些常量操作数据。
* @author HB
*
*/
public class ContentData {
public static final String AUTHORITY = "hb.android.contentProvider";
public static final String DATABASE_NAME = "teacher.db";
//创建 数据库的时候,都必须加上版本信息;并且必须大于4
public static final int DATABASE_VERSION = ;
public static final String USERS_TABLE_NAME = "teacher"; public static final class UserTableData implements BaseColumns {
public static final String TABLE_NAME = "teacher";
//Uri,外部程序需要访问就是通过这个Uri访问的,这个Uri必须的唯一的。
public static final Uri CONTENT_URI = Uri.parse("content://"+ AUTHORITY + "/teacher");
// 数据集的MIME类型字符串则应该以vnd.android.cursor.dir/开头
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/hb.android.teachers";
// 单一数据的MIME类型字符串应该以vnd.android.cursor.item/开头
public static final String CONTENT_TYPE_ITME = "vnd.android.cursor.item/hb.android.teacher";
/* 自定义匹配码 */
public static final int TEACHERS = ;
/* 自定义匹配码 */
public static final int TEACHER = ; public static final String TITLE = "title";
public static final String NAME = "name";
public static final String DATE_ADDED = "date_added";
public static final String SEX = "SEX";
public static final String DEFAULT_SORT_ORDER = "_id desc"; public static final UriMatcher uriMatcher;
static {
// 常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// 如果match()方法匹配content://hb.android.teacherProvider/teachern路径,返回匹配码为TEACHERS
uriMatcher.addURI(ContentData.AUTHORITY, "teacher", TEACHERS);
// 如果match()方法匹配content://hb.android.teacherProvider/teacher/230,路径,返回匹配码为TEACHER
uriMatcher.addURI(ContentData.AUTHORITY, "teacher/#", TEACHER);
}
}
}

SQLite操作类DBOpenHelper

/**
* 这个类继承SQLiteOpenHelper抽象类,用于创建数据库和表。创建数据库是调用它的父类构造方法创建。
* @author HB
*/
public class DBOpenHelper extends SQLiteOpenHelper { // 在SQLiteOepnHelper的子类当中,必须有该构造函数,用来创建一个数据库;
public DBOpenHelper(Context context, String name, CursorFactory factory,
int version) {
// 必须通过super调用父类当中的构造函数
super(context, name, factory, version);
// TODO Auto-generated constructor stub
} // public DBOpenHelper(Context context, String name) {
// this(context, name, VERSION);
// } public DBOpenHelper(Context context, String name, int version) {
this(context, name, null, version);
} /**
* 只有当数据库执行创建 的时候,才会执行这个方法。如果更改表名,也不会创建,只有当创建数据库的时候,才会创建改表名之后 的数据表
*/
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("create table");
db.execSQL("create table " + ContentData.UserTableData.TABLE_NAME
+ "(" + ContentData.UserTableData._ID
+ " INTEGER PRIMARY KEY autoincrement,"
+ ContentData.UserTableData.NAME + " varchar(20),"
+ ContentData.UserTableData.TITLE + " varchar(20),"
+ ContentData.UserTableData.DATE_ADDED + " long,"
+ ContentData.UserTableData.SEX + " boolean)" + ";");
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }

内容提供者类

/**
* 这个类给外部程序提供访问内部数据的一个接口
* @author HB
*
*/
public class TeacherContentProvider extends ContentProvider { private DBOpenHelper dbOpenHelper = null;
// UriMatcher类用来匹配Uri,使用match()方法匹配路径时返回匹配码
private static final UriMatcher uriMatcher=new UriMatcher(UriMatcher.NO_MATCH); /**
* 是一个回调函数,在ContentProvider创建的时候,就会运行,第二个参数为指定数据库名称,如果不指定,就会找不到数据库;
* 如果数据库存在的情况下是不会再创建一个数据库的。(当然首次调用 在这里也不会生成数据库必须调用SQLiteDatabase的 getWritableDatabase,getReadableDatabase两个方法中的一个才会创建数据库)
*/
@Override
public boolean onCreate() {
//这里会调用 DBOpenHelper的构造函数创建一个数据库;
dbOpenHelper = new DBOpenHelper(this.getContext(), ContentData.DATABASE_NAME, ContentData.DATABASE_VERSION);
return true;
}
/**
* 当执行这个方法的时候,如果没有数据库,他会创建,同时也会创建表,但是如果没有表,下面在执行insert的时候就会出错
* 这里的插入数据也完全可以用sql语句书写,然后调用 db.execSQL(sql)执行。
*/
@Override
public Uri insert(Uri uri, ContentValues values){
//获得一个可写的数据库引用,如果数据库不存在,则根据onCreate的方法里创建;
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
long id = ; switch (uriMatcher.match(uri)) {
case TEACHERS:
id = db.insert("teacher", null, values); // 返回的是记录的行号,主键为int,实际上就是主键值
return ContentUris.withAppendedId(uri, id);
case TEACHER:
id = db.insert("teacher", null, values);
String path = uri.toString();
return Uri.parse(path.substring(, path.lastIndexOf("/"))+id); // 替换掉id
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int count = ;
switch (uriMatcher.match(uri)) {
case TEACHERS:
count = db.delete("teacher", selection, selectionArgs);
break;
case TEACHER:
// 下面的方法用于从URI中解析出id,对这样的路径content://hb.android.teacherProvider/teacher/10
// 进行解析,返回值为10
long personid = ContentUris.parseId(uri);
String where = "_ID=" + personid; // 删除指定id的记录
where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : ""; // 把其它条件附加上
count = db.delete("teacher", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
db.close();
return count;
} @Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int count = ;
switch (uriMatcher.match(uri)) {
case TEACHERS:
count = db.update("teacher", values, selection, selectionArgs);
break;
case TEACHER:
// 下面的方法用于从URI中解析出id,对这样的路径content://com.ljq.provider.personprovider/person/10
// 进行解析,返回值为10
long personid = ContentUris.parseId(uri);
String where = "_ID=" + personid;// 获取指定id的记录
where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
count = db.update("teacher", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
db.close();
return count;
} @Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case TEACHERS:
return CONTENT_TYPE;
case TEACHER:
return CONTENT_TYPE_ITME;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
} @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (uriMatcher.match(uri)) {
case TEACHERS:
return db.query("teacher", projection, selection, selectionArgs, null, null, sortOrder);
case TEACHER:
// 进行解析,返回值为10
long personid = ContentUris.parseId(uri);
String where = "_ID=" + personid;// 获取指定id的记录
where += !TextUtils.isEmpty(selection) ? " and (" + selection + ")" : "";// 把其它条件附加上
return db.query("teacher", projection, where, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
}
}

文件清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="hb.android.contentProvider"
android:versionCode=""
android:versionName="1.0">
<uses-sdk android:minSdkVersion="" /> <application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".TeacherActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<span style="white-space:pre"> </span><provider android:name=".TeacherContentProvider"
<span style="white-space:pre"> </span>android:authorities="hb.android.contentProvider" />
</application>
</manifest>

main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/insert"
android:text="@string/insert"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/query"
android:text="@string/query"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/querys"
android:text="@string/querys"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/update"
android:text="@string/update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/delete"
android:text="@string/delete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

TeacherActivity内容提供者测试类

package hb.android.contentProvider;

import java.util.Date;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; /**
* 这个类用来测试ContentProvider是否可用。通过 给定的uri访问,数据库;
*
* @author HB
*
*/
public class TeacherActivity extends Activity {
Button insert;
Button query;
Button update;
Button delete;
Button querys;
Uri uri = Uri.parse("content://hb.android.contentProvider/teacher"); /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); insert = (Button) findViewById(R.id.insert);
query = (Button) findViewById(R.id.query);
update = (Button) findViewById(R.id.update);
delete = (Button) findViewById(R.id.delete);
querys = (Button) findViewById(R.id.querys);
// 绑定监听器的两种方法一;
insert.setOnClickListener(new InsertListener());
query.setOnClickListener(new QueryListener());
// 方法二
update.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
ContentResolver cr = getContentResolver();
ContentValues cv = new ContentValues();
cv.put("name", "huangbiao");
cv.put("date_added", (new Date()).toString());
int uri2 = cr.update(uri, cv, "_ID=?", new String[]{""});
System.out.println("updated"+":"+uri2);
}
}); delete.setOnClickListener(new OnClickListener() { public void onClick(View v) {
ContentResolver cr = getContentResolver();
cr.delete(uri, "_ID=?", new String[]{""});
}
}); querys.setOnClickListener(new OnClickListener() { public void onClick(View v) {
// TODO Auto-generated method stub
ContentResolver cr = getContentResolver();
// 查找id为1的数据
Cursor c = cr.query(uri, null, null,null, null);
System.out.println(c.getCount());
c.close();
}
});
} class InsertListener implements OnClickListener { public void onClick(View v) {
// TODO Auto-generated method stub
ContentResolver cr = getContentResolver(); ContentValues cv = new ContentValues();
cv.put("title", "jiaoshou");
cv.put("name", "jiaoshi");
cv.put("sex", true);
Uri uri2 = cr.insert(uri, cv);
System.out.println(uri2.toString());
} } class QueryListener implements OnClickListener { public void onClick(View v) {
// TODO Auto-generated method stub
ContentResolver cr = getContentResolver();
// 查找id为1的数据
Cursor c = cr.query(uri, null, "_ID=?", new String[] { "" }, null);
//这里必须要调用 c.moveToFirst将游标移动到第一条数据,不然会出现index -1 requested , with a size of 1错误;cr.query返回的是一个结果集。
if (c.moveToFirst() == false) {
// 为空的Cursor
return;
}
int name = c.getColumnIndex("name");
System.out.println(c.getString(name));
c.close();
}
}
}

运行结果为:

Android ContentProvider完整案例的更多相关文章

  1. Android实训案例(五)——四大组件之一ContentProvider的使用,通讯录的实现以及ListView的优化

    Android实训案例(五)--四大组件之一ContentProvider的使用,通讯录的实现 Android四大组件是啥这里就不用多说了,看图吧,他们之间通过intent通讯 我们后续也会一一的为大 ...

  2. Android实训案例(六)——四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听

    Android实训案例(六)--四大组件之一BroadcastReceiver的基本使用,拨号,短信,SD卡,开机,应用安装卸载监听 Android中四大组件的使用时重中之重,我这个阶段也不奢望能把他 ...

  3. Android基础 : Android ContentProvider

    Android 应用程序通过ContentProvider实现方式统一的数据共享功能. 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activi ...

  4. JavaEE开发之记事本完整案例(SpringBoot + iOS端)

    上篇博客我们聊了<JavaEE开发之SpringBoot整合MyBatis以及Thymeleaf模板引擎>,并且在之前我们也聊了<Swift3.0服务端开发(五) 记事本的开发(iO ...

  5. Android实训案例(九)——答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程

    Android实训案例(九)--答题系统的思绪,自己设计一个题库的体验,一个思路清晰的答题软件制作过程 项目也是偷师的,决心研究一下数据库.所以写的还是很详细的,各位看官,耐着性子看完,实现结果不重要 ...

  6. Android实训案例(八)——单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局

    Android实训案例(八)--单机五子棋游戏,自定义棋盘,线条,棋子,游戏逻辑,游戏状态存储,再来一局 阿法狗让围棋突然就被热议了,鸿洋大神也顺势出了篇五子棋单机游戏的视频,我看到了就像膜拜膜拜,就 ...

  7. Android实训案例(四)——关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程!

    Android实训案例(四)--关于Game,2048方块的设计,逻辑,实现,编写,加上色彩,分数等深度剖析开发过程! 关于2048,我看到很多大神,比如医生,郭神,所以我也研究了一段时间,还好是研究 ...

  8. Android实训案例(三)——实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果!

    Android实训案例(三)--实现时间轴效果的ListView,加入本地存储,实现恋爱日记的效果! 感叹离春节将至,也同时感叹时间不等人,一年又一年,可是我依然是android道路上的小菜鸟,这篇讲 ...

  9. Android实训案例(二)——Android下的CMD命令之关机重启以及重启recovery

    Android实训案例(二)--Android下的CMD命令之关机重启以及重启recovery Android刚兴起的时候,着实让一些小众软件火了一把,切水果,Tom猫,吹裙子就是其中的代表,当然还有 ...

随机推荐

  1. lesson9:分布式定时任务

    在实际的开发过程中,我们一定会遇到服务自有的定时任务,又因为现在的服务都是分布式的,但是对于定时任务,很多的业务场景下,还是只希望单台服务来执行,网上有很多分布式定时任务的框架,各位如感兴趣,可以自行 ...

  2. vector的含义

    数学中,vector(向量)表示一个量,由大小和方向构成.比如坐标中的一个带箭头的线段 -- 它1厘米长,正弦值六分之一π(30度角). 计算机的c++.java中,vector表示一种一维的数组.比 ...

  3. Android开发系列(十八):自己定义控件样式在drawable目录下的XML实现

    在Android开发的过程中,我们常常须要对控件的样式做一下改变,能够通过用添加背景图片的方式进行改变,可是背景图片放多了肯定会使得APK文件变的非常大. 我们能够用自己定义属性shape来实现. s ...

  4. java web mvc思想介绍

    1.首先简介一下什么是MVC思想. 在百度百科里面对MVC的说明,MVC全名是Model View Controller.是模型(model)-视图(view)-控制器(controller)的缩写. ...

  5. 实用bootstrap 表格控件

    http://wenzhixin.net.cn/p/bootstrap-table/docs/examples.html

  6. css06背景图片

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. tomcat startup.sh提示java.lang.OutOfMemoryError: PermGen space

    JAVA_OPTS="-server -XX:PermSize=512M -XX:MaxPermSize=1024m"if [ -z "$LOGGING_MANAGER& ...

  8. C#线程 访问资源同步简介

    在多线程应用(一个或多个处理器)的计算中会使用到同步这个词.实际上,这些应用程序的特点就是它们拥有多个执行单元,而这些单元在访问资源的时候可能会发生冲突.线程间会共享同步对象,而同步对象的目的在于能够 ...

  9. webclient乱码问题

    我的备注:这个方法可以得到相关页面的源代码,查看页面编码,浏览器中右键>选择编码就看到所用的编码类型了 webclient在调用DownloadData或者DownloadString的时候请求 ...

  10. HTML 控件和web控件 OnClientClick和OnClick OnServerClick区别

      ^_^ 本来对html控件,服务器控件的知识模模糊糊的.今天特地查了相关的知识. 下面是我写代码总结的. 这些事件   主要用于在客户端执行验证,然后决定是否执行服务端事件   (没接触之前就为此 ...