2011-03-16 151 views
4

我有一些代码,当有人打电话时,应该立即接听电话并立即挂断电话。当来自不同电话的呼叫进入时,我不会出现任何错误,也无法关闭。问题是它没有做它应该做的事。如何接听电话并挂断电话?

这是广播:

package com.QuickCallBlocking; 

import java.lang.reflect.Method; 


import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.os.Bundle; 
import android.telephony.TelephonyManager; 

import com.android.internal.telephony.ITelephony; 

public abstract class CallBlock extends BroadcastReceiver { 
    private Context context; 
    private ITelephony telephonyService; 

    /** Called when the activity is first created. */ 
    public void getTeleService() { 
     TelephonyManager tm = (TelephonyManager) context 
     getSystemService(Context.TELEPHONY_SERVICE); 

     try { 
      // Java reflection to gain access to TelephonyManager's 
      // ITelephony getter 

      Class c = Class.forName(tm.getClass().getName()); 
      Method m = c.getDeclaredMethod("getITelephony"); 
      m.setAccessible(true); 
      com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     telephonyService.endCall(); 
    } 

    String[] blockedNumbers = {"+911234567")}; 
    String incommingNumber; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     Bundle b = intent.getExtras(); 
     incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 
     // Additional Step 
     // Check whether this number matches with your defined Block List 
     // If yes, Reject the Call 
    }  
} 

这是com.android.internal.telephony.ITelephony

/* 
* 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} 
*/ 
public 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(); 

    /** 
    * Check if the SIM FDN lock is enabled. 
    * @return true if the SIM FDN lock is enabled. 
    */ 
    boolean isSimFDNEnabled(); 

    /** 
    * 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); 

    /** 
    * 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 supplyPuk(String pin, String newPin); 

    /** 
    * Supply a pin2 to unlock the SIM. Blocks until a result is determined. 
    * @param pin The pin2 to check. 
    * @return whether the operation was a success. 
    */ 
    boolean supplyPin2(String pin2); 

    /** 
    * Check MS-ISDN field in SIM. 
    * @param 
    * @return whether there is MS-ISDN field in SIM. 
    */ 

    boolean getMsisdnavailable(); 
    /** 
    * 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(); 

    /** 
    * Returns the current active phone type as integer. 
    * Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE 
    * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE 
    */ 
    int getActivePhoneType(); 

    /** 
    * Returns the CDMA ERI icon index to display 
    */ 
    int getCdmaEriIconIndex(); 

    /** 
    * Returns the CDMA ERI icon mode, 
    * 0 - ON 
    * 1 - FLASHING 
    */ 
    int getCdmaEriIconMode(); 

    /** 
    * Returns the CDMA ERI text, 
    */ 
    String getCdmaEriText(); 

    /** 
    * Returns true if CDMA provisioning needs to run. 
    */ 
    boolean getCdmaNeedsProvisioning(); 

    /** 
     * Returns the unread count of voicemails 
     */ 
    int getVoiceMessageCount(); 

    /** 
     * Returns the network type 
     */ 
    int getNetworkType(); 

    /** 
    * Return true if an ICC card is present 
    */ 
    boolean hasIccCard(); 

    //[ TelephonyFeature.CONFIG_FAKECALL_FEATURE 
    void initiateFakecall(); 
    //] 

    /** 
    * Returns the Value of PIN remain retry number. 
    */ 
    int getSimPinRetry(); 

    /** 
    * Returns the Value of PUK remain retry number. 
    */ 
    int getSimPukRetry(); 

    /** 
    * Switch Holding and Active 
    */ 
    void switchHoldingAndActive(); 

    /** 
    * Make call mute or unmute 
    */ 
    void setMute(boolean flag); 

    /** 
    * Return mute state 
    */ 
    boolean getMute(); 

    /** 
    * Make speaker call on or off 
    */ 
    void turnOnSpeaker(boolean flag); 

    /** 
    * Return Active calls count. 
    */ 
    int getActiveCallsCount(); 

    /** 
    * Return Hold calls count. 
    */ 
    int getHoldCallsCount(); 

    /** 
    * Return Caller name 
    * First active call has priority 
    */ 
    String getCallerName(); 

    /** 
    * Return Call time 
    * First active call has priority 
    */ 
    long getCallTime(); 

    /** 
    * Return Call base time 
    * First active call has priority 
    */ 
    long getCallBaseTime(); 

    /** 
    * Return TRUE, if current call is video call 
    * First active call has priority 
    */ 
    boolean isVideoCall(); 

    // [TelephonyFeature.CONFIG_MULTIPLE_PDP_FEATURE 
    boolean getDataStatebyApnType(String ApnType); 
    // ] 
    } 

PS这是从该网站另外一个人的工作:Prasanta's Blog

+0

你想拒绝**全部**电话或只是那些匹配被阻止的电话号码? – 2011-11-10 12:57:03

回答

6

你想,我不认为在中做telephonyService.endCall()。您可能想在onReceive方法中调用该方法。

我不确定您是要拒绝所有来电还是仅拒绝来自特定号码的来电。如果你想只拒绝某些数字,它看起来像你没有任何代码在这里取回后,要检查的阻塞的号码来电的号码:

public void onReceive(Context context, Intent intent) { 
    Bundle b = intent.getExtras(); 
    incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 
--->// Additional Step              <--- 
--->// Check whether this number matches with your defined Block List  <--- 
--->// If yes, Reject the Call            <--- 
} 

你可以尝试将其更改为如果你想检查的数量和拒绝仅从阻塞号码的来电以下:

public void onReceive(Context context, Intent intent) { 
    Bundle b = intent.getExtras(); 
    incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 

    // Additional Step 
    // Check whether this number matches with your defined Block List 
    // If yes, Reject the Call 
    for (int i=0; i<blockedNumbers.length; i++) { 
     if (incommingNumber.equals(blockedNumbers[i])) { 
      telephonyService.endCall(); 
      break; 
     } 
    } 
} 

或者,如果你只是想拒绝所有的来电,这是更简单:

public void onReceive(Context context, Intent intent) { 
    telephonyService.endCall(); 
} 
0

添加以下代码AndroidManifest.xml中

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.CALL_PHONE"/> (add it after READ_PHONE_STATE and before MODIFY_PHONE_STATE") 
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> 

,并用它来结束呼叫:

private void endCall() 
    { 
      Class<TelephonyManager> c = TelephonyManager.class; 
      Method getITelephonyMethod = null; 
      try { 

      getITelephonyMethod = c.getDeclaredMethod("getITelephony",(Class[]) null); 


      getITelephonyMethod.setAccessible(true); 
      ITelephony iTelephony = (ITelephony) getITelephonyMethod.invoke(tm, (Object[]) null); 
      iTelephony.endCall(); 

     } catch (Exception e) { 

     } 
} 
+2

是不是MODIFY_PHONE_STATE保留由谷歌? – 2012-12-21 20:15:43

+0

是的,我相信在android 2.3版本之后不允许使用MODIFY_PHONE_STATE。 – Tastybrownies 2014-12-18 00:49:22

1

呀,不能只用

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

,因为它是由保留系统,所以为了接听电话,我们使用像here这样的蓝牙技巧,并且为了拒绝来电,我们仍然可以使用TelephonyManager的endCall();功能。它实际上没有这样的许可。不要忘记添加

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

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

,但!干杯...

+0

这不适合我。三星S4,运行5.0.1 – SysHex 2015-10-08 12:07:43