<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:background="@drawable/bg"
tools:context=".MainActivity">
<Button
android:id="@+id/btn_insert"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_marginLeft="40dp"
android:layout_marginStart="40dp"
android:layout_marginTop="50dp"
android:background="@drawable/btn_bg"
android:text="添加"
android:textColor="#006000"
android:textSize="20dp"/>
<Button
android:id="@+id/btn_update"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_marginLeft="80dp"
android:layout_marginStart="80dp"
android:layout_marginTop="120dp"
android:background="@drawable/btn_bg"
android:text="更新"
android:textColor="#006000"
android:textSize="20dp"/>
<Button
android:id="@+id/btn_delete"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_marginLeft="120dp"
android:layout_marginStart="120dp"
android:layout_marginTop="190dp"
android:background="@drawable/btn_bg"
android:text="删除"
android:textColor="#006000"
android:textSize="20dp"/>
<Button
android:id="@+id/btn_select"
android:layout_width="120dp"
android:layout_height="40dp"
android:layout_marginLeft="160dp"
android:layout_marginStart="160dp"
android:layout_marginTop="260dp"
android:background="@drawable/btn_bg"
android:text="查询"
android:textColor="#006000"
android:textSize="20dp"/>
</RelativeLayout>
1.MainActivity.java代码:
package com.example.contentobserverdb;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private ContentResolver resolver;
private Uri uri;
private ContentValues values;
private Button btnInsert;
private Button btnUpdate;
private Button btnDelete;
private Button btnSelect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();//初始化界面
createDB();//创建数据库
}
private void initView() {
btnInsert = (Button) findViewById(R.id.btn_insert);
btnUpdate = (Button) findViewById(R.id.btn_update);
btnDelete = (Button) findViewById(R.id.btn_delete);
btnSelect = (Button) findViewById(R.id.btn_select);
btnInsert.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
btnDelete.setOnClickListener(this);
btnSelect.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//得到一个内容提供者的解析对象
resolver = getContentResolver();
//新加一个uri路径,参数是string类型的
uri = Uri.parse("content://com.example.contentobserverdb/info");
//新建一个ContentValues对象,该对象以key-values的形式来添加记录到数据库表中
values = new ContentValues();
switch (v.getId()) {
case R.id.btn_insert:
Random random = new Random();
values.put("name", "add_itcast" + random.nextInt(10));
Uri newuri = resolver.insert(uri, values);
Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();
Log.i("数据库应用:", "添加");
break;
case R.id.btn_delete:
//返回删除数据的条目数
int deleteCount = resolver.delete(uri, "name=?",
new String[]{"itcast0"});
Toast.makeText(this, "成功删除了" + deleteCount + "行", Toast.LENGTH_SHORT).show();
Log.i("数据库应用:", "删除");
break;
case R.id.btn_select:
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
//返回查询结果,是一个指向结果集的游标
Cursor cursor = resolver.query(uri, new String[]{"_id", "name"},
null, null, null);
//遍历结果集中的数据,将每一条遍历的结果存储在一个List的集合中
while (cursor.moveToNext()) {
Map<String, String> map = new HashMap<String, String>();
map.put("_id", cursor.getString(0));
map.put("name", cursor.getString(1));
data.add(map);
}
//关闭游标,释放资源
cursor.close();
Log.i("数据库应用:", "查询结果:" + data.toString());
break;
case R.id.btn_update:
//将数据库info表中name为itcast1的这条记录更改为name是update_itcast
values.put("name", "update_itcast");
int updateCount = resolver.update(uri, values, "name=?",
new String[]{"itcast1"});
Toast.makeText(this, "成功更新了" + updateCount + "行", Toast.LENGTH_SHORT).show();
Log.i("数据库应用:", "更新");
break;
}
}
private void createDB() {
//创建数据库并向info表中添加3条数据
PersonDBOpenHelper helper = new PersonDBOpenHelper(this);
SQLiteDatabase db = helper.getWritableDatabase();
for (int i = 0; i < 3; i++) {
ContentValues values = new ContentValues();
values.put("name", "itcast" + i);
db.insert("info", null, values);
}
db.close();
}
}
2、PersonProvider代码:
package com.example.contentobserverdb;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class PersonProvider extends ContentProvider {
//定义一个uri路径的匹配器,如果路径匹配不成功返回 -1
private static UriMatcher mUriMatcher = new UriMatcher(-1);
//匹配路径成功时的返回码
private static final int SUCCESS = 1;
//数据库操作类的对象
private PersonDBOpenHelper helper;
//添加路径匹配器的规则
static {
mUriMatcher.addURI("cn.itcast.contentobserverdb", "info", SUCCESS);
}
//当内容提供者被创建的时候调用
public boolean onCreate() {
helper = new PersonDBOpenHelper(getContext());
return false;
}
//查询数据操作
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
//匹配查询的Uri路径
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
return db.query("info", projection, selection, selectionArgs,
null, null, sortOrder);
} else {
throw new IllegalArgumentException("路径不正确,我是不会给你提供数据的!");
}
}
//添加数据操作
public Uri insert(Uri uri, ContentValues values) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getReadableDatabase();
long rowId = db.insert("info", null, values);
if (rowId > 0) {
Uri insertedUri = ContentUris.withAppendedId(uri, rowId);
//提示数据库的内容变化了
getContext().getContentResolver().notifyChange(insertedUri, null);
return insertedUri;
}
db.close();
return uri;
} else {
throw new IllegalArgumentException("路径不正确,我是不会给你插入数据的!");
}
}
//删除数据操作
public int delete(Uri uri, String selection, String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.delete("info", selection, selectionArgs);
//提示数据库的内容变化了
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
db.close();
return count;
} else {
throw new IllegalArgumentException("路径不正确,我是不会让你随便删除数据的!");
}
}
//更新数据操作
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int code = mUriMatcher.match(uri);
if (code == SUCCESS) {
SQLiteDatabase db = helper.getWritableDatabase();
int count = db.update("info", values, selection, selectionArgs);
//提示数据库的内容变化了
if (count > 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
db.close();
return count;
} else {
throw new IllegalArgumentException("路径不正确,我是不会让你更新数据的!");
}
}
@Override
public String getType(Uri uri) {
return null;
}
}
3、PersonDBOpenHelper代码:
package com.example.contentobserverdb;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class PersonDBOpenHelper extends SQLiteOpenHelper {
//构造方法,调用此方法新建一个person.db的数据库并返回一个数据库帮助类的对象
public PersonDBOpenHelper(Context context) {
super(context, "person.db", null, 1);
}
@Override
public void onCreate(SQLiteDatabase db) {
//创建该数据库的同时新建一个info表,表中有_id,name这两个字段
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
二、MonitorData的逻辑代码:
package com.example.monitordata;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 该uri路径指向数据库应用中的数据库info表
Uri uri = Uri.parse("content://cn.itcast.contentobserverdb/info");
//注册内容观察者,参数uri指向要监测的数据库info表,
//参数true定义了监测的范围,最后一个参数是一个内容观察者对象
getContentResolver().registerContentObserver(uri, true,
new MyObserver(new Handler()));
}
private class MyObserver extends ContentObserver {
public MyObserver(Handler handler) {//handler 是一个消息处理器。
super(handler);
}
@Override
//当info表中的数据发生变化时则执行该方法
public void onChange(boolean selfChange) {
Log.i("监测数据变化", "有人动了你的数据库!");
super.onChange(selfChange);
}
}
}