用代码实现来电拦截

如果要进行来电拦截,首先要定义权限,然后写一个接收来电去电的广播。由于不同机型的问题,动态注册还是静态注册有待商榷,我这里用的是静态注册,模拟器测试通过。

一、申请权限

    <!-- 添加访问手机电话状态的权限 -->  

    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

    <!-- 拨打电话权限 -->

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

    <!-- 监听手机去电的权限 -->

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

 

二、注册广播

      <!-- 拨打电话触发的广播 -->

        <receiver android:name="com.kale.phoneblock.PhoneReceiver">

            <intent-filter android:priority="1000">

                <action android:name="android.intent.action.PHONE_STATE"/>

        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />

            </intent-filter>

        </receiver>

 

三、复制aidl文件

由于高版本的系统中没给出操作电话的api,所以我们要在src文件下新建连个包,放两个文件进去。重要的是ITelephony文件,上面那个文件似乎可以不管它。

用代码实现来电拦截

 

NeighboringCellInfo.aidl

/* //device/java/android/android/content/Intent.aidl

**

** Copyright 2007, The Android Open Source Project

**

** Licensed under the Apache License, Version 2.0 (the "License");

** you may not use this file except in compliance with the License.

** You may obtain a copy of the License at

**

**     http://www.apache.org/licenses/LICENSE-2.0

**

** Unless required by applicable law or agreed to in writing, software

** distributed under the License is distributed on an "AS IS" BASIS,

** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

** See the License for the specific language governing permissions and

** limitations under the License.

*/

 

package android.telephony;

 

parcelable NeighboringCellInfo;

ITelephony.aidl

用代码实现来电拦截
/*

* Copyright (C) 2007 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0 

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.android.internal.telephony;

import android.os.Bundle;

import java.util.List;

import android.telephony.NeighboringCellInfo;

/**

* Interface used to interact with the phone.  Mostly this is used by the 

* TelephonyManager class.  A few places are still using this directly.

* Please clean them up if possible and use TelephonyManager insteadl.

*

* {@hide}

*/

interface ITelephony {

    /**

     * Dial a number. This doesn't place the call. It displays

     * the Dialer screen.

     * @param number the number to be dialed. If null, this

     * would display the Dialer screen with no number pre-filled.

     */

    void dial(String number);

    /**

     * Place a call to the specified number.

     * @param number the number to be called.

     */

    void call(String number);

    /**

     * If there is currently a call in progress, show the call screen.

     * The DTMF dialpad may or may not be visible initially, depending on

     * whether it was up when the user last exited the InCallScreen.

     *

     * @return true if the call screen was shown.

     */

    boolean showCallScreen();

    /**

     * Variation of showCallScreen() that also specifies whether the

     * DTMF dialpad should be initially visible when the InCallScreen

     * comes up.

     *

     * @param showDialpad if true, make the dialpad visible initially,

     *                    otherwise hide the dialpad initially.

     * @return true if the call screen was shown.

     *

     * @see showCallScreen

     */

    boolean showCallScreenWithDialpad(boolean showDialpad);

    /**

     * End call or go to the Home screen

     *

     * @return whether it hung up

     */

    boolean endCall();

    /**

     * Answer the currently-ringing call.

     *

     * If there's already a current active call, that call will be

     * automatically put on hold.  If both lines are currently in use, the

     * current active call will be ended.

     *

     * TODO: provide a flag to let the caller specify what policy to use

     * if both lines are in use.  (The current behavior is hardwired to

     * "answer incoming, end ongoing", which is how the CALL button

     * is specced to behave.)

     *

     * TODO: this should be a oneway call (especially since it's called

     * directly from the key queue thread).

     */

    void answerRingingCall();

    /**

     * Silence the ringer if an incoming call is currently ringing.

     * (If vibrating, stop the vibrator also.)

     *

     * It's safe to call this if the ringer has already been silenced, or

     * even if there's no incoming call.  (If so, this method will do nothing.)

     *

     * TODO: this should be a oneway call too (see above).

     *       (Actually *all* the methods here that return void can

     *       probably be oneway.)

     */

    void silenceRinger();

    /**

     * Check if we are in either an active or holding call

     * @return true if the phone state is OFFHOOK.

     */

    boolean isOffhook();

    /**

     * Check if an incoming phone call is ringing or call waiting.

     * @return true if the phone state is RINGING.

     */

    boolean isRinging();

    /**

     * Check if the phone is idle.

     * @return true if the phone state is IDLE.

     */

    boolean isIdle();

    /**

     * Check to see if the radio is on or not.

     * @return returns true if the radio is on.

     */

    boolean isRadioOn();

    /**

     * Check if the SIM pin lock is enabled.

     * @return true if the SIM pin lock is enabled.

     */

    boolean isSimPinEnabled();

    /**

     * Cancels the missed calls notification.

     */

    void cancelMissedCallsNotification(); 

    /**

     * Supply a pin to unlock the SIM.  Blocks until a result is determined.

     * @param pin The pin to check.

     * @return whether the operation was a success.

     */

    boolean supplyPin(String pin);

    /**

     * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated

     * without SEND (so <code>dial</code> is not appropriate).

     * 

     * @param dialString the MMI command to be executed.

     * @return true if MMI command is executed.

     */

