当前位置: 首页 > wzjs >正文

网站克隆镜像做关键字seo一键建站

网站克隆镜像做关键字seo,一键建站,鄂尔多斯教育网站入口,网页设计字体颜色代码一年经验的全栈程序员,目前头发健在,但不知道能撑多久。 该项目已成功部署并稳定运行于企业生产环境,如需个性化定制方案,欢迎联系作者进行深度合作。 文章目录 前言 一、页面设计 1.页面显示 2.代码实现 二、具体代码实现 1.添加…

一年经验的全栈程序员,目前头发健在,但不知道能撑多久。

该项目已成功部署并稳定运行于企业生产环境,如需个性化定制方案,欢迎联系作者进行深度合作。

文章目录

前言

一、页面设计

1.页面显示

 2.代码实现

 二、具体代码实现

1.添加网络权限和短信权限

2.实现短信监听(BroadcastReceiver)

3.AndroidManifest.xml 中注册广播接收器

4. 封装网络请求(HttpURLConnection) 

 三、MainActivity主程序编写

1. 权限管理模块

2. 短信接收与处理模块 

 3. 数据存储与展示模块

4. 用户配置管理模块

5. 定时清理模块(可选) 

 总结

🙌 求点赞、收藏、关注! 


前言

由于公司业务需求需要监控大批手机号的验证码所以有了这个项目,在 Android 应用开发中,短信监控通常用于合规场景,如企业设备管理、金融风控(验证码自动填充)或家长监护。不同于直接读取短信数据库(ContentProvider),使用 BroadcastReceiver 监听短信广播(android.provider.Telephony.SMS_RECEIVED)是一种更轻量、实时性更强的方案。

本文将介绍如何通过 BroadcastReceiver 捕获短信,并使用 原生 HttpURLConnection(而非第三方库)将数据安全上传至服务器,涵盖以下关键点:

  1. 短信监听机制:注册广播接收器,过滤有效短信(如特定发送方或验证码)。

  2. 网络请求实现:手动封装 HttpURLConnection,支持 POST/GET 请求。

  3. 安全与合规性

    • 动态申请 RECEIVE_SMS 权限,确保用户知情同意。

    • 避免存储敏感信息,仅传输必要数据。

注意:未经用户授权的短信监控属于违法行为,本文仅限技术探讨,请确保应用符合 Google Play 政策及《个人信息保护法》。


一、页面设计

由于没有做统一的日志管理但是也需要查看短信是否有监听到使用页面需要显示监听的手机号和内容。

1.页面显示

 2.代码实现

<?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"tools:context=".MainActivity"><!-- 应用名称标题 --><TextViewandroid:id="@+id/appNameTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="16dp"android:text="短信接收器"android:textSize="20sp"android:textStyle="bold"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><!-- 卡1标题 --><Buttonandroid:id="@+id/baoc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="16dp"android:onClick="save"android:text="保存"app:layout_constraintBottom_toBottomOf="@+id/appNameTextView"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@+id/appNameTextView" /><TextViewandroid:id="@+id/card1TitleTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="16dp"android:layout_marginTop="16dp"android:text="卡1:"android:textSize="16sp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="@+id/editTextPhone1"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@+id/appNameTextView" /><!-- 卡1输入框 --><EditTextandroid:id="@+id/editTextPhone1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginEnd="8dp"android:hint="输入卡1号码"android:textSize="16sp"app:layout_constraintLeft_toRightOf="@+id/card1TitleTextView"app:layout_constraintRight_toLeftOf="@+id/switch1"app:layout_constraintTop_toTopOf="@+id/card1TitleTextView" /><!-- 卡1开关 --><Switchandroid:id="@+id/switch1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="16dp"app:layout_constraintBottom_toBottomOf="@+id/editTextPhone1"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@+id/editTextPhone1" /><!-- 卡2标题 --><TextViewandroid:id="@+id/card2TitleTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="16dp"android:layout_marginTop="16dp"android:text="卡2:"android:textSize="16sp"android:textStyle="bold"app:layout_constraintBottom_toBottomOf="@+id/editTextPhone2"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@+id/editTextPhone1" /><!-- 卡2输入框 --><EditTextandroid:id="@+id/editTextPhone2"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginEnd="8dp"android:hint="输入卡2号码"android:textSize="16sp"app:layout_constraintLeft_toRightOf="@+id/card2TitleTextView"app:layout_constraintRight_toLeftOf="@+id/switch2"app:layout_constraintTop_toTopOf="@+id/card2TitleTextView" /><!-- 卡2开关 --><Switchandroid:id="@+id/switch2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="16dp"app:layout_constraintBottom_toBottomOf="@+id/editTextPhone2"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="@+id/editTextPhone2" /><!-- 短信内容显示框 --><TextViewandroid:id="@+id/smsTextView"android:layout_width="0dp"android:layout_height="300dp"android:layout_marginTop="8dp"android:background="#000000"android:padding="8dp"android:text="监控短信中"android:textColor="#FFFFFF"android:scrollbars="vertical"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toBottomOf="@+id/editTextPhone2" /></androidx.constraintlayout.widget.ConstraintLayout>

