前言

Android 监听短信的方式有两种

1、监听短信数据库,数据库发生改变时回调。

2、监听短信广播

其中第二种方式由于国内各厂家的定制Android 可能导致无响应 目前测试 魅族 无法监听到短信广播

本文介绍第一种方式监听短信

一、创建Service前台服务

package com.iwhalecloud.demo.SMS;import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import androidx.annotation.RequiresApi;
import com.iwhalecloud.demo.MainActivity;
import com.iwhalecloud.demo.R;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;public class MyService extends Service {private static final String TAG = MyService.class.getSimpleName();private SMSContentObserver smsObserver;public String phoneNo = "";public String httpUrl = "";@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}public class MyBinder extends Binder {/*** 获取当前Service的实例* @return*/public MyService getService(){return MyService.this;}}@RequiresApi(api = Build.VERSION_CODES.O)@Overridepublic void onCreate() {super.onCreate();//注册观察者smsObserver = new SMSContentObserver(MyService.this,new Handler());getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, smsObserver);}@RequiresApi(api = Build.VERSION_CODES.O)@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {phoneNo=intent.getStringExtra("phoneNum");httpUrl=intent.getStringExtra("httpUrl");startForeground(100,getNotification("服务运行中...","正在监听号码:"+phoneNo+",保持应用后台运行..."));return START_STICKY;}@Overridepublic void onDestroy() {super.onDestroy();getContentResolver().unregisterContentObserver(smsObserver);}@RequiresApi(api = Build.VERSION_CODES.O)private Notification getNotification(String title, String message){NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// 唯一的通知通道的id.String notificationChannelId = "notification_channel_id_01";// Android8.0以上的系统,新建消息通道if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//用户可见的通道名称String channelName = "Foreground Service Notification";//通道的重要程度int importance = NotificationManager.IMPORTANCE_HIGH;NotificationChannel notificationChannel = new NotificationChannel(notificationChannelId, channelName, importance);notificationChannel.setDescription("Channel description");//LED灯notificationChannel.enableLights(false);//震动notificationChannel.enableVibration(false);if (notificationManager != null) {notificationManager.createNotificationChannel(notificationChannel);}}NotificationCompat.Builder builder = new NotificationCompat.Builder(this, notificationChannelId);//通知小图标builder.setSmallIcon(R.mipmap.ic_launcher);//通知标题builder.setContentTitle(title);//通知内容builder.setContentText(message);//设定通知显示的时间builder.setWhen(System.currentTimeMillis());//设定启动的内容Intent clickIntent = new Intent(Intent.ACTION_MAIN);//点击回到活动主页 而不是创建新主页clickIntent.addCategory(Intent.CATEGORY_LAUNCHER);clickIntent.setComponent(new ComponentName(this,MainActivity.class));clickIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);builder.setContentIntent(pendingIntent);//创建通知并返回return builder.build();}@SuppressLint("Range")private  void setSmsCode() {Toast.makeText(MyService.this,phoneNo+":"+httpUrl,Toast.LENGTH_SHORT).show();Cursor cursor = null;// 添加异常捕捉try {cursor = getContentResolver().query(Uri.parse("content://sms"),new String[] { "_id", "address", "body", "date" },null, null, "date desc"); //if (cursor != null) {cursor.moveToFirst();final long smsdate = Long.parseLong(cursor.getString(cursor.getColumnIndex("date")));final long nowdate = System.currentTimeMillis();Toast.makeText(MyService.this,nowdate+":"+smsdate+"===="+ (nowdate - smsdate),Toast.LENGTH_SHORT).show();
//                 如果当前时间和短信时间间隔超过60秒,认为这条短信无效final String strAddress = cursor.getString(cursor.getColumnIndex("address"));    // 短信号码final String strBody = cursor.getString(cursor.getColumnIndex("body"));          // 在这里获取短信信息Toast.makeText(MyService.this,"strAddress:"+strAddress,Toast.LENGTH_SHORT).show();Toast.makeText(MyService.this,"strBody:"+strBody,Toast.LENGTH_SHORT).show();if (nowdate - smsdate > 60 * 1000) {Log.i(TAG, "短信过期");Toast.makeText(MyService.this,"短信过期",Toast.LENGTH_SHORT).show();return;}final int smsid = cursor.getInt(cursor.getColumnIndex("_id"));if (TextUtils.isEmpty(strAddress) || TextUtils.isEmpty(strBody)) {return;}Log.i(TAG, "phoneNo: "+phoneNo);Log.i(TAG, "httpUrl: "+httpUrl);if (strAddress.equals(phoneNo)){Log.i(TAG, "是我想要的号码");Toast.makeText(MyService.this,strAddress+":"+strBody,Toast.LENGTH_SHORT).show();Pattern continuousNumberPattern = Pattern.compile("(?<![0-9])([0-9]{6})(?![0-9])");Matcher m = continuousNumberPattern.matcher(strBody);String dynamicPassword = "";while (m.find()) {dynamicPassword = m.group();}//连接http服务String finalDynamicPassword = dynamicPassword;new Thread(new Runnable() {@Overridepublic void run() {OkHttpClient mOkHttpClient = new OkHttpClient();try {RequestBody requestBody = new FormBody.Builder().add("code", finalDynamicPassword).build();Request request = new Request.Builder().url(httpUrl).post(requestBody).build();Response response = mOkHttpClient.newCall(request).execute();//发送请求String result = response.body().string();Log.d(TAG, "result: " + result);} catch (IOException e) {e.printStackTrace();}}}).start();Log.i(TAG, "onReceiveSms: "+ dynamicPassword);}}else {Toast.makeText(MyService.this,"cursor 为 NULL",Toast.LENGTH_SHORT).show();}}catch (Exception e) {Toast.makeText(MyService.this,"出错了::::"+e.getMessage(),Toast.LENGTH_SHORT).show();e.printStackTrace();}finally {Toast.makeText(MyService.this, String.valueOf(cursor != null),Toast.LENGTH_SHORT).show();if (cursor != null) {cursor.close();}}}public class SMSContentObserver extends ContentObserver {private static final int MSG = 1;private int flag = 0;private Context mContext;private Handler mHandler;public SMSContentObserver(Context mContext,Handler mHandler) {super(mHandler);this.mContext = mContext;this.mHandler = mHandler;}@Overridepublic void onChange(boolean selfChange) {// TODO Auto-generated method stubsuper.onChange(selfChange);//onchange调用两次  过滤掉一次if (flag%2 == 1){setSmsCode();}flag++;}}}

二、主界面(参考)

package com.iwhalecloud.demo;import android.Manifest;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;import androidx.appcompat.app.AppCompatActivity;
import com.iwhalecloud.demo.SMS.MyService;public class MainActivity extends AppCompatActivity {private static final String TAG = "CC";final private int REQUEST_CODE_ASK_PERMISSIONS = 1;private boolean serviceFlag = false;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);SharedPreferences read = getSharedPreferences("info", MODE_PRIVATE);String phoneNum = "10659874";String httpUrl= "";if (read.getString("phoneNum",null)!=null){phoneNum = read.getString("phoneNum",null);}if (read.getString("httpUrl",null)!=null){httpUrl = read.getString("httpUrl",null);}TextView v1 = findViewById(R.id.editText1);TextView v2 = findViewById(R.id.editText2);v1.setText(phoneNum);v2.setText(httpUrl);ToggleButton tb = findViewById(R.id.button);tb.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {TextView pn = findViewById(R.id.editText1);TextView httpUrl = findViewById(R.id.editText2);if (tb.isChecked()){Intent service = new Intent(getApplicationContext(), MyService.class);SharedPreferences.Editor editor = getSharedPreferences("info",MODE_PRIVATE).edit();editor.putString("phoneNum",pn.getText().toString());editor.putString("httpUrl",httpUrl.getText().toString());editor.apply();service.putExtra("phoneNum",pn.getText().toString());service.putExtra("httpUrl",httpUrl.getText().toString());if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {MainActivity.this.startService(service);}pn.setEnabled(false);httpUrl.setEnabled(false);Toast.makeText(MainActivity.this,"服务开启",Toast.LENGTH_SHORT).show();}else {Intent service = new Intent(getApplicationContext(), MyService.class);MainActivity.this.stopService(service);pn.setEnabled(true);httpUrl.setEnabled(true);Toast.makeText(MainActivity.this,"服务停止",Toast.LENGTH_SHORT).show();}}});if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {int hasReadSmsPermission = checkSelfPermission(Manifest.permission.READ_SMS);if (hasReadSmsPermission != PackageManager.PERMISSION_GRANTED) {requestPermissions(new String[]{Manifest.permission.READ_SMS}, REQUEST_CODE_ASK_PERMISSIONS);return;}}}@Overrideprotected void onResume() {super.onResume();}@Overrideprotected void onDestroy() {super.onDestroy();Intent service = new Intent(getApplicationContext(), MyService.class);this.stopService(service);}
}

