Android monitor mobile phone SMS

There are two methods for Android to monitor mobile phone text messages, namely:

1. Accept the SMS broadcast of the system: when the mobile phone receives a new message, it will send a broadcast, and the SMS content can be obtained through the broadcast;

2. Monitor the SMS database: Use the observer mode to monitor the SMS database. When the SMS database changes, the onChange() method of the observer mode can be triggered, but the onChang callback or the acquisition of SMS is not the latest, and the problem of obtaining duplicate SMS.


The main structure of sms:

  _id: SMS serial number, such as 100

  thread_id: the serial number of the conversation, such as 100, the serial number of the text messages sent to and from the same mobile phone number is the same

  address: sender's address, that is, mobile phone number, such as +86138138000

  person: the sender, if the sender is in the address book, it is the specific name, and it is null for strangers

  date: date, long type, such as 1346988516, you can set the date display format

  protocol: Protocol 0SMS_RPOTO SMS, 1MMS_PROTO MMS

  read: whether to read 0 unread, 1 read

  status: SMS status - 1 received, 0complete, 64pending, 128failed

  type: SMS type 1 is received, 2 is sent

  body: the specific content of the message

  service_center: SMS service center number, such as +8613800755500


The first way to receive the SMS broadcast of the system: A. This method is only valid for newly received short messages. Running the code will not read the read or unread messages in the inbox, only when a new message is received When a short message comes, the onReceive() method will be executed.

B. And this broadcast is an orderly broadcast. If other programs read this broadcast first and then intercept this broadcast, you will not receive it. Of course, we can set the value of priority, but sometimes it doesn’t work. Now, in some customized systems or security software, short messages are often intercepted and killed.

<uses-permission android:name="android.permission.RECEIVE_SMS" /> <!-- 接收短信权限 -->
<uses-permission android:name="android.permission.READ_SMS" /> <!-- 读取短信权限 -->

<receiver android:name="com.example.smslistenerdemo.SmsReceiver" >
            <intent-filter android:priority="2147483647" >
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
 </receiver>
public class SmsReceiver extends BroadcastReceiver {
//    private static MessageListener mMessageListener;

    private Context mContext;
    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    public static final String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";

    @Override
    public void onReceive(Context context, Intent intent) {
        this.mContext = context;
     
        Toast.makeText(context, "接收短信执行了.....", Toast.LENGTH_LONG).show();
        Log.e("日志:广播::onReceive", isOrderedBroadcast() + "");
        Log.e("日志:onReceive...", "-接收短信执行了......"+intent.getStringExtra("sele"));
        String action = intent.getAction();
        if (SMS_RECEIVED_ACTION.equals(action) || SMS_DELIVER_ACTION.equals(action) ) {
           
            Log.e("日志:onReceive。。。", "开始接收短信.....");
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                Object[] pdus = (Object[]) bundle.get("pdus");
                if (pdus != null && pdus.length > 0) {
                    SmsMessage[] messages = new SmsMessage[pdus.length];
                    for (int i = 0; i < pdus.length; i++) {
                        byte[] pdu = (byte[]) pdus[i];
                        messages[i] = SmsMessage.createFromPdu(pdu);
                    }
                    for (SmsMessage message : messages) {
                        String content = message.getMessageBody();// 得到短信内容
                        String sender = message.getOriginatingAddress();// 得到发信息的号码
                        Date date = new Date(message.getTimestampMillis());
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        format.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
                        String dateContent = format.format(date);

                    if ((sender.equals("8610086") || sender.equals(Constant.phone))){
                        Log.e("日志:短信时间::: ", format.format(date) + " ");
                        Log.e("日志:发信息的号码 ", sender + " ");
                        Log.e("日志:得到短信内容 ", content + " ");
                        this.abortBroadcast();// 中止
                    }

                    }
                }

            }
        }
    }
}

Enable Service to realize lock screen monitoring