为什么这里需要设置卡号显示起除是因为安卓开发系统的匹配度问题有些手机系统是不能自动识别手机号的所以显示这个卡号是看看有没有自动识别,如果没有需要手动输入并且保存,以为后面是根据具体卡槽id识别是哪个手机号接收到的验证码。


 二、具体代码实现

1.添加网络权限和短信权限

在AndroidManifest.xml

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

2.实现短信监听(BroadcastReceiver)

新建一个SMSReceiver.class服务监听短信

public class SMSReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 1. 从广播意图中提取短信数据Bundle bundle = intent.getExtras();if (bundle != null) {// 2. 获取短信PDU数组和SIM卡订阅IDObject[] pdus = (Object[]) bundle.get("pdus");int subscriptionId = bundle.getInt("subscription", -1);if (pdus != null) {for (Object pdu : pdus) {// 3. 解析短信内容(发送方、正文)SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);String messageBody = smsMessage.getMessageBody();String sender = smsMessage.getDisplayOriginatingAddress();// 4. 获取SIM卡槽位信息(双卡场景)String slotInfo = getSlotInfo(context, subscriptionId);// 5. 发送自定义广播传递短信数据Intent smsIntent = new Intent("smsReceived");smsIntent.putExtra("message", messageBody);smsIntent.putExtra("sender", sender);smsIntent.putExtra("slotInfo", slotInfo);context.sendBroadcast(smsIntent);}}}}/*** 获取SIM卡槽位信息(兼容双卡)* @param subscriptionId SIM卡订阅ID* @return 如 "Slot 1" 或 "Unknown Slot"*/private String getSlotInfo(Context context, int subscriptionId) {// 实现逻辑:通过SubscriptionManager查询对应SIM卡槽// ...}/*** 获取接收方手机号(需权限)* @note 因权限问题已注释,实际使用需动态申请READ_PHONE_STATE权限*/@RequiresApi(api = Build.VERSION_CODES.N)private String getReceiverPhoneNumber(Context context, int subscriptionId) {// 实现逻辑:通过TelephonyManager获取本机号码// ...}
}

3.AndroidManifest.xml 中注册广播接收器

 <receiver android:name=".SMSReceiver"android:exported="true"android:enabled="true"><intent-filter><action android:name="android.provider.Telephony.SMS_RECEIVED"/></intent-filter></receiver>

4. 封装网络请求(HttpURLConnection) 

