Android短信监听实现,及Android4.4之后短信机制变更
前阵子公司有一个项目,简单的监听短信应用,功能只有如下两个:
1.监听数据库变化方式监听短信内容
_id: 短信序号,如100
thread_id:对话的序号,如100,与同一个手机号互发的短信,其序号是相同的
address: 发件人地址,即手机号,如+86138138000
person: 发件人,如果发件人在通讯录中则为具体姓名,陌生人为null
date: 日期,long型,如1346988516,可以对日期显示格式进行设置
protocol: 协议0SMS_RPOTO短信,1MMS_PROTO彩信
read: 是否阅读0未读,1已读
status: 短信状态-1接收,0complete,64pending,128failed
type: 短信类型1是接收到的,2是已发出
body: 短信具体内容
service_center:短信服务中心号码编号,如+8613800755500
收件箱:content://sms/inbox
private Uri SMS_INBOX = Uri.parse("content://sms/inbox");
public void getSmsFromPhone() {
ContentResolver cr = getContentResolver();
String[] projection = new String[] { "body","address" };//"_id", "address", "person",, "date", "type
String where = " date > "
+ (System.currentTimeMillis() - 10 * 60 * 1000);
Cursor cur = cr.query(SMS_INBOX, projection, where, null, "date desc");
if (null == cur)
return;
if (cur.moveToFirst()) {
String number = cur.getString(cur.getColumnIndex("address"));//手机号
String body = cur.getString(cur.getColumnIndex("body"));
//TODO 这里是具体处理逻辑
}
}
在这里我们只是写了一个方法查询数据库,但是还有一个问题就是我们应该在什么时候去查数据库,总不能起个线程去轮训,这样太耗费资源了,这里我们可以是用观察者模式;
private SmsObserver smsObserver;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_login);
smsObserver = new SmsObserver(this, smsHandler);
getContentResolver().registerContentObserver(SMS_INBOX, true,
smsObserver);
}
public Handler smsHandler = new Handler() {
//这里可以进行回调的操作
//TODO
};
class SmsObserver extends ContentObserver {
public SmsObserver(Context context, Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//每当有新短信到来时,使用我们获取短消息的方法
getSmsFromPhone();
}
}
2.通过广播监听短信内容
public class SmsReceiver extends BroadcastReceiver {
public static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private static final String TAG = "yjj";
public SmsReceiver() {
Log.i("yjj", "new SmsReceiver");
}
@Override
public void onReceive(final Context context, Intent intent) {
Log.i(TAG, "jie shou dao");
Cursor cursor = null;
try {
if (SMS_RECEIVED.equals(intent.getAction())) {
Log.d(TAG, "sms received!");
Bundle bundle = intent.getExtras();
if (bundle != null) {
Object[] pdus = (Object[]) bundle.get("pdus");
final SmsMessage[] messages = new SmsMessage[pdus.length];
for (int i = 0; i < pdus.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
}
if (messages.length > 0) {
String content = messages[0].getMessageBody();
String sender = messages[0].getOriginatingAddress();
long msgDate = messages[0].getTimestampMillis();
String smsToast = "New SMS received from : "
+ sender + "\n'"
+ content + "'";
Toast.makeText(context, smsToast, Toast.LENGTH_LONG)
.show();
Log.d(TAG, "message from: " + sender + ", message body: " + content
+ ", message date: " + msgDate);
//自己的逻辑
}
}
cursor = context.getContentResolver().query(Uri.parse("content://sms"), new String[] { "_id", "address", "read", "body", "date" }, "read = ? ", new String[] { "0" }, "date desc");
if (null == cursor){
return;
}
Log.i(TAG,"m cursor count is "+cursor.getCount());
Log.i(TAG,"m first is "+cursor.moveToFirst());
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Exception : " + e);
} finally {
if (cursor != null) {
cursor.close();
cursor = null;
}
}
}
}
这个很简单就是定义一个广播接收者,并且在清单文件中注册(注册有两种方式,这里就不展开了)
<receiver android:name=".message.SmsReceiver" android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="2147483647">
<action android:name="android.provider.Telephony.SMS_DELIVER" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
3.Android 4.4以上版本短信权限问题

4.Android4.4版本以上设置默认短信应用
<!-- BroadcastReceiver that listens for incoming MMS messages -->
<receiver android:name=".message.MmsReceiver"
android:permission="android.permission.BROADCAST_WAP_PUSH">
<intent-filter>
<action android:name="android.provider.Telephony.WAP_PUSH_DELIVER" />
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
<!-- Activity that allows the user to send new SMS/MMS messages -->
<activity android:name=".message.ComposeSmsActivity" >
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SENDTO" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</activity>
<!-- Service that delivers messages from the phone "quick response" -->
<service android:name=".message.HeadlessSmsSendService"
android:permission="android.permission.SEND_RESPOND_VIA_MESSAGE"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.RESPOND_VIA_MESSAGE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="sms" />
<data android:scheme="smsto" />
<data android:scheme="mms" />
<data android:scheme="mmsto" />
</intent-filter>
</service>
public class MmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
}
}
ComposeSmsActivity.java
public class ComposeSmsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
}
HeadlessSmsSendService.java
public class HeadlessSmsSendService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
通过以上步骤,我们所写的应用就可以被设置为默认短信应用了
最后别忘了添加相应的权限:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
这里贴出的是我整个项目的权限,世纪应该只需要SMS相关的权限,这里就不做区分了
Android短信监听实现,及Android4.4之后短信机制变更的更多相关文章
- wemall app商城源码Android短信监听接收器
wemall doraemon是Android客户端程序,服务端采用wemall微信商城,不对原商城做任何修改,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可随意定制修改.本文分享其中 ...
- Android短信监听软件
本案例是在android手机中运行,是一个没有界面的短信监听软件.主要是用BroadcastReceiver来接受短信广播,当接收到短信后就跳转到service中来转发短信.哈哈,不是用来干坏事的.这 ...
- Android手机上监听短信的两种方式
Android手机上监听短信有两种方式: 1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: ...
- Android短信监听(二)——利用ContentObserver实现短信监听
MainActivity例如以下: package cc.testsmslistener; import cc.testsmslistener.SMSContentObserver.MessageLi ...
- Android实战简易教程-第四十枪(窃听风云之短信监听)
近期在做监听验证码短信自己主动填入的功能,无意间想到了一个短信监听的办法. 免责声明:短信监听本身是一种违法行为,这里仅仅是技术描写叙述.请大家学习技术就可以.(哈哈) 本实例是基于bmob提供的后台 ...
- Android 编程下短信监听在小米手机中失效的解决办法
相信很多人写的短信监听应用在小米手机上是拦截不到短信的,这是因为小米对短信的处置权优先分给了系统.我们可以在短信的[设置]→[高级设置]→[系统短信优先]中发现短信的优先处理权默认是分给系统的,只要关 ...
- Android 手势水平监听判断
package com.zihao.ui; import com.zihao.R; import android.os.Bundle; import android.app.Activity; imp ...
- Android中如何监听GPS开启和关闭
转自 chenming 原文 Android中如何监听GPS开启和关闭 摘要: 本文简单总结了如何监听GPS开关的小技巧 有时需要监听GPS的开关(这种需求并不多见).实现的思路是监听代表 GPS ...
- android的电话监听
android的电话监听 新建一个项目,结构图如下: PhoneService: package com.demo.tingdianhua; import android.app.Service; i ...
- Android零基础入门第34节:Android中基于监听的事件处理
原文:Android零基础入门第34节:Android中基于监听的事件处理 上一期我们学习了Android中的事件处理,也详细学习了Android中基于监听的事件处理,同时学会了匿名内部类形式,那么本 ...
随机推荐
- Django-自定义增删改查组件的一些体会
1.路由系统 namespace,用于区分相同name的url,通过namespace为url添加一个前缀 反向生成URL的时候 reverse('namespace:name') {% url &q ...
- php 允许浏览器跨域访问web服务端的解决方案
今天和同事探讨了前后端如何真正实现隔离开发的问题,如果前端单独作为服务发布,势必会涉及到无法直接调用后端的接口的问题,因为浏览器是不允许跨域提交请求的. 所谓跨域访问,就是在浏览器窗口,和某个服务端通 ...
- 潭州课堂25班:Ph201805201 爬虫基础 第十四课 js破解 (课堂笔记)
打断点 找要的数据 鼠标的点击事件 新浪微博登录 表单提交分析 : 先佃输入错误密码开始调式 f10 往下走, f11 进入函数 sh + f11 跳出函数 # -*- coding: utf-8 - ...
- Tcp端口以及端口相关协议详解
http://www.codeweblog.com/tcp%e5%b8%b8%e7%94%a8%e7%ab%af%e5%8f%a3/
- The type javax.servlet.http.HttpServletRequest cannot be resolved. It is indirectly referenced from required .class files
我的方法:是缺少servlet的引用库,解决如下 1.工程右键-properties->java build path 2.在java build path的libraries tab页中选择A ...
- windows 下重置 mysql 的 root 密码
今天发现 WordPress 连接不上数据库,登录 window server 服务器查看,所有服务均运行正常. 使用 root 账号登录 mysql 数据库,结果提示密码不匹配.我突然意识到,服务器 ...
- 【linux】linux修改open file 大小
使用下面命令可以查看openfile数量 ulimit -a linux修改open file 大小,修改步骤如下: 1>修改file-max 修改文件: vi /etc/sysctl.conf ...
- SSE图像算法优化系列一:一段BGR2Y的SIMD代码解析。
一个同事在github上淘到一个基于SIMD的RGB转Y(彩色转灰度或者转明度)的代码,我抽了点时间看了下,顺便学习了一些SIMD指令,这里把学习过程中的一些理解和认识共享给大家. github上相关 ...
- loopback文件系统
回环设备(loop-back devices) 实验环境 centos7.2 回环设备( 'loopback device')允许用户以一个普通磁盘文件虚拟一个块设备.(磁盘文件 --> 块设备 ...
- java command line error opening registry key 'Software\JavaSoft\Java Runtime Environment' java.dll
C:\Users\huxxxxchan>javaError: opening registry key 'Software\JavaSoft\Java Runtime Environment'E ...