Android 短信攔截+來去電話攔截
一.短信攔截分為2種方式,其一是廣播,其二是內容觀察者
如何判斷android 短信發送(sendTextMessage)是否成功
第一種是通過BroadcastReciver
<uses-permission android:name="android.permission.RECEIVE_SMS"/> <!-- 攔截短信(就是接受短些的權限) --> <receiver android:name="com.demo.artshell.broadcastreceiverdemo.InterceptReceiver"> <!-- 這里沒有設置android:enable和android:exported屬性,<a >參考官方文檔</a> --> <!--這里的優先級為1000,假定你手機中沒有安裝其他第三方短信攔截軟件,如360等,否則其他第三方軟件攔截權限過高導致你都應用程序攔截不到短信--> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver
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; import java.text.SimpleDateFormat; import java.util.Date; public class InterceptReceiver extends BroadcastReceiver { public static final String TAG = "InterceptReceiver"; public static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED"; public InterceptReceiver() {} @Override public void onReceive(Context context, Intent intent) { Log.i(TAG,"---------------InterceptReceiver onReceive()----------------"); if (ACTION_SMS_RECEIVED.equals(intent.getAction())) { Bundle carryContent = intent.getExtras(); if (carryContent != null) { StringBuilder sb = new StringBuilder(); // 通過pdus獲取接收到的所有短信息,獲取短信內容 Object[] pdus = (Object[]) carryContent.get("pdus"); // 構建短信對象數組 SmsMessage[] mges = new SmsMessage[pdus.length]; for (int i = 0, len = pdus.length; i < len; i++) { // 獲取單條短信內容,以pdu格式存,并生成短信對象 mges[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); } for (SmsMessage mge : mges) { sb.append("短信來自:" ).append(mge.getDisplayOriginatingAddress()).append("\n") .append("短信內容:").append(mge.getMessageBody()).append("\n"); Date sendDate = new Date(mge.getTimestampMillis()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sb.append("短信發送時間:").append(format.format(sendDate)); } Log.i(TAG,sb.toString()); // 打印日志記錄 Toast.makeText(context,sb.toString(),Toast.LENGTH_LONG).show(); this.abortBroadcast(); // 不再往下傳播 } } } }
第二種通過ContentObserver
content://sms/inbox 收件箱
content://sms/sent 已發送
content://sms/draft 草稿
content://sms/outbox 發件箱
content://sms/failed 發送失敗
content://sms/queued 待發送列表
private SmsObserver smsObserver; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.app_login); smsObserver = new SmsObserver(this, null); getContentResolver().registerContentObserver(SMS_INBOX, true, smsObserver); } protected void onstop() { super.onstop(); //必須解除注冊,否則Activity不能銷毀 getContentResolver().unregisterContentObserver(smsObserver); } class SmsObserver extends ContentObserver { public SmsObserver(Context context, Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { super.onChange(selfChange); //每當有新短信到來時,使用我們獲取短消息的方法 getSmsFromPhone(); } }
查詢數據庫
private Uri SMS_INBOX = Uri.parse("content://sms/inbox"); public void getSmsFromPhone() { ContentResolver cr = getContentResolver(); String[] projection = new String[] { "body" };//"_id", "address", "person",, "date", "type String where = " address = '1066321332' AND date > " + (System.currentTimeMillis() - 10 * 60 * 1000); Cursor cur = cr.query(SMS_INBOX, projection, where, null, "date desc"); if (null == cur) return; if (cur.moveToNext()) { String number = cur.getString(cur.getColumnIndex("address"));//手機號 String name = cur.getString(cur.getColumnIndex("person"));//聯系人姓名列表 String body = cur.getString(cur.getColumnIndex("body")); //這里我是要獲取自己短信服務號碼中的驗證碼~~ Pattern pattern = Pattern.compile(" [a-zA-Z0-9]{10}"); Matcher matcher = pattern.matcher(body); if (matcher.find()) { String res = matcher.group().substring(1, 11); mobileText.setText(res); } } }
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
Android4.4方案有些問題,看這里
------------------------------------------------
推薦博客:
二.電話來去電攔截
public class CallPhoneActivity extends Activity { private CallPhoneBroadcastReceiver mBroadcastReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_call_phone); mBroadcastReceiver = new CallPhoneBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);//添加此Action來攔截來去電電話 intentFilter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);//添加此Action來攔截來電電話狀態 registerReceiver(mBroadcastReceiver, intentFilter); } @Override protected void onDestroy() { //取消注冊,防止內存溢出 unregisterReceiver(mBroadcastReceiver); super.onDestroy(); } public class CallPhoneBroadcastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { AudioManager mAudioManager=(AudioManager)context.getSystemService(Context.AUDIO_SERVICE); String inComingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);//去電 String outGogingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); //來電 String phoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if(Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) { if (outGogingNumber == null) { outGogingNumber = getResultData(); } if (shouldCancel(outGogingNumber)) //判斷號碼是不是需要攔截 { mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); setResultData(null); mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); } else { setResultData(reformatNumber(outGogingNumber)); } Log.i("TAG", "去電號碼:phoneState="+phoneState+",phoneNumber="+outGogingNumber); } else if(!TextUtils.isEmpty(inComingNumber) && TelephonyManager.EXTRA_STATE_RINGING.equals(phoneState)) { //關于來電攔截,網上例子很多,如:http://blog.csdn.net/wangfayinn/article/details/8004023 //注意TelephonyManager.EXTRA_STATE_RINGING.equals(phoneState)必須判斷,否則來去電判斷不準確 Log.e("TAG", "來電號碼:inComingNumber="+phoneState+",phoneNumber="+inComingNumber); } } //攔截變更號碼 private String reformatNumber(String phoneNumber) { return "17951".concat(phoneNumber); } //判斷該號碼是否為危險號碼 private boolean shouldCancel(String phoneNumber) { return "13002248003".equals(phoneNumber); } } /** * 摸你去電 * @param v */ public void onClickToCallPhone(View v) { Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:13724551306")); startActivity(intent); } }
注意TelephonyManager.EXTRA_STATE_RINGING.equals(phoneState)必須判斷,否則來去電判斷不準確
權限
<!-- 呼出電話攔截 --> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/> <!-- 讀取電話狀態 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 撥打電話 --> <uses-permission android:name="android.permission.CALL_PHONE" />
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!