public class MyRequest {public String post(String url1, String data) {try {URL url = new URL(url1);HttpURLConnection Connection = (HttpURLConnection) url.openConnection();//创建连接Connection.setRequestMethod("POST");Connection.setConnectTimeout(3000);Connection.setReadTimeout(3000);Connection.setDoInput(true);Connection.setDoOutput(true);Connection.setUseCaches(false);Connection.connect();DataOutputStream dos = new DataOutputStream(Connection.getOutputStream());String title = data;//这里是POST请求需要的参数字符串类型,例如"id=1&data=2"dos.write(title.getBytes());dos.flush();dos.close();//写完记得关闭int responseCode = Connection.getResponseCode();if (responseCode == Connection.HTTP_OK) {//判断请求是否成功InputStream inputStream = Connection.getInputStream();ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();byte[] bytes = new byte[1024];int length = 0;while ((length = inputStream.read(bytes)) != -1) {arrayOutputStream.write(bytes, 0, length);arrayOutputStream.flush();}//读取响应体的内容String s = arrayOutputStream.toString();return s;//返回请求到的内容,字符串形式} else {return "-1";//如果请求失败返回-1}} catch (Exception e) {return "-1";//出现异常也返回-1}}public String get(String url1) {try {URL url = new URL(url1);HttpURLConnection Connection = (HttpURLConnection) url.openConnection();Connection.setRequestMethod("GET");Connection.setConnectTimeout(3000);Connection.setReadTimeout(3000);int responseCode = Connection.getResponseCode();if (responseCode == Connection.HTTP_OK) {InputStream inputStream = Connection.getInputStream();ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();byte[] bytes = new byte[1024];int length = 0;while ((length = inputStream.read(bytes)) != -1) {arrayOutputStream.write(bytes, 0, length);arrayOutputStream.flush();//强制释放缓冲区}String s = arrayOutputStream.toString();return s;} else {return "-1";}} catch (Exception e) {return "-1"+e;}}}


 三、MainActivity主程序编写

1. 权限管理模块

// 定义所需权限
private static final int PERMISSION_REQUEST_CODE = 1;
String[] permissions = {Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_SMS,Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_PHONE_NUMBERS
};// 检查并请求权限
if (未全部授权) {ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
} else {registerSmsReceiver(); // 注册广播接收器
}// 权限请求结果回调
@Override
public void onRequestPermissionsResult(...) {if (权限通过) {registerSmsReceiver();} else {showToast("短信监控功能不可用");}
}

2. 短信接收与处理模块 

// 自定义广播接收器
private BroadcastReceiver smsReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {// 解析短信数据String message = intent.getStringExtra("message");String sender = intent.getStringExtra("sender");String slotInfo = intent.getStringExtra("slotInfo");// 根据SIM卡槽匹配接收号码String receiverNumber = slotInfo.contains("1") ? editTextPhone1.getText().toString() : editTextPhone2.getText().toString();// 过滤重复消息if (pdMessages(message)) {// 启动网络请求线程new Thread(() -> {String url = "服务器接口;String response = new MyRequest().get(url);handleResponse(response, receiverNumber, sender, message);}).start();}}
};// 消息去重检查
private boolean pdMessages(String mess) {Set<String> savedMessages = sp.getStringSet("messages", new HashSet<>());if (savedMessages.contains(mess)) {return false; // 重复消息}savedMessages.add(mess);sp.edit().putStringSet("messages", savedMessages).apply();return true;
}

 3. 数据存储与展示模块

// 存储消息记录(包含状态和时间戳)
private void storeMessageStatus(String receiver, String sender, String message, String status) {String key = "message_" + System.currentTimeMillis();String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());String record = String.format("接收号: %s\n发送方: %s\n时间: %s\n内容: %s\n状态: %s\n",receiver, sender, time, message, status);sp.edit().putString(key + "_data", record).putLong(key + "_time", System.currentTimeMillis()).apply();
}// 显示历史消息
private void displayStoredMessages() {StringBuilder sb = new StringBuilder();for (Map.Entry<String, ?> entry : sp.getAll().entrySet()) {if (entry.getKey().endsWith("_data")) {sb.append(entry.getValue()).append("\n");}}smsTextView.setText(sb.length() > 0 ? sb.toString() : "无记录");
}

4. 用户配置管理模块

// 保存用户设置的手机号
public void save(View view) {sp.edit().putString("editTextPhone1", editTextPhone1.getText().toString()).putString("editTextPhone2", editTextPhone2.getText().toString()).apply();showToast("保存成功");
}// 初始化时加载配置
private void loadConfig() {editTextPhone1.setText(sp.getString("editTextPhone1", ""));editTextPhone2.setText(sp.getString("editTextPhone2", ""));
}

5. 定时清理模块(可选) 

// 设置每天中午12点清理旧数据
private void setDailyCleanupAlarm() {AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);Intent intent = new Intent(this, CleanupReceiver.class);PendingIntent pendingIntent = PendingIntent.getBroadcast(...);Calendar calendar = Calendar.getInstance();calendar.set(Calendar.HOUR_OF_DAY, 12); // 12:00 PMif (已过当前时间) calendar.add(Calendar.DAY_OF_YEAR, 1);alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}

