Android 短信攔截+來去電話攔截

jopen 8年前發布 | 51K 次閱讀 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方案有些問題,看這里

如何在Android 4.4上實現短信攔截


------------------------------------------------

推薦博客:

http://my.csdn.net/L173864930

http://su1216.iteye.com/


二.電話來去電攔截

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" />


來自: http://my.oschina.net/ososchina/blog/501874

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!