Listen to text messages in the Activity. When the application is placed in the background or the screen is locked for a period of time, the content of the text message cannot be uploaded to the server. Therefore, a Service needs to be started, and the text message can be monitored in the Service to continue listening to the text message after the screen is locked .

To start the Service, you first need to apply for the android.permission.FOREGROUND_SERVICE permission, which is a normal permission, so just declare it in AndroidManifest.xml

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

After that, you need to add the <service> tag corresponding to the Service class in AndroidManifest.xml, where the meanings of the three attribute values ​​are:

android:name is pakagename+Service class name, pakagename can be omitted;

android:enabled indicates whether it can be instantiated by the system;

android:exported indicates whether components of other applications can wake up the service or interact with the service;

<service
  android:name=".MyService"
  android:enabled="true"
  android:exported="true"\>
public class SmsObserver extends ContentObserver {

    public Context mContext;
    public SmsHandler smsHandler;
    private static int id=0; //这里必须用静态的,防止程序多次意外初始化情况
    String _id;
    public SmsObserver(Context context, SmsHandler handler) {
        super(handler);
        this.mContext = context;
        this.smsHandler = handler;
    }
    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);

        Log.i("日志:SmsObserver", "SmsObserver ------短信有改变------");
//        Cursor mCursor = mResolver.query(Uri.parse("content://sms/inbox"),
//                null, null, null, "date desc");
        Cursor mCursor = mContext.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, "date desc");

        if (mCursor == null) {
            return;
        } else {
            if (mCursor.moveToFirst()){
                SmsInfo _smsInfo = new SmsInfo();
                int _inIndex = mCursor.getColumnIndex("_id");
                if (_inIndex != -1) {
                     _id = mCursor.getString(_inIndex);
                    _smsInfo._id=_id;
                }
                Log.e("日志:SmsObserver ...", "id:::"+id);
                //比较id 解决重复问题
                if (id < Integer.parseInt(_id)) {
                    id = Integer.parseInt(_id);

                    int thread_idIndex = mCursor.getColumnIndex("thread_id");

                    _smsInfo.thread_id = mCursor.getString(thread_idIndex);

                    int bodyIndex = mCursor.getColumnIndex("body");
                    _smsInfo.smsBody = mCursor.getString(bodyIndex);
                    int dateIndex = mCursor.getColumnIndex("date");
                    String date = mCursor.getString(dateIndex);
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    _smsInfo.date = dateFormat.format(new Date(Long.parseLong(date)));
                    int addressIndex = mCursor.getColumnIndex("address");
                    String address=   mCursor.getString(addressIndex);

                    if (address.contains("10086")) {
                        id = Integer.parseInt(_id);
                        Log.e("日志:SmsObserver ...", "10086::"+address);
                        Message msg = smsHandler.obtainMessage();
                        _smsInfo.action = 0;// 0不对短信进行操作;1将短信设置为已读;2将短信删除
                        msg.obj = _smsInfo;
                        smsHandler.sendMessage(msg);

                        //发广播
                        Intent intent = new Intent("com.zl.zl_sms_monitor_DBiErICZ");
                        intent.putExtra("hello", address);         //向广播接收器传递数据
                        mContext.sendBroadcast(intent);
                        return;
                      }
                    Log.e("日志:SmsObserver ...", "获取的短信内容::"+_smsInfo.toString());

                }
            }
           // getHttp();

        }

        if (mCursor != null) {
            mCursor.close();
            mCursor = null;
        }
    }
}
public class SmsService  extends Service {

    private  SmsObserver mObserver = new SmsObserver(this, new SmsHandler(this));
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this,"SmsService服务器启动了。。。",  Toast.LENGTH_LONG).show();
        //所有短信  注册
        getContentResolver().registerContentObserver(Uri.parse("content://sms"),true, mObserver);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.getContentResolver().unregisterContentObserver(mObserver);
        Process.killProcess(Process.myPid());
    }

}

Guess you like

Origin blog.csdn.net/qq_37599041/article/details/129319220