三、Main.XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"><EditTextandroid:id="@+id/editText1"android:layout_width="295dp"android:layout_height="58dp"android:hint="监听电话号码"android:textColorHint="#95A1AA"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.465"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.469" /><EditTextandroid:id="@+id/editText2"android:layout_width="295dp"android:layout_height="58dp"android:text="http://10.0.2.2:8888/api/test/t1"android:hint="验证码请求接口"android:textColorHint="#95A1AA"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.45"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:layout_constraintVertical_bias="0.595" /><ToggleButtonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textOn="停止服务"android:textOff="启动服务"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/editText1"app:layout_constraintVertical_bias="0.495" /></androidx.constraintlayout.widget.ConstraintLayout>

四、清单文件

    <uses-permission android:name="android.permission.RECEIVE_SMS" /><uses-permission android:name="android.permission.READ_SMS" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.INTERNET" /><application ........><serviceandroid:name=".SMS.MyService"android:enabled="true"android:exported="false" /></application>

Android 监听短信数据库过滤获取短信内容上传至服务器相关推荐

  1. Android监听SMS发送状态并获取短信服务中心号码

    监听SMS发送状态的例子网上虽然有,但还是太杂了不完全.自己写了个. 短信服务中心号码的获取是通过SmsMessage.getServiceCenterAddress()方法获得.也就是只能从已经存储 ...

  2. phpcms发布新闻到数据库_Phpcms V9网站从本地上传到服务器需要修改的地方小结

    Phpcms V9网站从本地上传到服务器需要修改的地方小结 发布时间:2013-06-22 13:37:28   作者:佚名   我要评论 网站在本地做好后要迁移到服务器上:网站在发展的过程中,很可能 ...

  3. Android 监听系统来电获取来电信息

    本文主要介绍了Android监听系统来电,并获取来电信息,在开发app中需要在来电时候,获取来电人的信息并显示出来 首选要注册权限监听来电,然后通过监听到的手机号,来通过接口查询相关的联系人信息 注册 ...

  4. android 监听短信并获取验证码

    最近想给 app 添加自动获取短信验证码的功能,让注册流程更加友好,在网上搜索了一些资料,主要的实现方法有两种. 第一:实现广播 BroadCastReceiver 来监听收件箱,在需要监听的地方注册 ...

  5. Android监听手机短信

    Android监听手机短信的方法有两种,分别为: 1.接受系统的短信广播:当手机收到新消息时,会发送一条广播,通过该广播就可以获取短信内容: 2.监听短信数据库:利用观察者模式监听短信数据库,当短信数 ...

  6. Android监听消息(二)——电话及短信监听

    学更好的别人, 做更好的自己. --<微卡智享> 本文长度为2747字,预计阅读6分钟 前言 前面一篇<Android监听消息(一)--应用消息捕获>我们使用Notificat ...

  7. android 监听短信并发送到服务器

    1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. 2. 应用观察者模式,监听短信数据库,操作短信内容.   实例如下: SystemE ...

  8. 监听mysql表内容变化 使用canal,canal 监听同步指定数据库,所有表

    canal 监听同步指定数据库,所有表 canal 监听同步指定数据库,所有表 因为工作需求,需要用到数据库同步,又从网上找了一些发现都有些问题,所以自己弄好之后写一篇总结,及配置步骤吧 先将 MyS ...

  9. android 监听手机电量变化

    今天,简单讲讲如何监听手机电量的变化. 监听电量是不能静态注册的. 后来上网搜索,发现有五个不能静态注册的广播,这里记录一下,免得下次再后知后觉的发现并惊讶于自己的笨拙. 不能静态注册的广播: and ...

