工具:Android Studio
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"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg"/>
<TextView
android:id="@+id/tv_des"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
android:paddingLeft="20dp"
android:text="读取到的系统短信信息如下:"
android:textSize="20sp"
android:visibility="invisible"/>
<TextView
android:id="@+id/tv_sms"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_des"
android:lines="20"
android:paddingLeft="20dp"
android:paddingTop="10dp"
android:textSize="16sp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="28dp"
android:layout_marginLeft="26dp"
android:layout_marginStart="26dp"
android:background="#D9D1FA"
android:onClick="readSMS"
android:text="查看短信"
android:textSize="30sp"/>
</RelativeLayout>
SmsInfo.java
package com.example.readsms;
public class SmsInfo {
private int _id;//短信的主键
private String address;//发送地址
private int type;//类型
private String body;//短信内容
private long date;//时间
//构造方法
public SmsInfo(int _id,String address,int type,String body,long date){
this._id=_id;
this.address=address;
this.type=type;
this.body=body;
this.date=date;
}
public int get_id(){
return _id;
}
public void set_id(int _id){
this._id=_id;
}
public String getAddress(){
return address;
}
public void setAddress(String address){
this.address=address;
}
public int getType(){
return type;
}
public void setType(int type){
this.type=type;
}
public String getBody(){
return body;
}
public void setBody(String body){
this.body=body;
}
public long getDate(){
return date;
}
public void setDate(long date){
this.date=date;
}
}
MainActivity.java
> package com.example.readsms;
>
> import androidx.appcompat.app.AppCompatActivity; import
> android.content.ContentResolver; import android.database.Cursor;
> import android.net.Uri; import android.view.View; import
> android.widget.TextView; import java.util.ArrayList; import
> java.util.List;
>
> import android.os.Bundle;
>
> public class MainActivity extends AppCompatActivity {
> private TextView tvSms;
> private TextView tvDes;
> private String text = "";
>
> @Override
> protected void onCreate(Bundle savedInstanceState) {
> super.onCreate(savedInstanceState);
> setContentView(R.layout.activity_main);
> tvSms = (TextView) findViewById(R.id.tv_sms);
> tvDes = (TextView) findViewById(R.id.tv_des);
> }
> //单击Button时触发的方法
> public void readSMS(View view){
> //查询系统信息的Uri
> Uri uri = Uri.parse("content://sms/");
> //获取ContentResolver对象
> ContentResolver resolver = getContentResolver();
> //通过ContentResolver对象查询系统短信
> Cursor cursor = resolver.query(uri,new String[]{"_id","address","type","body","date"},null,null,null);
> List<SmsInfo> smsInfos = new ArrayList<SmsInfo>();
> if(cursor != null && cursor.getCount() > 0){
> tvDes.setVisibility(View.VISIBLE);
> while (cursor.moveToNext()){
> int _id = cursor.getInt(0);
> String address = cursor.getString(1);
> int type = cursor.getInt(2);
> String body = cursor.getString(3);
> long date = cursor.getLong(4);
> SmsInfo smsInfo = new SmsInfo(_id,address,type,body,date);
> smsInfos.add(smsInfo);
> }
> cursor.close();
> }
> //将查询到的短信内容显示到界面上
> for(int i = 0;i < smsInfos.size();i++){
> text += "手机号码:" + smsInfos.get(i).getAddress() + "\n";
> text += "短信内容:" + smsInfos.get(i).getBody() + "\n\n";
> tvSms.setText(text);
> }
> } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.readsms">
<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/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_SMS"/>
</manifest>
源代码:
activity_main.xml
<?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"
android:orientation="vertical" 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:backgroundTint="@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:backgroundTint="@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:backgroundTint="@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:backgroundTint="@drawable/btn_bg"
android:text="查询"
android:textColor="#006000"
android:textSize="20dp"/>
</RelativeLayout>
PersonDBOpenHelper.java
package cn.itcast.contentobserverdb;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabaseLockedException;
import android.database.sqlite.SQLiteOpenHelper;
public class PersonDBOpenHelper extends SQLiteOpenHelper
{
public PersonDBOpenHelper(Context context)
{
super(context,"person.db",null,1);
}
public void onCreate(SQLiteDatabase db)
{
db.execSQL("create table info (_id integer primary key autoincrement,name varchar(20))");
}
public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)
{
}
}
PersonProvider.java
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.service","info",SUCCESS);
}
public boolean onCreate()
{
helper=new PersonDBOpenHelper(getContext());
return false;
}
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("路径不正确,我是不会给你提供数据的!");
}
}
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.getReadableDatabase();
int count=db.update("info",values,selection,selectionArgs);
if(count>0)
{
getContext().getContentResolver().notifyChange(uri,null);
}
db.close();
return count;
}else {
throw new IllegalArgumentException("路径不正确,我是不会给你更新数据的!");
}
}
public String getType(Uri uri)
{
return null;
}
}
MainActivity.java(ContentObserverDB)
package cn.itcast.contentobserverdb;
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.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import android.os.Bundle;
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://cn.itcast.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();
}
}
MainActivity.java(MonitorData)
package cn.itcast.monitordata;
import androidx.appcompat.app.AppCompatActivity;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import android.os.Bundle;
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);
}
}
}