Androidの短信拦截方法详解
小米系统在安装时,让用户来控制权限;360来监听优先拦截短信等等(关于谁先安装谁有优先权,动态注册比静态注册优先级别高等问题)
(1)注册BroadcastReceiver可以使用两种方法:
通过在AndroidManifest.xml文件中定义<Receiver>字段静态注册;
通过在程序中Context.registerReceiver()动态注册;
那么,应用怎么确定获取消息的先后顺序呢?Android提供了两种类型的Broadcast:
Normal broadcast:应用抛出的这种类型的广播是异步的,应用接收到的顺序也是不可控制的;同时,应用无法选择是否不将该广播传递给下一个 应用(系统会自动派发管理,保证每一个应用都可接收到该广播);
Ordered broadcast:应用按顺序处理该广播,并且可以决定是否将广播消息继续传递下去;接收到广播的顺序按照android:priority属性值决定(程序中同样可以控制),同一个priority值的应用按照应用的包名的字符顺序排列顺序来决定接收广播的顺序;
ok,应用获取消息的顺序,如何获取广播消息等基础知识讲完了,那么我们来看看如何截获短信:
首先应用需要注册一个Receiver,短信是一个Ordered broadcast,我们的例子里面使用静态方法注册:
<receiver android:name=".SmsReceiver"> <intent-filter android:priority="2324324234"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter></receiver>注意这里的priority可以适当设置大一点,只要不超过Integer.MAX_VALUE就可以。紧接着下面就可以在onReceive里面处理广播来的消息。
public static class SmsRecivers extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Bundle bundle = intent.getExtras();SmsMessage msg = null;if (null != bundle) {Object[] smsObj = (Object[]) bundle.get("pdus");for (Object object : smsObj) {msg = SmsMessage.createFromPdu((byte[]) object);Date date = new Date(msg.getTimestampMillis());// 时间SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String receiveTime = format.format(date);System.out.println("blueberry_number:"+ msg.getOriginatingAddress() + " body:"+ msg.getDisplayMessageBody() + " time:"+ msg.getTimestampMillis());// 在这里写自己的逻辑if (msg.getOriginatingAddress().equals("10086")) {// TODO}}}}}
利用广播监听到信息后,然后可以在吃出进行处理了。
2. 利用监听数据库拦截短信
(1)开启一个服务开监听数据库
import android.app.Service;import android.content.ContentResolver;import android.content.Intent;import android.net.Uri;import android.os.IBinder;import android.os.Process;public class SmsService extends Service { private SmsObserver mObserver; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { 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()); }}
(2)数据库观察者
import android.content.ContentResolver;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Message;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) { 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); } //根据你的拦截策略,判断是否不对短信进行操作;将短信设置为已读;将短信删除 Message msg=smsHandler.obtainMessage(); _smsInfo.action=2;//0不对短信进行操作;1将短信设置为已读;2将短信删除 msg.obj=_smsInfo; smsHandler.sendMessage(msg); } } if(mCursor!=null){ mCursor.close(); mCursor=null; } }}
(3)短信处理类
import android.content.ContentValues;import android.content.Context;import android.net.Uri;import android.os.Handler;import android.os.Message;/** * @author 短信的处理 * */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}); } } }(4) SmsInfo 数据结构
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表示删除短信}这样就可以监听数据库中短信变化,拦截删除短信了。
3. 源代码
android短信拦截
更多源码
http://blog.csdn.net/xiabing082/article/details/10189827
更多相关文章
- Android: Image类浅析(结合YUV_420_888)
- Android(安卓)记一次解决问题的过程
- 屏幕适配那点事
- 使用Android提供的android-support-v7出错
- android 各种权限 permission 列举
- android软键盘弹出引起的各种不适终极解决方案 .
- android tabhost 自定义标题 you cannot combine custom titles
- Adnroid——自定义控件(入门篇之自定义验证码)
- Android大图片裁剪终极解决方案