最新文章

  1. 博客作业05--查找
  2. 深度学习模型大合集:GitHub趋势榜第一,两天斩获2000星
  3. Hibernate配置属性详解
  4. 2.12 矩阵及乘法重要总结
  5. linux外部命令帮助,Linux的命令帮助
  6. (2)MongoDB副本集自动故障转移原理(含客户端)
  7. 怎样更换UC浏览器的字体?更换UC浏览器的字体的方法
  8. MySQL常见面试题与答案
  9. Spring Boot学习总结(21)——SpringBoot集成Redis等缓存以注解的方式优雅实现幂等,防千万次重复提交实例代码
  10. VS2013、VS2015中,新建项目没有看到解决方案的问题(已解决)
  11. 【MFC开发(15)】进度条控件Progress Control
  12. 使用R语言中的spgwr包进行GWR模型的相关运算
  13. 家庭服务器搭建,NAS存储
  14. 语音论文阅读TINY TRANSDUCER: A HIGHLY-EFFICIENT SPEECH RECOGNITION MODEL ON EDGE DEVICES
  15. 解读Vue项目文件目录结构,实例化Vue对象,数据和方法
  16. JVM之常用的字节码指令(基于《深入理解Java虚拟机》之第六章类文件结构)(下)
  17. Java表的设计合同_java毕业设计_springboot框架的基于合同管理系统
  18. 登录TOM163VIP邮箱的几种方式,以及常见问题有哪些?
  19. excel怎么一次性删除所有的批注
  20. 【RESTful】REST 与 RESTful 理解与实践

热门文章

  1. 50句哲理 语录(二)
  2. 找个免费的天气预报API真难a
  3. NGS数据分析实践:06. 数据预处理 - 序列比对+PCR重复标记+Indel区域重比对+碱基质量重校正
  4. 数据防泄密·工控安全保障方案
  5. 用 python 写了一个日记本
  6. c 与易语言程序间通信,易语言与三菱PLC通信-FX系列
  7. win10 蓝牙忽然消失,设备管理器有未知USB设备描述符请求失败
  8. 通过命令行使用bandizip压缩与解压
  9. 【C语言初阶】——简易版·扫雷(9*9)【运行逻辑思维导图+细节讲解+源码】【初级】
  10. matlab自带的mri数据集,探查三维 MRI 数据集的切片