一、项目介绍
如何在 Android studio 中使用 “ 内容观察者 ” 去监测数据库中的数据,因此在该项目中需要创建两个程序去实现项目效果。一个实现对数据库中的数据进行操作,另一个用来监测数据库中的数据是否变化。
二、使用步骤
1.创建第一个程序
创建第一个程序命名为 ContentObserverDB , 指定包名为 cn.itcast.contentobserverdb 。
2.导入图片
3.放置界面控件
由于我们要建立一个操作数据库的界面,所以需要在 res/layout 文件夹中的 activity_main.xml 文件中放置四个 Button 按钮控件,分别表示 “添加” 、“更新” 、“删除” 、“查询” 。
代码如下:
4.创建数据库
显而易见我们要实现监测数据变化,自然要创建一个数据库。所以我们需要在 com.itcast.contentobserverdb 包下新建一个命名为 PersonDBOpenHelper 的java类,来继承 SQLiteOpenHelper 类。
代码如下:
package cn.itcast.contentobserverdb;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
public class PersonDBOpenHelper extends SQLiteOpenHelper {
//构造方法,调用此方法新建一个person.db的数据库并返回一个数据库帮助类的对象
public PersonDBOpenHelper(Context context) {
super(context,"person.db",null,1);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO: Implement this to initialize your content provider on startup.
// 创建该数据库的同时新建一个info表,表中有_id,name这两个字段
db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int oldVersion, int newVersion) {
}
}
5.创建内容提供者
选择程序中的 cn.itcast.contentobserverdb 包,单击鼠标右键,选择 【New】-> 【Other】-> 【Content Provide】选项,创建一个内容提供者命名为 PersonProvider 。
代码如下:
package cn.itcast.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 {
private static UriMatcher mUriMatcher = new UriMatcher(-1);
private static final int SUCCESS = 1;
private PersonDBOpenHelper helper;
static {
mUriMatcher.addURI("cn.itcast.contentobserverdb", "info", SUCCESS);
}
@Override
public boolean onCreate() {
helper = new PersonDBOpenHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
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("路径不正确,无法查询数据!");
}
}
@Override
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("路径不正确,无法插入数据!");
}
}
@Override
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("路径不正确,无法随便删除数据!");
}
}
@Override
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;
}
}
6.实现界面交互
对上文中创建的操作界面中的四个 Button 按钮控件在 java/cn.itcast.contentobserverdb 文件夹下创建命名为 MainActivity 的Java类中去实现具体操作功能。同时需要注意创建程序后会自动生产一个名为 MainActivity 的 kt 类,这两只是名字相同,不要搞混了。
代码如下:
package cn.itcast.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 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 = findViewById(R.id.btn_insert);
btnUpdate = findViewById(R.id.btn_update);
btnDelete = findViewById(R.id.btn_delete);
btnSelect = findViewById(R.id.btn_select);
btnInsert.setOnClickListener(this);
btnUpdate.setOnClickListener(this);
btnDelete.setOnClickListener(this);
btnSelect.setOnClickListener(this);
}
private void createDB() {
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();
}
@Override
public void onClick(View v) {
ContentResolver resolver = getContentResolver();
uri = Uri.parse("content://cn.itcast.contentobserverdb/info");
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
7.创建第二个程序
创建第二个程序,命名为 MonitorData ,指定包名为 cn.itcast.monitordata ,由于我们只需要对数据库的操作进行监测,所以就不需要再有主界面,我们可以直接 java/cn.itcast.monitordata 文件夹下创建一个命名为 MainActivity 的java类,来注册一个内容观察者,观察数据库是否发生了变化。
代码如下:
package cn.itcast.monitordata;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentProvider;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import cn.itcast.contentobserverdb.R;
public class MonitorData extends AppCompatActivity {
private MyObserver mMyObserver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyObserver = new MyObserver(new Handler());
//该Uri路径指向数据库应用中的数据库info表
Uri uri = Uri.parse("content://cn.itcast.contentobserverdb/info");
getContentResolver().registerContentObserver(uri,true,mMyObserver);
}
private class MyObserver extends ContentObserver{
public MyObserver(Handler handler) {
super(handler);
}
@Override
//当info表中的数据发生变化时则执行该方法
public void onChange(boolean selfChange) {
Log.i("监测数据变化", "有人动了你的数据库!");
super.onChange(selfChange);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消注册内容观察者
getContentResolver().unregisterContentObserver(mMyObserver);
}
}
运行程序。