介绍:
用于监测数据库的变化,因此需要创建两个程序,一个用与操作数据库,一个用于监测数据库变化。当数据库发生变化时,监测数据库的程序会立即响应。接下来创建操作数据库的程序
布局:
- 所有包
- 操作数据库
- 监测数据库的变化
代码:
- 创建项目:
项目名:ContentObserverDB - activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".activity.MainActivity"> <Button android:id="@+id/btu_insert" android:layout_width="120dp" android:layout_height="40dp" android:layout_marginLeft="40dp" android:layout_marginStart="40dp" android:layout_marginTop="50dp" android:text="添加" android:textColor="#006000" android:textSize="20dp"/> <Button android:id="@+id/btu_update" android:layout_width="120dp" android:layout_height="40dp" android:layout_marginStart="80dp" android:layout_marginLeft="80dp" android:layout_marginTop="120dp" android:text="更新" android:textColor="#006000" android:textSize="20dp" /> <Button android:id="@+id/btu_delete" android:layout_width="120dp" android:layout_height="40dp" android:layout_marginLeft="120dp" android:layout_marginStart="120dp" android:layout_marginTop="190dp" android:text="删除" android:textColor="#006000" android:textSize="20dp"/> <Button android:id="@+id/btu_select" android:layout_width="120dp" android:layout_height="40dp" android:layout_marginStart="160dp" android:layout_marginLeft="160dp" android:layout_marginTop="260dp" android:text="查询" android:textColor="#006000" android:textSize="20dp" /> </RelativeLayout>
- MainActivity
package com.e.contentobserverdb.activity; import androidx.appcompat.app.AppCompatActivity; 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.os.ConditionVariable; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.e.contentobserverdb.R; import com.e.contentobserverdb.others.PersonDBOpenHelper; import java.util.ArrayList; import java.util.Currency; 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 Button btnInsert; private Button btnUpdate; private Button btnDelete; private Button btnSelect; private ConditionVariable variable; private ContentValues values; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView();//初始化界面 createDB();//创建数据库 } //初始化界面 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(); } //创建数据库 private void initView() { btnInsert = (Button) findViewById(R.id.btu_insert); btnDelete = (Button) findViewById(R.id.btu_delete); btnSelect = (Button) findViewById(R.id.btu_select); btnUpdate = (Button) findViewById(R.id.btu_update); btnInsert.setOnClickListener(this); btnDelete.setOnClickListener(this); btnSelect.setOnClickListener(this); btnUpdate.setOnClickListener(this); } @Override public void onClick(View v) { //得到一个内容提供者的解析对象 resolver = getContentResolver(); //新加一个uri路径,参数是string类型的 uri = Uri.parse("content://cn.contentobserverdb/info"); //新建一个ContentValues对象,该对象以key-values的形式来添加记录到数据库中 values = new ContentValues(); switch (v.getId()){ case R.id.btu_insert: Random random = new Random(); //random.nextInt(10)随机生成一个(0,10)的正数 values.put("name","新增"+random.nextInt(10)); Uri newuri = resolver.insert(uri,values); Toast.makeText(this,"添加成功",Toast.LENGTH_SHORT).show(); Log.i("数据库应用","添加"); break; case R.id.btu_delete: //返回删除数据的条目数 //int deleteCount = resolver.delete(uri,"name=?,new string[]){"新增0"}}; int deleteCount = resolver.delete(uri,null,null); Toast.makeText(this,"成功删除了" + deleteCount + "行",Toast.LENGTH_SHORT).show(); Log.i("数据库应用","删除"); break; case R.id.btu_select: List<Map<String,String>> data = new ArrayList<>(); //返回查询结果,是一个指向结果的游标 Cursor cursor = resolver.query(uri,new String[]{"_id","name"},null,null,null); while (cursor.moveToNext()) { Map<String,String> map = new HashMap<>(); 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.btu_update: //将数据库info表中那么为itcase1这条记录update_itcast values.put("name","update_itcast"); int updateCount = resolver.update(uri,values,"name=?",new String[]{"更新"}); if (updateCount!=0){ Toast.makeText(this,"成功更新了"+updateCount+"行",Toast.LENGTH_SHORT).show(); Log.i("数据库应用","更新"); }else { Toast.makeText(this,"没有好到更新的数据",Toast.LENGTH_SHORT).show(); } break; } } }
- PersonDBOpenHelper
package com.e.contentobserverdb.others; 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) { } }
- PersonProvder
package com.e.contentobserverdb.others; 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.contentobserverdb","info",SUCCESS); } public PersonProvider() { } @Override //删除数据操纵作 public int delete(Uri uri, String selection, String[] selectionArgs) { // Implement this to handle requests to delete one or more rows. 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 UnsupportedOperationException("路径不正确,我是不会让你随便删除数据库的!"); } } @Override public String getType(Uri uri) { // TODO: Implement this to handle requests for the MIME type of the data // at the given URI. return null; } @Override //添加数据操作 public Uri insert(Uri uri, ContentValues values) { // TODO: Implement this to handle requests to insert a new row. 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 UnsupportedOperationException("数据路今年不正确,我是不会给你插入数据的!"); } } @Override //当类容提供者被创键的时候调用 public boolean onCreate() { // TODO: Implement this to initialize your content provider on startup. helper = new PersonDBOpenHelper(getContext()); return false; } @Override //查询数据操作 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO: Implement this to handle query requests from clients. //匹配查询的uri路径 int code = mUriMatcher.match(uri); if (code == SUCCESS){ SQLiteDatabase db = helper.getReadableDatabase(); return db.query("into",projection,selection,selectionArgs,null,null,sortOrder); }else { throw new IllegalArgumentException("路径不真确,我们时不会给你提供数据的!"); } } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO: Implement this to handle requests to update one or more rows. 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 UnsupportedOperationException("Not yet implemented"); } } }
运行结果:
- 效果图
- 点击添加
- monitordata结果
- app结果
- monitordata结果
- 点击更新
- monitordata结果
- app结果
- 点击删除
- monitordata结果
- app结果
- 点击查询
- monitordata结果
- app结果
自己做出现的错误
(给大家避一下雷)