Android 监听短信(同时监听广播和数据库)

暗扣,强烈谴责这种侵害用户利益的行为。。。

下面给大家介绍Android暗扣原理.......  Android4.4以下的系统玩游戏就要小心了哈

暗扣方式之一:短信订购,即监听--------拦截------------处理短信。

暗扣方式之二:模拟人为操作(又叫模拟流量),通过后台程序代码模拟人的点击行为,暗自给用户订购业务,由运营商收取你的费用,当然这其中也需要涉及监听/拦截/处理短信。使用这种方式的原理无非是Http处理网页,还涉及接入点切换问题,这里就不详细讲解。

回归正题:有的时候,我们的手机程序需要监听手机短信,当满足条件A时,不处理;当满足条件B时,将其设置为已读;当满足条件C时,将短信删除。

注:Android 4.4以及以后可能由用户来控制程序的权限,如果用户关闭这个程序的权限,意味着你无法监听短信/操作短信内容

目前也有如小米系统在安装时,让用户来控制权限;360来监听优先拦截短信等等(关于谁先安装谁有优先权,动态注册比静态注册优先级别高等问题,在这些情况这里就不讲了)。。。

Android 实现监听短信(同时监听广播和数据库)代码如下:

    1. 拦截广播

      package com.javen.sms.receiver;
      
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import java.util.TimeZone;
      
      import com.javen.util.InterceptKeyKeeper;
      
      import android.content.BroadcastReceiver;
      import android.content.Context;
      import android.content.Intent;
      import android.os.Bundle;
      import android.telephony.SmsMessage;
      import android.util.Log;
      import android.widget.Toast;
      
      public class SmsReceiver extends BroadcastReceiver {
          private Context mContext;
          public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
          public static final String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER";
      
          @Override
          public void onReceive(Context context, Intent intent) {
              this.mContext=context;
              Toast.makeText(context, "接收短信执行了.....", Toast.LENGTH_LONG).show();
              Log.e("SMSReceiver, isOrderedBroadcast()=", isOrderedBroadcast()+"");
              Log.e("SmsReceiver onReceive...", "接收短信执行了......");
              String action = intent.getAction();
              if (SMS_RECEIVED_ACTION.equals(action) || SMS_DELIVER_ACTION.equals(action)) {
                  Toast.makeText(context, "开始接收短信.....", Toast.LENGTH_LONG).show();
                  Log.e("SmsReceiver onReceive...", "开始接收短信.....");
      
                  Bundle bundle = intent.getExtras();
                  if (bundle != null) {
                      Object[] pdus = (Object[])bundle.get("pdus");
                      if (pdus != null && pdus.length > 0) {
                          SmsMessage[] messages = new SmsMessage[pdus.length];
                          for (int i = 0; i < pdus.length; i++) {
                              byte[] pdu = (byte[]) pdus[i];
                              messages[i] = SmsMessage.createFromPdu(pdu);
                          }
                          for (SmsMessage message : messages) {
                              String content = message.getMessageBody();// 得到短信内容
                              String sender = message.getOriginatingAddress();// 得到发信息的号码
                              if (content.contains(InterceptKeyKeeper.getInterceptKey(mContext))) {
                                  Toast.makeText(mContext, "内容为:"+content, Toast.LENGTH_LONG).show();
                                  //setResultData(null);
                                  this.abortBroadcast();// 中止
                              }else if (sender.equals("10010") || sender.equals("10086")) {
                                  Toast.makeText(mContext, "内容为:"+content, Toast.LENGTH_LONG).show();
                                  this.abortBroadcast();// 中止
                              }
                              Date date = new Date(message.getTimestampMillis());
                              SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                              format.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
                              String sendContent = format.format(date) + ":" + sender + "--" + content;
                              Log.e("SmsReceicer onReceive ",sendContent +" ");
                          }
                      }
                  }
              }
          }
      }


    2. 开启一个服务开监听数据库

      package com.javen.service;
      
      import android.app.Service;
      import android.content.ContentResolver;
      import android.content.Intent;
      import android.net.Uri;
      import android.os.IBinder;
      import android.os.Process;
      import android.widget.Toast;
      
      /**
       * @author Javen
       * 开启一个服务开监听数据库
       */
      public class SmsService extends Service {
      
          private SmsObserver mObserver;
      
          @Override
          public IBinder onBind(Intent intent) {
              return null;
          }
      
          @Override
          public void onCreate() {
              Toast.makeText(this, "SmsService 服务器启动了....", Toast.LENGTH_LONG).show();
              // 在这里启动
              ContentResolver resolver = getContentResolver();
              mObserver = new SmsObserver(resolver, new SmsHandler(this));
              resolver.registerContentObserver(Uri.parse("content://sms"), true,mObserver);
          }
      
          @Override
          public void onDestroy() {
              super.onDestroy();
              this.getContentResolver().unregisterContentObserver(mObserver);
              Process.killProcess(Process.myPid());
          }
      }


    3. 数据库观察者

      package com.javen.service;
      
      import android.content.ContentResolver;
      import android.database.ContentObserver;
      import android.database.Cursor;
      import android.net.Uri;
      import android.os.Message;
      import android.util.Log;
      
      /**
       * @author Javen
       * 数据库观察者
       */
      public class SmsObserver extends ContentObserver {
      
          private ContentResolver mResolver;
          public SmsHandler smsHandler;
      
          public SmsObserver(ContentResolver mResolver, SmsHandler handler) {
              super(handler);
              this.mResolver = mResolver;
              this.smsHandler = handler;
          }
      
          @Override
          public void onChange(boolean selfChange) {
              Log.i("SmsObserver onChange ", "SmsObserver 短信有改变");
              Cursor mCursor = mResolver.query(Uri.parse("content://sms/inbox"),
                      new String[] { "_id", "address", "read", "body", "thread_id" },
                      "read=?", new String[] { "0" }, "date desc");
      
              if (mCursor == null) {
                  return;
              } else {
                  while (mCursor.moveToNext()) {
                      SmsInfo _smsInfo = new SmsInfo();
      
                      int _inIndex = mCursor.getColumnIndex("_id");
                      if (_inIndex != -1) {
                          _smsInfo._id = mCursor.getString(_inIndex);
                      }
      
                      int thread_idIndex = mCursor.getColumnIndex("thread_id");
                      if (thread_idIndex != -1) {
                          _smsInfo.thread_id = mCursor.getString(thread_idIndex);
                      }
      
                      int addressIndex = mCursor.getColumnIndex("address");
                      if (addressIndex != -1) {
                          _smsInfo.smsAddress = mCursor.getString(addressIndex);
                      }
      
                      int bodyIndex = mCursor.getColumnIndex("body");
                      if (bodyIndex != -1) {
                          _smsInfo.smsBody = mCursor.getString(bodyIndex);
                      }
      
                      int readIndex = mCursor.getColumnIndex("read");
                      if (readIndex != -1) {
                          _smsInfo.read = mCursor.getString(readIndex);
                      }
      
                      // 根据你的拦截策略,判断是否不对短信进行操作;将短信设置为已读;将短信删除
                      // TODO
                      System.out.println("获取的短信内容为:"+_smsInfo.toString());
                      Log.i("SmsObserver ...", "获取的短信内容为:"+_smsInfo.toString());
                      Message msg = smsHandler.obtainMessage();
                      _smsInfo.action = 2;// 0不对短信进行操作;1将短信设置为已读;2将短信删除
                      msg.obj = _smsInfo;
                      smsHandler.sendMessage(msg);
                  }
              }
      
              if (mCursor != null) {
                  mCursor.close();
                  mCursor = null;
              }
          }
      }


    4. 短信处理类

      package com.javen.service;
      
      import android.content.ContentValues;
      import android.content.Context;
      import android.net.Uri;
      import android.os.Handler;
      import android.os.Message;
      
      /**
       * @author Javen
       *
       *         短信的处理
       *
       */
      public class SmsHandler extends Handler {
          private Context mcontext;
      
          public SmsHandler(Context context) {
              this.mcontext = context;
          }
      
          @Override
          public void handleMessage(Message msg) {
              SmsInfo smsInfo = (SmsInfo) msg.obj;
      
              if (smsInfo.action == 1) {
                  ContentValues values = new ContentValues();
                  values.put("read", "1");
                  mcontext.getContentResolver().update(
                          Uri.parse("content://sms/inbox"), values, "thread_id=?",
                          new String[] { smsInfo.thread_id });
              } else if (smsInfo.action == 2) {
                  Uri mUri = Uri.parse("content://sms/");
                  mcontext.getContentResolver().delete(mUri, "_id=?",
                          new String[] { smsInfo._id });
              }
          }
      }


    5. SmsInfo 数据结构 主要用于短信拦截

      package com.javen.service;
      
      /**
       * 主要用于短信拦截
       *
       * @author Javen
       *
       */
      public class SmsInfo {
          public String _id = "";
          public String thread_id = "";
          public String smsAddress = "";
          public String smsBody = "";
          public String read = "";
          public int action = 0;// 1代表设置为已读,2表示删除短信
          @Override
          public String toString() {
              return "SmsInfo [_id=" + _id + ", thread_id=" + thread_id
                      + ", smsAddress=" + smsAddress + ", smsBody=" + smsBody
                      + ", read=" + read + ", action=" + action + "]";
          }
      
      }


    6. 需要的权限以及配置信息

      <?xml version="1.0" encoding="utf-8"?>
      <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.javen.sms"
          android:versionCode="1"
          android:versionName="1.0" >
      
          <uses-sdk
              android:minSdkVersion="8"
              android:targetSdkVersion="21" />
      
          <uses-permission android:name="android.permission.SEND_SMS" />
           <uses-permission android:name="android.permission.RECEIVE_SMS" />
      
           <!-- <uses-permission android:name="android.permission.BROADCAST_SMS" />
           <uses-permission android:name="android.permission.READ_SMS" />
          <uses-permission android:name="android.permission.WRITE_SMS" /> -->
          <application
              android:allowBackup="true"
              android:icon="@drawable/ic_launcher"
              android:label="@string/app_name"
              >
              <activity
                  android:name=".MainActivity"
                  android:label="@string/app_name" >
                  <intent-filter>
                      <action android:name="android.intent.action.MAIN" />
      
                      <category android:name="android.intent.category.LAUNCHER" />
                  </intent-filter>
              </activity>
      
               <receiver
                  android:name="com.javen.sms.receiver.SmsReceiver"
                  android:exported="true"
                  android:permission="android.permission.BROADCAST_SMS">
                  <intent-filter android:priority="2147483647" >
                      <action android:name="android.provider.Telephony.SMS_RECEIVED" />
                      <action android:name="android.provider.Telephony.SMS_DELIVER" />
                      <category android:name="android.intent.category.DEFAULT" />
                  </intent-filter>
              </receiver>
      
              <service android:name="com.javen.service.SmsService"></service>
          </application>
      
      </manifest>

    7. 测试在MainActivity 中启动SmsService  发送短信到10086 或者10010即可测试

       

              intentService = new Intent(this, SmsService.class);
              startService(intentService);
              Toast.makeText(this, "启动service中.....", 1).show();
          

      以上就是Android 4.4以下暗扣原理。   Android 4.4以上如何实现大家可以在此博客中讨论交流。。。。。

