android拦截黑名单电话和短信

在之前的这篇博客中,https://blog.csdn.net/huangbaokang/article/details/112334420

一、手工调用Service来拦截黑名单号码

我们讲解了手工挂断电话,使用的是AIDL,通过点击按钮来触发挂断电话的功能。接下来我们实现自动挂断电话,到达拦截黑名单电话的功能。
具体原理是通过广播接收器,通过注册开机的广播,启动一个挂断电话的服务即可,我们分两步,手工启动挂断电话的服务,此处不使用广播,后面将讲解。
布局
在这里插入图片描述

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <Button
        android:id="@+id/btn_main_start"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="启动来电监听"
        android:onClick="startListenCall" />
    
     <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="停止来电监听"
        android:onClick="stopListenCall" 
        android:layout_below="@id/btn_main_start"
        />

</RelativeLayout>

处理Activity类,很简单,直接启动服务,和中断服务

package com.hbk.service;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {
    
    

	@Override
	protected void onCreate(Bundle savedInstanceState) {
    
    
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	
	public void startListenCall(View v) {
    
    
		startService(new Intent(this, ListenCallService.class));
	}
	
	public void stopListenCall(View v) {
    
    
		stopService(new Intent(this, ListenCallService.class));
	}
}

我定义ListenCallService类,并使用PhoneStateListener来监听不同打电话的状态,重点在处理响铃状态。

package com.hbk.service;

import java.lang.reflect.Method;

import com.android.internal.telephony.ITelephony;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class ListenCallService extends Service {
    
    

	private TelephonyManager tm;
	private PhoneStateListener listener = new PhoneStateListener() {
    
    

		// 当通话状态发生改变时调用
		/**
		 * Callback invoked when device call state changes.
		 *
		 * @see TelephonyManager#CALL_STATE_IDLE
		 * @see TelephonyManager#CALL_STATE_RINGING
		 * @see TelephonyManager#CALL_STATE_OFFHOOK
		 */
		public void onCallStateChanged(int state, String incomingNumber) {
    
    
			switch (state) {
    
    
			case TelephonyManager.CALL_STATE_IDLE:// 空闲 (挂断电话/未来电之前)
				Log.e("TAG", "空闲 (挂断电话/未来电之前)");
				break;
			case TelephonyManager.CALL_STATE_RINGING:// 响铃
				Log.e("TAG", "响铃");
				// 如果来电电话是黑名单号(110), 就挂断电话
				if ("110".equals(incomingNumber)) {
    
    
					try {
    
    
						endCall();
					} catch (Exception e) {
    
    
						e.printStackTrace();
					}
				}
				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:// 接通
				Log.e("TAG", "接通");

				break;
			default:
				break;
			}
		}
	};

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

	/**
	 * 挂断电话
	 * @throws Exception 
	 */
	private void endCall() throws Exception {
    
    
		// 通过反射调用隐藏的API
		// 得到隐藏类的Class对象
		Class c = Class.forName("android.os.ServiceManager");
		// 得到方法所对应的Method对象
		Method method = c.getMethod("getService", String.class);
		// 调用方法
		IBinder iBinder = (IBinder) method.invoke(null,
				Context.TELEPHONY_SERVICE);
		// 得到接口对象
		ITelephony telephony = ITelephony.Stub.asInterface(iBinder);
		// 结束通话
		telephony.endCall();
	}

	@Override
	public void onCreate() {
    
    
		super.onCreate();
		Log.e("TAG", "Service onCreate()");

		// 得到电话管理器
		tm = (TelephonyManager) this
				.getSystemService(Context.TELEPHONY_SERVICE);
		// 监听电话状态
		tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
	}

	@Override
	public void onDestroy() {
    
    
		super.onDestroy();
		Log.e("TAG", "Service onDestroy()");
		// 停止电话监听
		tm.listen(listener, PhoneStateListener.LISTEN_NONE);
	}

}

如上文件需要根据AIDL文件生成代码,才能在ListenCallService 中进行引用。
在这里插入图片描述

清单文件中增加如下两个权限

 	<!-- 挂断电话 -->
    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <!-- 读取电话状态 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

并注册服务

<service android:name="com.hbk.service.ListenCallService"></service>

测试点击启动监听,然后在模拟器中对110进行打电话,发现没有电话呼入,但在通话记录里却可以看到记录。
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程

二、使用广播进行黑名单号码短信拦截

解析来我们介绍使用广播来实现黑名单号码的电话及短信拦截。
新建一个BootReceiver来接收开机完成广播的receiver

package com.hbk.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

/**
 * 接收开机完成广播的receiver
 *
 */
public class BootReceiver extends BroadcastReceiver {
    
    

	@Override
	public void onReceive(Context context, Intent intent) {
    
    
		//启动电话监听的service
		context.startService(new Intent(context, ListenCallService.class));
	}

}

并在清单文件中增加如下权限

 <!-- 接收开机完成广播的权限 -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

注册广播,action name是固定写法,记住即可

		<receiver android:name="com.hbk.service.BootReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

工作中常用的广播
在这里插入图片描述
同理,我们定义一个拦截黑名单短信的receiver

package com.hbk.service;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;

/**
 * 接收来了短信的广播的receiver
 *
 */
public class SmsReceiver extends BroadcastReceiver {
    
    

	@Override
	public void onReceive(Context context, Intent intent) {
    
    
		//1. 得到intent短信数据, 并封装为短信对象smsMessage
		Bundle extras = intent.getExtras();
		Object[] pdus = (Object[])extras.get("pdus");
		SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])pdus[0]);
		//2. 取号码
		String number = smsMessage.getOriginatingAddress();
		String content = smsMessage.getMessageBody();
		Log.e("TAG", number +" : "+content);
		//3. 判断是否是黑名单号
		if("110".equals(number)) {
    
    
			//4. 如果是, 中断广播(拦截短信)
			abortBroadcast();
			Log.e("TAG", "拦截到一个黑名单短信");
		}
	}

}

在清单文件中进行配置

<receiver android:name="com.hbk.service.SmsReceiver">
         <intent-filter android:priority="2147483647">
             <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
         </intent-filter>
     </receiver>

通过SmsMessage 对象去取出电话号码及短信内容。测试的话,先部署应用,然后关掉虚拟机,重新开机进行测试,开机的时候可以看到黑名单号码的广播接收器生效了。

猜你喜欢

转载自blog.csdn.net/huangbaokang/article/details/112461401