Android 来电(包括铃声),短信拦截的实现方法

关于拦截的文章我之前写过拦截Back按键和Home按键的处理方法,今天就开发过程中关于电话,短信的拦截做一个总结。

一:拦截来电的功能实现

  现在的Android版本已经把Phone类的相关API给隐藏起来了,想要用代码实现挂断电话的功能,就必须通过AIDL才行,然后利用反射来使用其方法。

  1:在程序中新建一个包,因为要使用aidl,所以包名必须为:com.android.internal.telephony。

   2:在这个包里面新建一个名为ITelephony.aidl的文件,然后在文件里面写入代码:

package com.android.internal.telephony;
    interface ITelephony{
        boolean endCall();
        void answerRingingCall();
    }
   这个时候就可以监听电话的状态, 现在我们处理的方式是如果联系人在手机中不存在就进行来电拦截 ,代码如下: 
package com.example.zf_bluteethservice;

import java.lang.reflect.Method;
import java.util.ArrayList;

import com.android.internal.telephony.ITelephony;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.provider.ContactsContract;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.media.AudioManager;
import android.os.RemoteException;

public class PhoneStatReceiver extends BroadcastReceiver{

	String TAG = "lyj_incall";
	TelephonyManager telMgr;
	private AudioManager mAudioManager;
	private static int previousMuteMode = -1;
	@Override
	public void onReceive(Context context, Intent intent) {
         telMgr = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
		 mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 
		//M:lyj -- 拦截来电铃声 start ---
		if (previousMuteMode == -1){
			previousMuteMode = mAudioManager.getRingerMode();
			mAudioManager.setRingerMode(0);
   		 }
		mAudioManager.setRingerMode(previousMuteMode);
		previousMuteMode = -1;
		//M:lyj -- 拦截来电铃声 end ---
        switch (telMgr.getCallState()) {
            case TelephonyManager.CALL_STATE_RINGING:
            	String number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); 
            	if (!getPhoneNum(context).contains(number)) {
            		Log.e("lyj_incall", "Reject to answer ring call.");
					//挂断电话     
					 endCall();
					//再恢复正常铃声     
            		
            	}
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:                               
                break;
            case TelephonyManager.CALL_STATE_IDLE:                               
                break;
        }
        
	}
	/**
	 * 挂断电话
	 */
    private void endCall()
    {
        Class c = TelephonyManager.class;         
        try
        {
            Method getITelephonyMethod = c.getDeclaredMethod("getITelephony", (Class[]) null);
            getITelephonyMethod.setAccessible(true);
            ITelephony iTelephony = null;
            Log.e(TAG, "End call.");
            iTelephony = (ITelephony) getITelephonyMethod.invoke(telMgr, (Object[]) null);
            iTelephony.endCall();
        }
        catch (Exception e)
        {
            Log.e(TAG, "Fail to answer ring call.", e);
        }        
    }
    private ArrayList  getPhoneNum(Context context) {
    	ArrayList numList = new ArrayList();
		//得到ContentResolver对象   
        ContentResolver cr = context.getContentResolver();     
        //取得电话本中开始一项的光标   
        Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);   
        while (cursor.moveToNext())   
        {               
            // 取得联系人ID   
            String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));   
            Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
            		ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);   
            // 取得电话号码(可能存在多个号码)   
            while (phone.moveToNext())   
            {   
                String strPhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));   
                numList.add(strPhoneNumber);  
                Log.v("tag","strPhoneNumber:"+strPhoneNumber);
            }   
            
            phone.close();   
        }   
        cursor.close();
        return numList;
	}
}
  注意  1:PhoneStatReceiver一定要在清单文件(AndroidManifest.xml)中注册。   2:在AndroidManifest.xml 添加权限

      
      
      
      
      
      
     这里只是完成了对来电的拦截功能,未对外拨电话进行拦截。

二:拦截来电铃声

private static int previousMuteMode = -1;

/**
 * 来电静音
 *
 * @param context
 */
private void toggleRingerMute(Context context)
{
    AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    if (previousMuteMode == -1)
    {
        previousMuteMode = am.getRingerMode();
        am.setRingerMode(0);
    }
    am.setRingerMode(previousMuteMode);
    previousMuteMode = -1;
}
  这段代码在来电拦截的代码中写过,这个大家一看就明白。

 三:短信拦截

  要做一个自动短信回复,所以需要拦截系统短信.

  1.在Manifest.xml里加"接收"SMS的权限  

  2:在Manifest.xml里注册一个receive


  
   
    
   
  
3.定义一个短信接收类,并且重写onReceive

 完整代码如下:

package com.example.zf_bluteethservice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

//继承BroadcastReceiver
public class AutoSMS extends BroadcastReceiver {

    private String TAG="LYJ_Mms";
    //广播消息类型
    public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
    //覆盖onReceive方法
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        // TODO Auto-generated method stub
        Log.i(TAG, "引发接收事件");
        //先判断广播消息
        String action = intent.getAction();
        if (SMS_RECEIVED_ACTION.equals(action))
        {
        	Log.i(TAG, "引发接收事件");
        	Toast.makeText(context, "屏蔽一条短信信息", Toast.LENGTH_LONG).show();
        	abortBroadcast();
            //获取intent参数
            Bundle bundle=intent.getExtras();
            
        }
    }

}
  通过广播拦截这样就能屏蔽来的短信。

  以上电话和短信的拦截代码实现 希望对大家有所帮助。


 

你可能感兴趣的:(Android,拦截)