android 黑名单中电话拦截

来源:互联网 发布:淘宝号为什么会被监控 编辑:程序博客网 时间:2024/04/17 00:16

今天讲一下最近项目中刚做的黑名单拦截,其中可以拦截短信和电话

先讲一下拦截电话的操作

首先要注册一个监听电话广播的广播接收器。

在Manifest文件中

<receiver    android:name=".Receiver.InterceptSmsReceiver"    android:enabled="true"    android:exported="true">    <intent-filter android:priority="2147483647">        <action android:name="android.provider.Telephony.SMS_RECEIVED" />    </intent-filter></receiver>
同时还要添加读取电话记录,写入电话记录,以及监听电话的权限

<uses-permission android:name="android.permission.CALL_PHONE" /><uses-permission android:name="android.permission.WRITE_CALL_LOG" /><uses-permission android:name="android.permission.READ_CALL_LOG" />

现在来说一下拦截电话的逻辑

使用广播接收器监听电话广播,如果发现来电号码存在于黑名单中,那么就endCall(),这时要注意通话记录中是都存在需要拦截的号码的电话记录,如果存在的话,要通过ContentResolver将其删除掉。

public class InterceptCallReceiver extends BroadcastReceiver {    private static final String TAG = "interceptcall";    public InterceptCallReceiver() {    }    @Override    public void onReceive(Context context, Intent intent) {        SharedPreferences mSp = context.getSharedPreferences("config", Context.MODE_PRIVATE);        boolean BlackNumStatus = mSp.getBoolean("BlackNumStatus", true);        if (!BlackNumStatus) {            return;        }        BlackNumberDBOperation operation = new BlackNumberDBOperation(context);        if (!intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {            String mIncomingNumber = "";            /**来电**/            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);            switch (telephonyManager.getCallState()) {                case TelephonyManager.CALL_STATE_RINGING:                    mIncomingNumber = intent.getStringExtra("incoming_number");                    int blackContactMode = operation.getBlackContactMode(mIncomingNumber);                    /**这里的Opration是一个实体类的操作类,用户与查询黑名单是都存在,并返回拦截模式**/                    if (blackContactMode == 1 || blackContactMode == 3) {                        /**                         * 观察呼叫记录(其他的应用程序,像是手机通讯录程序)的变化                         * 如果生成了呼叫记录,就把呼叫记录删除掉                         */                        Uri uri = Uri.parse("content://call_log/calls");                        context.getContentResolver().registerContentObserver(uri, true, new CallLogObserver(new Handler(), mIncomingNumber, context));                        endCall(context);                    }                    break;            }        }    }    private class CallLogObserver extends ContentObserver {        /**         * Creates a content observer.         *         * @param handler The handler to run {@link #onChange} on, or null if none.         */        private String incomingNumber;        private Context context;        public CallLogObserver(Handler handler, String incomingNumber, Context context) {            super(handler);            this.incomingNumber = incomingNumber;            this.context = context;        }        @Override        public void onChange(boolean selfChange) {            super.onChange(selfChange);            Log.d(TAG, "呼叫数据库的内容变化了");            context.getContentResolver().unregisterContentObserver(this);            deleteCallLog(incomingNumber, context);        }    }    /**     * 清除呼叫记录     * @param incomingNumber     * @param context     */    public void deleteCallLog(String incomingNumber, Context context) {        ContentResolver resolver = context.getContentResolver();        Uri uri = Uri.parse("content://call_log/calls");        Cursor cursor = resolver                .query(uri,                        new String[]{"_id"}, "number=?",                        new String[]{incomingNumber}, "_id desc limit 1");        if (cursor.moveToNext()) {            String id = cursor.getString(0);            resolver.delete(uri, "_id", new String[]{id});        }    }    /**     * 挂断电话需要复制两个AIDL(利用反射)     */    public void endCall(Context context){        try {            Class clazz=context.getClassLoader().loadClass("android.os.Service Manager");            Method method=clazz.getDeclaredMethod("getService",String.class);            IBinder iBinder = (IBinder) method.invoke(null,Context.TELEPHONY_SERVICE);            ITelephony itelephony = ITelephony.Stub.asInterface(iBinder);            itelephony.endCall();              } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }    }}

最后,需要讲的是程序挂断电话,需要通过反射得到ITelephony接口。

需要将android源码中的两个AIDL复制到程序目录中。

一个是ITelephony.aidl,需要建立一个与其包名一致的包com.android.internal.telephony(在src下建立的是com/android/internal/telephony),然后将其复制到包下

还有一个则是与ITelephony关联的AIDL文件,NeighboringCellInfo.aidl,它所在的包是android.telephony,如上方法创建

两个AIDL文件的下载路径:http://pan.baidu.com/s/1pLrh9VX

密码:y4fw


0 0
原创粉丝点击