如何在 Android 中以编程方式读取设备短信?

androidmobile developmentapps/applications更新于 2026/1/31 9:37:17

简介

在 Android 应用中,我们经常会看到应用从用户移动设备读取短信并在应用中显示。例如,当我们创建一个短信应用时,我们会在应用中显示来自用户移动设备的短信。在本文中,我们将介绍如何在 Android 中以编程方式读取设备短信。

实现

我们将创建一个简单的应用,其中我们将创建一个文本视图,用于显示应用的标题。之后,我们将创建另外三个文本视图,用于显示发件人姓名、消息正文以及消息接收日期。在我们的应用中,我们将显示收件箱中收到的最新消息。现在,让我们转到 Android Studio 创建一个新项目。

步骤 1:在 Android Studio 中创建新项目

如下图所示,导航到 Android Studio。在下方屏幕中,点击"新建项目"以创建一个新的 Android Studio 项目。

点击"新建项目"后,您将看到以下屏幕。

在此屏幕中,我们只需选择"空活动",然后点击"下一步"。点击"下一步"后,您将看到以下屏幕。

在此屏幕中,我们只需指定项目名称。然后包名称将自动生成。

注意:请确保选择 Java 作为语言。

指定所有详细信息后,点击"完成"以创建一个新的 Android Studio 项目。

项目创建完成后,我们将看到两个打开的文件,即 activity_main.xml 和 MainActivity.java 文件。

步骤 2:使用 activity_main.xml

导航到 activity_main.xml。如果此文件不可见,请打开此文件。在左侧窗格中,导航至 app>res>layout>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">

   <!-- text view to displaying heading of application -->
   <TextView
       android:id="@+id/idTVHeading"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_marginTop="100dp"
       android:text="Read SMS in Android"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="20sp"
       android:textStyle="bold" />

   <!-- on below line creating a text view for displaying the sms header -->
   <TextView
       android:id="@+id/idTVNumber"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVHeading"
       android:layout_centerHorizontal="true"
       android:layout_margin="10dp"
       android:padding="4dp"
       android:text="NUmber"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="18sp" />

   <!-- on below line creating a text view for displaying the sms body -->
   <TextView
       android:id="@+id/idTVSMSBody"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVNumber"
       android:layout_centerHorizontal="true"
       android:layout_margin="10dp"
       android:padding="4dp"
       android:text="SMS Body"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="18sp" />

   <!-- on below line creating a text view for displaying the date on which sms have recieved. -->
   <TextView
       android:id="@+id/idTVSMSDate"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_below="@id/idTVSMSBody"
       android:layout_centerHorizontal="true"
       android:layout_margin="10dp"
       android:padding="4dp"
       android:text="SMS Date"
       android:textAlignment="center"
       android:textColor="@color/black"
       android:textSize="18sp" />
</RelativeLayout>

说明:在上面的代码中,我们创建了一个相对布局的根布局。在这个布局中,我们创建了一个文本视图,用于显示应用程序的标题。之后,我们创建了另外三个文本视图:第一个文本视图显示发件人的姓名,第二个文本视图显示发件人的短信正文,第三个文本视图显示收到短信的日期。

步骤 3:在 AndroidManifest.xml 文件中添加权限

导航到 app>AndroidManifest.xml 文件,并在 manifest 标签中添加以下权限以读取短信。

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

步骤 4:使用 MainActivity.java 文件

导航到 MainActivity.java。如果此文件不可见,请打开此文件。在左侧窗格中,导航至 app>res>layout>MainActivity.java 以打开此文件。打开此文件后,将以下代码添加到其中。代码中添加了注释,以便您详细了解。

package com.example.java_test_application;

import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.IntentSender;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Telephony;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.auth.api.credentials.Credential;
import com.google.android.gms.auth.api.credentials.CredentialPickerConfig;
import com.google.android.gms.auth.api.credentials.CredentialRequest;
import com.google.android.gms.auth.api.credentials.CredentialRequestResult;
import com.google.android.gms.auth.api.credentials.Credentials;
import com.google.android.gms.auth.api.credentials.CredentialsClient;
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
import com.google.android.gms.auth.api.credentials.HintRequest;
import com.google.android.gms.auth.api.credentials.IdentityProviders;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

import org.w3c.dom.Text;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
   // 在下面一行创建文本视图变量,用于显示发件人姓名、消息正文和收到消息的日期。
   private TextView numberTV, bodyTV, dateTV;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 初始化下一行文本视图的变量。
        numberTV = findViewById(R.id.idTVNumber);
        bodyTV = findViewById(R.id.idTVSMSBody);
        dateTV = findViewById(R.id.idTVSMSDate);
        // 为下一行内容解析器创建一个变量。
        ContentResolver cr = getApplicationContext().getContentResolver();
        // 为下一行光标创建一个变量,并将 uri 设置为短信 uri。
        Cursor c = cr.query(Telephony.Sms.CONTENT_URI, null, null, null, null);
        // 检查下一行光标是否为空。
        if (c != null) {
           // 在下一行移动到第一个位置。
           if (c.moveToFirst()) {
                // 下面一行从光标中提取短信数据。
                String smsDate = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.DATE));
                // 下面一行从光标中提取发件人姓名/号码。
                String number = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.ADDRESS));
                // 下面一行从光标中提取短信正文。
                String body = c.getString(c.getColumnIndexOrThrow(Telephony.Sms.BODY));
                // 下面一行将日期转换为日期格式。
                Date dateFormat = new Date(Long.valueOf(smsDate));
                // 下面一行将光标移动到下一个位置。
                c.moveToNext();
                // 下面一行将字符串中的数据设置到我们的文本视图中。
               numberTV.setText("Sender is : " + number);
               bodyTV.setText("Body is : 
" + body); dateTV.setText(dateFormat.toString()); } // 在下一行关闭光标。 c.close(); } else { // 如果设备中没有短信,则在下面一行显示 toast 消息。 Toast.makeText(this, "No message to show!", Toast.LENGTH_SHORT).show(); } } }

说明:在上面的代码中,我们首先为文本视图创建变量。现在我们来看一下 onCreate 方法。这是每个 Android 应用程序的默认方法。此方法在应用程序视图创建时调用。在此方法中,我们设置内容视图,即名为 activity_main.xml 的布局文件,并从该文件设置 UI。在 onCreate 方法中,我们使用在 activity_main.xml 文件中指定的 ID 初始化按钮变量。之后,我们为内容解析器创建一个变量。然后,我们通过将短信查询和其他参数设置为 null 来创建并初始化游标变量。之后,我们检查游标是否为 null。如果为 null,我们将游标移动到第一个位置。在此方法中,我们提取短信的不同部分,例如发件人姓名、消息正文和接收短信的日期。获取所有数据后,我们将这些数据设置为我们创建的文本视图。之后,我们关闭游标。如果光标为空,即表示收件箱为空,则我们会将 Toast 消息显示为无消息。

添加上述代码后,现在只需点击顶部栏中的绿色图标即可在移动设备上运行我们的应用程序。

注意 - 确保您已连接到真实设备或模拟器。

输出

结论

在上文中,我们介绍了如何在 Android 中以编程方式从设备读取短信。


相关文章