 总结

  1. 实现了双卡短信监控:通过BroadcastReceiver捕获短信,并根据SIM卡槽自动匹配预设的手机号,支持双卡场景下的短信分类处理。

  2. 数据安全与合规性:动态申请权限确保用户知情权,使用SharedPreferences存储消息记录,避免敏感信息泄露,符合隐私保护要求。

  3. 网络上传与状态反馈:通过HttpURLConnection将短信内容上传至服务器,并实时显示发送状态(成功/失败),数据持久化便于追溯。

  4. 可扩展性强:模块化设计(权限管理、消息处理、数据存储)便于后续扩展,如增加加密传输或对接其他API。

🙌 求点赞、收藏、关注! 

如果这篇文章对你有帮助,不妨:
👍 点个赞 → 让更多人看到这篇干货!
⭐ 收藏一下 → 方便以后随时查阅!
🔔 加关注 → 获取更多 前端/后端/全栈技术深度解析

你的支持,是我持续创作的最大动力! 🚀

http://www.dtcms.com/wzjs/155411.html

相关文章:

  • 做wish选品参考什么网站seo关键词排名优化哪家好
  • 网站more应该怎么做个人网站免费域名和服务器
  • 做任务的正规网站做网站公司哪家正规
  • 公司做宣传网站发票可以抵扣不宁波网站推广平台效果好
  • 网站收录很少却有排名湛江百度seo公司
  • 制作网站的程序语言长沙正规seo优化公司
  • 做网站运营的要求网页优化
  • 网站开发需求方案做seo如何赚钱
  • 网站设计的素材如何开通网站
  • 家电网站建设总体目标网页设计与制作期末作品
  • 网站建设思维导图模板优秀的软文广告案例
  • 网上哪个网站做的系统好用吗抖音引流推广免费软件app
  • 设计新闻发布网站模板上海推广网络营销咨询热线
  • 珠海企业集团网站建设长沙网站制作公司哪家好
  • 如何给网站做快速排名南京网络营销服务
  • 商城首页设计百度seo优化包含哪几项
  • 长宁手机网站建设企业营销网站制作
  • aardio 网站开发网络营销的策略
  • wejianzhan是什么网站百度文库官网入口
  • 档案网站建设思考百度打广告收费表
  • 西安网站建设报价媒体发稿网
  • 花生壳做网站需要备案火蝠电商代运营公司
  • 做网站流程、自媒体平台排名前十
  • 包头网站建设推广国家再就业免费培训网
  • 自助建站系统源源码网络营销培训
  • 西安招聘网站建设今晚赛事比分预测
  • 网站建设公司江苏什么软件可以发布广告信息
  • 网站建设如何收费企查查在线查询
  • 网站建设 人性的弱点抖音信息流广告怎么投放
  • 做团购网站视频今日小说搜索风云榜