Android-实现对指定电话的短信拦截和来电拦截

用service的onCreate/onDestroy来控制广播的监听(电话,sms)。

先写一个这样的框架,具体功能不实现:
/**
 * 用TelSmsBlackService来控制广播监听(电话,sms)。
 * 
 * @author lmk
 * 
 */
public class TelSmsBlackService extends Service {

	private SmsBroadcastReceiver smsBroadcastReceiver;
	private BlackDao blackDao;
	private TelephonyManager tm;
	private PhoneStateListener listener;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	// 短信广播
	private class SmsBroadcastReceiver extends BroadcastReceiver {

		@Override
		public void onReceive(Context context, Intent intent) {
			// 短信广播监听要干的事情
			//__①__
		}
	}

	@Override
	public void onCreate() {
		blackDao = new BlackDao(getApplicationContext());
		// 创建短信的广播监听对象
		smsBroadcastReceiver = new SmsBroadcastReceiver();
		// 短信广播意图
		IntentFilter filter = new IntentFilter(
				"android.provider.Telephony.SMS_RECEIVED");
		// 设置最高级别
		filter.setPriority(Integer.MAX_VALUE);
		registerReceiver(smsBroadcastReceiver, filter);

		// 开启电话的监听

		tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		listener = new PhoneStateListener() {

			@Override
			public void onCallStateChanged(int state,
					final String incomingNumber) {
				// state 电话的状态 incomingNumber 打进来的号码
				switch (state) {
				case TelephonyManager.CALL_STATE_IDLE:// 挂断的状态,空闲的状态
					System.out.println("CALL_STATE_IDLE");
					break;
				case TelephonyManager.CALL_STATE_RINGING:// 响铃状态
					System.out.println("CALL_STATE_RINGING");
					// 判断是否是黑名单号码
					//__②__
					break;
				case TelephonyManager.CALL_STATE_OFFHOOK:// 通话的状态
					System.out.println("CALL_STATE_OFFHOOK");
					break;

				default:
					break;
				}
				super.onCallStateChanged(state, incomingNumber);
			}

		};
		// 注册电话的监听
		tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// 关闭短信的广播监听
		unregisterReceiver(smsBroadcastReceiver);
		// 关闭电话的监听
		tm.listen(listener, PhoneStateListener.LISTEN_NONE);
		super.onDestroy();
	}
}

当然了,service是要在清单中配置的,如下:

以上就已经完成了大体,现在开始实现具体功能

短信拦截功能这个相对来电拦截较简单,实现代码如下(把下面代码填入上面框架的①位置里):
// 短信广播监听要干的事情
			Object[] datas = (Object[]) intent.getExtras().get("pdus");
			for (Object sms : datas) {
				SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms);
				//短信来自的号码
				String phone = smsMessage.getOriginatingAddress();
				if(phone.equals("1234657981")){
					//终止广播
					abortBroadcast();
				}
			}


来电拦截,因为TelephonyManager.endCall();方法自1.5版本后,把该方法被阉割掉,所以现在只能厉用反射(把以下代码放到框架的②里)。
// 如果是拦截号码
					if (incomingNumber.equals("1231565123231")) {
						// 电话拦截
						System.out.println("挂断电话");
						// 挂断电话之前先注册内容观察者,监听电话日志的变化
						getContentResolver().registerContentObserver(
								Uri.parse("content://call_log/calls"), true,
								new ContentObserver(new Handler()) {
									// 电话日志变化 触发此方法调用
									@Override
									public void onChange(boolean selfChange) {
										// 马上删除电话日志
										deleteCalllog(incomingNumber);//__③_
										// 再取消内容观察者注册
										getContentResolver()
												.unregisterContentObserver(this);
										super.onChange(selfChange);
									}

								});
						endCall();//__④__
					}


上面的③方法具体实现为:
protected void deleteCalllog(String number) {
		Uri uri = Uri.parse("content://call_log/calls");
		// 删除日志
		getContentResolver().delete(uri, "number=?", new String[] { number });
	}

上面的④方法才死重点的反射,当然了,反射前要放入两个aidl文件到项目中(具体请看图片),这两个aidl文件再Android源码里搜索就有。
Android-实现对指定电话的短信拦截和来电拦截_第1张图片


方法④具体代码实现如下
/**
	 * 挂断电话
	 */
	protected void endCall() {
		// TelephonyManager.endCall(); 1.5版本后,把该方法阉割掉了
		// 想用该功能,实现方法
		// ServiceManager.getService();
		// 反射调用

		try {
			// 1.class
			Class clazz = Class.forName("android.os.ServiceManager");
			// 2. method
			Method method = clazz.getDeclaredMethod("getService", String.class);

			// 3.obj 不需要 静态方法
			// 4. 调用
			IBinder binder = (IBinder) method.invoke(null,
					Context.TELEPHONY_SERVICE);

			// 5.aidl
			ITelephony iTelephony = ITelephony.Stub.asInterface(binder);

			AudioManager mAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
			// 先静音处理
			mAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
			// 挂断电话
			iTelephony.endCall(); 
			// 再恢复正常铃声
			mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);

		} catch (Exception e) {
			e.printStackTrace();
		}

	}


功能已全部实现!又完成一项任务!太简单了!






你可能感兴趣的:(Android开发)