时间: 2024-10-10 09:09:07

Android 监听短信(同时监听广播和数据库)的相关文章

监听短信(监听系统广播)

监听短信(监听系统广播)

Android实战简易教程-第三十六枪(监听短信)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: <code class="hljs java has-numbering"><span class="hljs-keyword">package</s

Android 监听短信2种方式:Broadcast和ContentObserver

1. 基于Broadcast接受短信 1.1 原理 Android收到短信后系统会发送一个android.provider.Telephony.SMS_RECEIVED广播.把它放在Bundle(intent.Extras)中,Bundle可以理解为一个Map,短信采用"pdus"作为键,pdus应该是protocol description units的简写,也就是一组短信.Android不是一接收到短信就立刻发出广播的,他会有一定的延迟,所以就有可能会有多条短信,所以才会用数组来存

(七)android开发中两种方式监听短信的原理和实现

一.监听短信的两种方式的简介 Android程序开发中,有两种方式监听短信内容:一.接收系统的短信广播:二.应用观察者模式,监听短信数据库. 第一种方式接收系统的短信广播: A.这种方式只对新收到的短消息有效,运行代码,并不会读取收件箱中已读或未读的消息,只有当收到新来的短消息时,才会执行onReceive()方法. B.并且这个广播是有序广播,如果当别的程序先读取到了这个广播,然后拦截掉了个这个广播,你将接收不到.当然我们可以通过设置priority的数值,其实有时是不管用的,现在在一些定制的

