使用ContentResolver读取通话记录与短信记录

本文介绍如何使用Android系统的ContentResolver来读取设备上的短信和通话记录,包括所需权限及动态权限申请流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所需要知道的内容包括:
(一)短信Uri:
content://sms 所有短信
content://sms/outbox 发送箱中的短信
content://sms/inbox 收件箱中短信
【数据库中主要字段:】
短信手机号码 : address
短信标题: subject
短信内容:body
短信发送时间戳:date
短信类型:type 【0:待发信息; 1:接收到信息; 2:发出】
_id
(二)、通话记录Uri:
content://call_log/calls
所有通话记录 “_id”, “number”, “date”, “type”
(三) 过去Resolver对象
getContentResolver()
调用Resolver的方法:
insert()/delete/update/query 对应参数:2,3,4,5

insert()
public final @Nullable Uri insert(@NonNull Uri url, @Nullable ContentValues values)
delete()
int update(@NonNull Uri uri, @Nullable ContentValues values,
@Nullable String where, @Nullable String[] selectionArgs)
update()
int update(@NonNull Uri uri, @Nullable ContentValues values,
@Nullable String where, @Nullable String[] selectionArgs)
query()
public final @Nullable Cursor query(@NonNull Uri uri, @Nullable String[] projection,
@Nullable String selection, @Nullable String[] selectionArgs,
@Nullable String sortOrder)
参数说明:
Uri uri : uri地址
String[] projection:查询的列的列名
String selection:带占位符(?)的查询条件
String[] selectionArgs:替换占位符?的字符串数组
String sortOrder :排序方式
比如 按 _id 降序 >> _id desc
order by 关键字可以不用写
实例:
实现如下功能,读取系统通话记录与短信记录。
在界面上输出最后一次的通话记录 与短信记录
实现代码如下:

package com.oldeleven.day18_contentresolversmslogcalllogfirst;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Context mContext = this;
    private TextView textView_main_sms;
    private TextView textView_main_call;
    private ContentResolver resolver = null;
    private static final String URI_SMS_LOG = "content://sms";
    private static final String URI_CALL_LOG = "content://call_log/calls";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        readSmsLog();

        readCallLog();
    }

    private void readCallLog() {
        Cursor cursor_call = resolver.query(Uri.parse(URI_CALL_LOG), new String[]{"_id", "number", "date", "type"}, null, null, "_id desc limit 0,1");
        if (cursor_call != null){
            cursor_call.moveToFirst();
            if (cursor_call.getCount() > 0){
                String id = cursor_call.getString(cursor_call.getColumnIndex("_id"));
                String number = cursor_call.getString(cursor_call.getColumnIndex("number"));
                String date = cursor_call.getString(cursor_call.getColumnIndex("date"));
                String type = cursor_call.getString(cursor_call.getColumnIndex("type"));
                textView_main_call.append(id + ":" + number + ":" + date + ":" + type );
            }
            cursor_call.close();
        }

    }

    private void readSmsLog() {
        Cursor cursor_sms = resolver.query(Uri.parse(URI_SMS_LOG), new String[]{"_id", "address", "body", "date", "type"}, null, null, "_id desc limit 1");
        if (cursor_sms != null){
            cursor_sms.moveToFirst();
            if (cursor_sms.getCount() > 0){
                String id = cursor_sms.getString(cursor_sms.getColumnIndex("_id"));
                String address = cursor_sms.getString(cursor_sms.getColumnIndex("address"));
                String body = cursor_sms.getString(cursor_sms.getColumnIndex("body"));
                String date = cursor_sms.getString(cursor_sms.getColumnIndex("date"));
                String type = cursor_sms.getString(cursor_sms.getColumnIndex("type"));
                String sms_type = "0".equals(type)?"待发信息":("1".equals(type)?"接收到的信息":"已发送的信息");

                textView_main_sms.append(id + ":" + address + ":" + body + ":" + date + ":" + sms_type);

            }
            cursor_sms.close();
        }

    }

    private void initView() {
        textView_main_sms = (TextView) findViewById(R.id.textView_main_sms);
        textView_main_call = (TextView) findViewById(R.id.textView_main_call);
        resolver = getContentResolver();
    }


}

布局页面如下:

<?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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.oldeleven.day18_contentresolversmslogcalllogfirst.MainActivity">

    <TextView
        android:id="@+id/textView_main_sms"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="最后一条短信:"/>

    <TextView
        android:id="@+id/textView_main_call"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="最后一条通话记录:"
        android:layout_below="@id/textView_main_sms"/>
</RelativeLayout>

最后,需要在清单文件中加上读取Sms,Call_Log的权限

<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>

二、以上代码再
加上动态授权,对于23以上的版本,当访问系统数据库时需要添加动态访问权限,否则程序会报错。
优化如下:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        grandReadSmsLog();

        grandReadCallLog();
    }

    private void grandReadCallLog() {
        int hasReadSmsPermisson = ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS);
        if (hasReadSmsPermisson != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_SMS},READ_SMS_CODE);
        }else {
            readSmsLog();
        }

    }

    private void grandReadSmsLog() {
        int hasReadCallLogPermission = ContextCompat.checkSelfPermission(mContext,Manifest.permission.READ_CALL_LOG);
        if (hasReadCallLogPermission != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CALL_LOG},READ_CALL_CODE);
        }else {
            readCallLog();
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode){
            case READ_SMS_CODE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    readSmsLog();
                }else{
                    Toast.makeText(mContext,"读取短信记录授权失败",Toast.LENGTH_LONG).show();
                }
                break;
            case READ_CALL_CODE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    readCallLog();
                }else {
                    Toast.makeText(mContext,"读取通话记录授权失败",Toast.LENGTH_LONG).show();
                }

                break;
        }
    }

这样在23版本以上的手机上,也可以读取系统通话记录与短信记录了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值