    boolean handlePinMmi(String dialString);

    /**

     * Toggles the radio on or off.

     */

    void toggleRadioOnOff();

    /**

     * Set the radio to on or off

     */

    boolean setRadio(boolean turnOn);

    /**

     * Request to update location information in service state

     */

    void updateServiceLocation();

    /**

     * Enable location update notifications.

     */

    void enableLocationUpdates();

    /**

     * Disable location update notifications.

     */

    void disableLocationUpdates();

    /**

     * Enable a specific APN type.

     */

    int enableApnType(String type);

    /**

     * Disable a specific APN type.

     */

    int disableApnType(String type);

    /**

     * Allow mobile data connections.

     */

    boolean enableDataConnectivity();

    /**

     * Disallow mobile data connections.

     */

    boolean disableDataConnectivity();

    /**

     * Report whether data connectivity is possible.

     */

    boolean isDataConnectivityPossible();

    Bundle getCellLocation();

    /**

     * Returns the neighboring cell information of the device.

     */

    List<NeighboringCellInfo> getNeighboringCellInfo();

     int getCallState();

     int getDataActivity();

     int getDataState();

}
View Code

 

四、编写广播接收类——PhoneReceiver

4.1 TelephonyManager

TelephonyManager是用来操作电话的控制器,通过它我们可以对来/去电来绑定监听器

@Override

    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {

            // 如果是去电(拨出)

        } else {

            TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);

            // 设置一个监听器

            tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);

        }

    }

 

4.2 处理监听事件

绑定监听器后我们就要根据监听到的不同的情况写不同的代码了

PhoneStateListener listener = new PhoneStateListener() {



        @Override

        public void onCallStateChanged(int state, String incomingNumber) {

            // state 当前状态 incomingNumber,貌似没有去电的API

            super.onCallStateChanged(state, incomingNumber);

            switch (state) {

            //手机空闲了

            case TelephonyManager.CALL_STATE_IDLE:

                break;

                //电话被挂起

            case TelephonyManager.CALL_STATE_OFFHOOK:

                break;

                // 当电话呼入时

            case TelephonyManager.CALL_STATE_RINGING:

                Log.e(TAG, "来电号码是:"+ incomingNumber);

                // 如果该号码属于黑名单

                if (incomingNumber.equals("123456")) {

                    // TODO:如果是黑名单,就进行屏蔽

                    stopCall();

                }

                break;

            }

        }

    };

 

4.3 挂断电话

public void stopCall() {



        try {

            Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);

            // 获取远程TELEPHONY_SERVICE的IBinder对象的代理

            IBinder binder = (IBinder) method.invoke(null, new Object[] { "phone" });

            // 将IBinder对象的代理转换为ITelephony对象

            ITelephony telephony = ITelephony.Stub.asInterface(binder);

            // 挂断电话

            telephony.endCall();

            telephony.cancelMissedCallsNotification();

        } catch (Exception e) {

        }



    }

 

4.4全部代码

package com.kale.phoneblock;



import java.lang.reflect.Method;



import android.app.Service;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.os.IBinder;

import android.telephony.PhoneStateListener;

import android.telephony.TelephonyManager;

import android.util.Log;



import com.android.internal.telephony.ITelephony;



public class PhoneReceiver extends BroadcastReceiver {

    String TAG = "PhoneReceiver";



    @Override

    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {

            // 如果是去电(拨出)

        } else {

            TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);

            // 设置一个监听器

            tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);

        }

    }

    

    PhoneStateListener listener = new PhoneStateListener() {



        @Override

        public void onCallStateChanged(int state, String incomingNumber) {

            // state 当前状态 incomingNumber,貌似没有去电的API

            super.onCallStateChanged(state, incomingNumber);

            switch (state) {

            //手机空闲了

            case TelephonyManager.CALL_STATE_IDLE:

                break;

                //电话被挂起

            case TelephonyManager.CALL_STATE_OFFHOOK:

                break;

                // 当电话呼入时

            case TelephonyManager.CALL_STATE_RINGING:

                Log.e(TAG, "来电号码是:"+ incomingNumber);

                // 如果该号码属于黑名单

                if (incomingNumber.equals("123456")) {

                    // TODO:如果是黑名单,就进行屏蔽

                    stopCall();

                }

                break;

            }

        }

    };



    public void stopCall() {



        try {

            Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);

            // 获取远程TELEPHONY_SERVICE的IBinder对象的代理

            IBinder binder = (IBinder) method.invoke(null, new Object[] { "phone" });

            // 将IBinder对象的代理转换为ITelephony对象

            ITelephony telephony = ITelephony.Stub.asInterface(binder);

            // 挂断电话

            telephony.endCall();

            telephony.cancelMissedCallsNotification();

        } catch (Exception e) {

        }



    }



}

 

五、运行效果

环境:2.2模拟器

接电话时会触发监听器,测试中会出现一次或多次触发监听器。对于要屏蔽的号码进行了完全的拦截,测试成功!

只触发一次的情况:

用代码实现来电拦截

多次触发的情况:

用代码实现来电拦截

 

 

源码下载:http://download.csdn.net/detail/shark0017/8371787

 

参考自:http://blog.csdn.net/wangfayinn/article/details/8004023

你可能感兴趣的:(代码)