简单步骤:Android studio 内容观察者 - 实现数据变化监测

提示:本篇文章将会尽量保持精简,附加图文解释,焦躁是敲写代码最大的敌人,三连是最大的支持!

本篇文章将会介绍如何使用 Android studio “内容观察者”,实现 “监测数据变化” 。文章尽量保持精简,并带有图文解释,努力让各位读者拥有更佳的观看体验。项目包括了前篇中的 “内容提供者” 的内容,如果对 “内容提供者” 的项目实施并不是很熟悉,可以先移步到另一篇文章 简单步骤:Android studio 内容提供者 - 实现读取手机通讯录_蛇形刁手的博客-CSDN博客


一、项目介绍

首先在这里不会过多的赘述 “ 内容观察者 ” 的具体知识点,着重介绍如何在 Android studio 中使用 “ 内容观察者 ” 去监测数据库中的数据,因此在该项目中需要创建两个程序去实现项目效果。一个实现对数据库中的数据进行操作,另一个用来监测数据库中的数据是否变化。

二、使用步骤

1.创建第一个程序

创建第一个程序命名为 ContentObserverDB , 指定包名为 com.itcast.contentobserverdb 。


2.导入图片

图片分别命名为 bg.png 和 btn_bg.png  (无水印),当然也可使用自己的图片(要注意修改代码中的图片名称)


 3.放置界面控件

由于我们要建立一个操作数据库的界面,所以需要在 res/layout 文件夹中的 activity_main.xml 文件中放置四个 Button 按钮控件,分别表示 “添加” 、“更新” 、“删除” 、“查询” 。

 代码如下:

<?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:background="@drawable/bg"
    android:orientation="vertical">
    <Button
        android:id="@+id/btn_insert"
        android:layout_width="120dp"
        android:layout_height="40dp"
        android:layout_marginLeft="40dp"
        android:layout_marginTop="30dp"
        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_marginTop="30dp"
        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_marginTop="30dp"
        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_marginTop="30dp"
        android:background="@drawable/btn_bg"
        android:text="查询"
        android:textColor="#006000"
        android:textSize="20dp" />
</LinearLayout>


4.创建数据库

显而易见我们要实现监测数据变化,自然要创建一个数据库。所以我们需要在 com.itcast.contentobserverdb 包下新建一个命名为 PersonDBOpenHelper 的java类,来继承 SQLiteOpenHelper 类。

代码如下: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itcast.contentobserverdb">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ContentObserverDB">
        <provider
            android:name=".PersonProvider"
            android:authorities="com.itcast.contentobserverdb"
            android:enabled="true"
            android:exported="true"></provider>

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

5.创建内容提供者

选择程序中的 com.itcast.contentobserverdb 包,单击鼠标右键,选择 【New】-> 【Other】-> 【Content Provide】选项,创建一个内容提供者命名为 PersonProvider 。

代码如下:

package com.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("com.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/com.itcast.contentobserverdb 文件夹下创建命名为 MainActivity Java类中去实现具体操作功能。同时需要注意创建程序后会自动生产一个名为 MainActivity 的 kt 类,这两只是名字相同,不要搞混了。

 

代码如下:

package com.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 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 = 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) {

        resolver = getContentResolver();

        uri = Uri.parse("content://com.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<Map<String, String>> data = new ArrayList<Map<String, String>>();

                Cursor cursor = resolver.query(uri, new String[]{"_id", "name"},
                        null, null, null);

                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:

                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;
        }
    }
}


7.创建第二个程序

创建第二个程序,命名为 MonitorData ,指定包名为 com.itcast.monitordata ,由于我们只需要对数据库的操作进行监测,所以就不需要再有主界面,我们可以直接 java/com.itcast.monitordata 文件夹下创建一个命名为 MainActivity 的java类,来注册一个内容观察者,观察数据库是否发生了变化。

代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.itcast.monitordata">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MonitorData">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

8.运行程序

<1>.我们在运行程序时,先回到我们的第一个 ContentObserverDB 程序 打开虚拟机,进行运行。

<2>.然后我们可以打开 Device File Explorer 窗口中(在整个 Android studio 界面的右下角) 根据 【data】->【data】->【com.itcast.contentoberverfb】->【databases】 路径查看系统是否已经生成了 数据库文件 person.db 。

 <3>.我们再回到第二个 MonitorData 程序进行运行,然后在 ContentObserverDB 程序界面中分别点击  “添加” 、“更新” 、“删除” 、“查询” 四个按钮,这时界面下方就会出现反馈。

示例效果图:

<4>.最后完成上诉操作后,我们可以点开 Logcat 窗口去查看输出的 Log 信息。


总结

以上就是 Android studio 内容观察者 - 实现数据变化监测的具体操作,由于每个人的配置、编写习惯等等多种原因,如果在实际操作中出现问题,或者发现文章中的错误,也可以在评论区中发表出来,尽能所答,欢迎指点与建议。

编写不易,关注、三连是最大的支持!!!

欢迎建议,感谢支持!!!

猜你喜欢

转载自blog.csdn.net/qq_56017400/article/details/124295009