Android真机监听手机短信

  • Post author:
  • Post category:其他


最近做的项目里要监听手机的短消息内容,这个东西好像在最初学的时候都做过,不过现在早忘记了,现在写下来,记住了。

前提–权限:

  1. <uses-permission android:name=

    “android.permission.RECEIVE_SMS”

    >
  2. </uses-permission>
  3. <uses-permission android:name=

    “android.permission.READ_SMS”

    >
  4. </uses-permission>


方式一:通过广播监听短信消息


(注意:这种方式只对新收到的短消息有效,运行代码,并不会读取收件箱中已读或未读的消息,只有当收到新来的短消息时,才会执行onChange方法)

注册一个广播:

  1. <receiver android:name=

    “com.dbjtech.acbxt.waiqin.SmsReciver”

    >
  2. <intent-filter android:priority=

    “999”

    >
  3. <action android:name=

    “android.provider.Telephony.SMS_RECEIVED”

    />
  4. </intent-filter>
  5. </receiver>

SmsReceiver.java


  1. public


    class

    SmsReciver

    extends

    BroadcastReceiver {

  2. @Override

  3. public


    void

    onReceive(Context context, Intent intent) {
  4. Bundle bundle = intent.getExtras();
  5. SmsMessage msg =

    null

    ;

  6. if

    (

    null

    != bundle) {
  7. Object[] smsObj = (Object[]) bundle.get(

    “pdus”

    );

  8. for

    (Object object : smsObj) {
  9. msg = SmsMessage.createFromPdu((

    byte

    []) object);
  10. Date date =

    new

    Date(msg.getTimestampMillis());

    //时间
  11. SimpleDateFormat format =

    new

    SimpleDateFormat(

    “yyyy-MM-dd HH:mm:ss”

    );
  12. String receiveTime = format.format(date);
  13. System.out.println(

    “number:”

    + msg.getOriginatingAddress()
  14. +

    ”   body:”

    + msg.getDisplayMessageBody() +

    ”  time:”
  15. + msg.getTimestampMillis());

  16. //在这里写自己的逻辑

  17. if

    (msg.getOriginatingAddress().equals(

    “10086”

    )) {

  18. //TODO
  19. }
  20. }
  21. }
  22. }
  23. }



系统的这个广播是有序广播,就是当别的程序先获取到了这个广播再传递给你,当然它也可以干掉这个广播,让你接收不到,这样你的程序肯定是接收不到这个广播的了。我们发现,通过设置priority的数值,其实有时是不管用的,现在在一些定制的系统或是有安全软件的情况下,往往短消息都被截取到,并被干掉。



那么,我们只能使用方法二,监听短信数据库的变化,这种方式比方法一稍微复杂一些,不过使用起来也很方便,不受其它程序干扰~


方式二:通过短信数据库获取短信内容

(注意:这种方式可以获取手机上所有的短信,包括已读未读的短信,是不是很赞)


  1. private

    Uri SMS_INBOX = Uri.parse(

    “content://sms/”

    );

  2. public


    void

    getSmsFromPhone() {
  3. ContentResolver cr = getContentResolver();
  4. String[] projection =

    new

    String[] {

    “body”

    };

    //”_id”, “address”, “person”,, “date”, “type
  5. String where =

    ” address = ‘1066321332’ AND date >  ”
  6. + (System.currentTimeMillis() –

    10

    *

    60

    *

    1000

    );
  7. Cursor cur = cr.query(SMS_INBOX, projection, where,

    null

    ,

    “date desc”

    );

  8. if

    (

    null

    == cur)

  9. return

    ;

  10. if

    (cur.moveToNext()) {
  11. String number = cur.getString(cur.getColumnIndex(

    “address”

    ));

    //手机号
  12. String name = cur.getString(cur.getColumnIndex(

    “person”

    ));

    //联系人姓名列表
  13. String body = cur.getString(cur.getColumnIndex(

    “body”

    ));

  14. //这里我是要获取自己短信服务号码中的验证码~~
  15. Pattern pattern = Pattern.compile(

    ” [a-zA-Z0-9]{10}”

    );
  16. Matcher matcher = pattern.matcher(body);

  17. if

    (matcher.find()) {
  18. String res = matcher.group().substring(

    1

    ,

    11

    );
  19. mobileText.setText(res);
  20. }
  21. }
  22. }

sms主要结构:

_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

通过方式二,我们就能获取手机中所有的短消息了,可是还有一个问题,如果来了新的短消息呢?我们总不能写个线程,每隔多少秒,去读取一下短信数据库吧?其实我们可以把方式二换个方式写:


  1. private

    SmsObserver smsObserver;

  2. protected


    void

    onCreate(Bundle savedInstanceState) {

  3. super

    .onCreate(savedInstanceState);
  4. setContentView(R.layout.app_login);
  5. smsObserver =

    new

    SmsObserver(

    this

    , smsHandler);
  6. getContentResolver().registerContentObserver(SMS_INBOX,

    true

    ,
  7. smsObserver);
  8. }

  9. public

    Handler smsHandler =

    new

    Handler() {

  10. //这里可以进行回调的操作

  11. //TODO
  12. };

  13. class

    SmsObserver

    extends

    ContentObserver {

  14. public

    SmsObserver(Context context, Handler handler) {

  15. super

    (handler);
  16. }

  17. @Override

  18. public


    void

    onChange(

    boolean

    selfChange) {

  19. super

    .onChange(selfChange);

  20. //每当有新短信到来时,使用我们获取短消息的方法
  21. getSmsFromPhone();
  22. }
  23. }

效果:




版权声明:本文为PZ0605原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。