Android 监听短信 两种方式

1. 接受系统的短信广播,操作短信内容. 优点:操作方便,适合简单的短信应用. 缺点:来信会在状态栏显示通知信息. AndroidManifest.xml: <uses-permission android:name="android.permission.SEND_SMS"></uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"

Android短信的发送和广播接收者实现短信的监听

原文地址:http://www.cnblogs.com/zyw-205520/archive/2013/01/24/2875686.html Android短信的发送和广播接收者实现短信的监听  要注意Android清单中权限的设置以及广播的注册监听实现 以下就是 Android清单的XML AndroidManifest.xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" packag

Android实战简易教程-第三十六枪(监听短信-实现短信验证码自动填入)

一般用户喜欢用手机号作为用户名注册APP账号,这时一般都是通过手机验证码的方式进行验证,下面我们就研究一个非常实用的方法,通过监听短信-实现短信验证码的自动填入,提高用户体验. 首先我们看一下如何监听手机短信. 一.获取短信全部内容 1.新建一个SMSBroadcastReceiver: package com.example.messagecut; import java.text.SimpleDateFormat; import java.util.Date; import android.

android菜鸟学习笔记23----ContentProvider(三)利用内置ContentProvider监听短信及查看联系人

要使用一个ContentProvider,必须要知道的是它所能匹配的Uri及其数据存储的表的结构. 首先想办法找到访问短信及联系人数据的ContentProvider能接受的Uri: 到github上找对应ContentProvider的源码:https://github.com/android 有好多个,哪一个才是短信数据的ContentProvider呢? 在filters输入框:输入telephony. 现在只有一个了,打开: 装有git的话,可以选择clone到本地,没有的话,就选择下载

Android监听短信到来并自动填充到输入框中

基本原理:通过ContentObserver观察者监听sms数据库的改变,当有变化时检测是否是来自指定号码的短信,如果是的话就通过正则表达式获得需要的内容,然后贴代码 (*^__^*) 嘻嘻……: 1 /** 2 * 3 * @ClassName: SmsContent 4 * @Description: 短信监听类 5 * @author guoyizhe 6 * @email [email protected] 7 * @date 2015-6-9 下午3:30:12 8 * 9 */ 10