如何拦截来电的Andr​​oid

如何拦截来电的Andr​​oid

本文介绍了如何拦截来电的Andr​​oid 2.3.x的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以拦截接听和拨打电话。我的问题是,它不能在版本2.3.x工作

我在这里的code:

 公共类PhoneCallReceiver扩展的BroadcastReceiver {

/ **
 *回拨这触发了的时候,手机改变状态。
 * /
@覆盖
公共无效的onReceive(上下文的背景下,意图意图){


    //去做
    // ===========
    //这里我需要CHACK数

    //叠B = intent.getExtras();
    //字符串incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
    //附加步骤
    //检查这个数字是否与你定义的阻止列表匹配
    //如果是的话,拒绝呼叫
    // ===========


    / *检查导致该接收机火关了手机的状态* /
    字符串phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
    如果(phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING))
    {
        //如果(context.getShared preferences(HC。preFSNAME,0).getBoolean(HC。preF_CALL_ANSWER_TOOLS_KEY,真))
        // {
        logMe(电话铃声:手机铃声响起,调度创建呼叫应答屏幕活动);
        意图I =新的意图(背景下,CallAnswerIntentService.class);
        i.putExtra(延迟,100升);
        context.startService(ⅰ);
        logMe(电话铃声:开始,时间回去听);
        //                    } 其他 {
        // logMe(电话铃声:由用户禁用呼叫应答工具);
        //}
    }
    如果(phone_state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
    {
        //如果(context.getShared preferences(HC。preFSNAME,0).getBoolean(HC。preF_SCREEN_GUARD_TOOLS_KEY,真))
        // {

        //去做
        意图I =新的意图(背景下,InCallScreenGuardService.class);
        i.putExtra(延迟,100升);
        logMe(电话摘机:在启动屏幕保护服务);
        context.startService(ⅰ);
        //                    } 其他 {
        // logMe(电话摘机:在呼叫屏幕保护禁用用户);
        //}
    }
    如果(phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE))
    {
        //如果(context.getShared preferences(HC。preFSNAME,0).getBoolean(HC。preF_SCREEN_GUARD_TOOLS_KEY,真))
        // {
        //去做
        意图I =新的意图(背景下,InCallScreenGuardService.class);
        logMe(电话空闲:停止贴膜服务);
        context.stopService(ⅰ);
        //                    } 其他 {
        // logMe(电话空闲:在呼叫屏幕保护禁用用户);
        //}
    }

    返回;
}
 

这送交意愿提高服务质量与SERVIC发送意图以下活动:

 公共类CallAnswerActivity延伸活动{
/ **
 *是否使用AIDL技术或
 *在HEADSET_HOOK /包重新启动技术
 * /
私有静态最终布尔USE_ITELEPHONY = TRUE;

/ **
 *手机内部状态广播接收器
 * /
受保护的BroadcastReceiverř;

/ **
 *使用本次活动TelephonyManager实例
 * /
私人TelephonyManager TM;

/ **
 * AIDL接入电话业务流程
 * /
私人com.android.internal.telephony.ITelephony telephonyService;

// ------------------------------------------------ ------------------------
//主生命周期回调
// ------------------------------------------------ ------------------------

/ **
 * 主要() :)
 * /
@覆盖保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    DEBUGLOG(的onCreate称为);
    的setContentView(R.layout.callanswerscreen);

    //取得电话管理器的实例
    TM =(TelephonyManager)getSystemService(TELEPHONY_SERVICE);

    //连接到底层的Andr​​oid电话系统
    如果(USE_ITELEPHONY)
        connectToTelephonyService();

    //把我们的闲置手机状态接收器
    registerReciever();



    //触摸屏返回按钮
    按钮returnToCallScreen =(按钮)findViewById(R.id.returnToCallScreen);
    returnToCallScreen.setOnClickListener(新ReturnButtonOnClickListener());

    //触摸屏拒绝/忽略呼叫按钮
    按钮rejectCall =(按钮)findViewById(R.id.rejectCallButton);
    如果//(getShared preferences(HC。preFSNAME,0).getBoolean(HC。preF_ALLOW_REJECT_KEY,真))
    rejectCall.setOnLongClickListener(新RejectCallOnLongClickListener());
    //            其他
    // rejectCall.setVisibility(View.GONE);

    //触摸屏接听按钮
    按钮answerButton =(按钮)findViewById(R.id.answerCallButton);
    如果//(getShared preferences(HC。preFSNAME,0).getBoolean(HC。preF_ANSWER_WITH_BUTTON_KEY,真))
    answerButton.setOnLongClickListener(新AnswerCallOnLongClickListener());
    //            其他
    // answerButton.setVisibility(View.GONE);
}

/ **
 *(重新)注册手机状态接收器上的简历,退出如果手机处于闲置状态
 * /
@覆盖保护无效onResume(){
    super.onResume();

    registerReciever();

    如果(tm.getCallState()== TelephonyManager.CALL_STATE_IDLE){
        DEBUGLOG(电话处于空闲状态,停止。);
        exitCleanly();
    }
}

/ **
 *注销手机状态接收器,定时重启,如果不退出,在用户请求
 * /
@覆盖保护无效的onPause(){
    super.onPause();

    unHookReceiver();

    如果(!isFinishing())
    {
        DEBUGLOG(制度被迫暂停发生,调度延迟重启);
        意图I =新的意图(getApplicationContext(),CallAnswerIntentService.class);
        i.putExtra(延迟,Hc.RESTART_DELAY);
        startService(ⅰ);
    }
}

// ------------------------------------------------ ------------------------
//输入事件处理程序回调
// ------------------------------------------------ ------------------------

/ **
 *轨迹球preSS事件处理程序,将接听电话
 * /
@覆盖公共布尔onTrackballEvent(MotionEvent事件){

    开关(event.getAction())
    {
    案例MotionEvent.ACTION_MOVE:返回true;
    案MotionEvent.ACTION_DOWN:answerCall();返回true;
    默认:DEBUGLOG(轨迹球事件:+活动);
    }
    返回super.dispatchTrackballEvent(事件);
}

/ **
 *相机按钮preSS事件处理程序,将接听电话
 * /
@覆盖公共布尔dispatchKeyEvent(KeyEvent的事件){

    开关(event.getKey code())
    {
    案例KeyEvent.KEY code_FOCUS:返回true;
    案例KeyEvent.KEY code_CAMERA:answerCall();返回true;
    默认:DEBUGLOG(未知关键事件:+活动);
    }
    返回super.dispatchKeyEvent(事件);
}

/ **
 *返回按钮点击监听器会退出回
 *手机股票回答呼叫应用。
 * /
私有类ReturnButtonOnClickListener实现OnClickListener {
    公共无效的onClick(视图v){
        DEBUGLOG(returnToCallScreen onClick事件);
        exitCleanly();
    }
}

/ **
 *拒绝按钮,长按监听器会拒绝
 *来电。
 * /
私有类RejectCallOnLongClickListener实现OnLongClickListener {
    公共布尔onLongClick(视图v){
        DEBUGLOG(触摸屏忽略呼叫按钮onClick事件);
        ignoreCall();
        exitCleanly();
        返回true;
    }
}

/ **
 *应答键长按监听器会回答
 *来电。
 * /
私有类AnswerCallOnLongClickListener实现OnLongClickListener {
    公共布尔onLongClick(视图v){
        DEBUGLOG(触摸屏接听按钮onClick事件);
        answerCall();
        返回true;
    }
}

// ------------------------------------------------ ------------------------
//广播接收机
// ------------------------------------------------ ------------------------

/ **
 *登记手机状态接收器
 * /
私人无效registerReciever(){
    如果(R!= NULL)回报;

    R =新的BroadcastReceiver(){
        @覆盖
        公共无效的onReceive(上下文C,意图我){
            字符串phone_state = i.getStringExtra(TelephonyManager.EXTRA_STATE);
            如果(!phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING))
            {
                DEBUGLOG(获得+ phone_state +,时间去拜拜,感谢您的参与!);
                        exitCleanly();
            }
        }
    };

    registerReceiver(R,新的IntentFilter(android.intent.action.PHONE_STATE));
}

/ **
 *注销手机状态接收器
 * /
私人无效unHookReceiver(){
    如果(R!= NULL)
    {
        unregisterReceiver(r)的;
        R = NULL;
    }
}

// ------------------------------------------------ ------------------------
//应用方法
// ------------------------------------------------ ------------------------

/ **
 *得到ITelephony的一个实例说说手柄通话与
 * /
@燮pressWarnings(未登记)私人无效connectToTelephonyService(){
    尝试
    {
        //骗与Java反射来访问TelephonyManager的ITelephony吸
        C类=的Class.forName(tm.getClass()的getName());
        方法米= c.getDeclaredMethod(getITelephony);
        m.setAccessible(真正的);
          telephonyService =(com.android.internal.telephony.ITelephony)m.invoke(商标);
    }赶上(例外五){
        e.printStackTrace();
        DEBUGLOG(致命错误:无法连接到电话子系统);
        DEBUGLOG(异常物体+ E);
        完();
    }
}

//
//应答呼叫
//

/ **
 *接听来电
 * /
私人无效answerCall(){
    如果(USE_ITELEPHONY)
        尝试 {
            answerCallAidl();
        }赶上(RemoteException的E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }
    其他
        answerCallHeadsetHook();

    exitCleanly();
}

/ **
 * ACTION_MEDIA_BUTTON接听手机广播技术
 * /
私人无效answerCallHeadsetHook(){
    KeyEvent的headsetHook =新的KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEY code_HEADSETHOOK);
    意图mediaButtonIntent =新的意图(Intent.ACTION_MEDIA_BUTTON);
    mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT,headsetHook);
    sendOrderedBroadcast(mediaButtonIntent,NULL);
}

/ **
 * AIDL / ITelephony技术接听电话
 * /
私人无效answerCallAidl()将抛出RemoteException {
    telephonyService.silenceRinger();
    telephonyService.answerRingingCall();
}

//
//忽略呼叫
//

/ **
 *忽略来电
 * /
私人无效ignoreCall(){
    如果(USE_ITELEPHONY)
        尝试 {
            ignoreCallAidl();
        }赶上(RemoteException的E){
            // TODO自动生成的catch块
            e.printStackTrace();
        }
    其他
        ignoreCallPackageRestart();
}

/ **
 *无视话费套餐重启技术
 * /
私人无效ignoreCallPackageRestart(){
    ActivityManager AM =(ActivityManager)getSystemService(ACTIVITY_SERVICE);
    am.restartPackage(com.android.providers.telephony);
    am.restartPackage(com.android.phone);
}

/ **
 * AIDL / ITelephony技术忽略呼叫
 * /
私人无效ignoreCallAidl()将抛出RemoteException {
    telephonyService.silenceRinger();
    telephonyService.endCall();
}

/ **
 *清理和退出程序
 * /
私人无效exitCleanly(){
    unHookReceiver();
    moveTaskToBack(真正的);
    完();
}
 

我需要帮助,使其在2.3
工作谢谢

此产生的异常:

  java.lang.SecurityException异常:无论是用户还是10156当前进程android.permission.MODIFY_PHONE_STATE。
在android.os.Parcel.readException(Parcel.java:1322)
在android.os.Parcel.readException(Parcel.java:1276)
在com.android.internal.telephony.ITelephony $存根$ Proxy.silenceRinger(ITelephony.java:1231)
在com.y_y_full.photo_dailer.CallAnswerActivity.answerCallAidl(CallAnswerActivity.java:281)
在com.y_y_full.photo_dailer.CallAnswerActivity.answerCall(CallAnswerActivity.java:256)
在com.y_y_full.photo_dailer.CallAnswerActivity.access $ 3(CallAnswerActivity.java:253)
在com.y_y_full.photo_dailer.CallAnswerActivity$AnswerCallOnLongClickListener.onLongClick(CallAnswerActivity.java:181)
在android.view.View.performLongClick(View.java:2556)
在android.widget.TextView.performLongClick(TextView.java:8358)
在android.view.View $ CheckForLong press.run(View.java:9128)
在android.os.Handler.handleCallback(Handler.java:587)
在android.os.Handler.dispatchMessage(Handler.java:92)
在android.os.Looper.loop(Looper.java:130)
在android.app.ActivityThread.main(ActivityThread.java:3691)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:507)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:907)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
在dalvik.system.NativeStart.main(本机方法)
 

解决方案

它不能在姜饼2.3.x工作的原因是<一个href="http://$c$c.google.com/p/android/issues/detail?can=1&q=audio%20redirect%20https&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&id=15031"相对=nofollow>这个15031的问题和<一href="http://$c$c.google.com/p/android/issues/detail?can=1&q=15872&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars&id=15872"相对=nofollow> 15872问题谷歌改变了周围的权限电话的框架,这让开发者的烦恼。虽然不能保证,一些手机厂商留许可的地方(索尼是一个想到!),其他人拉下code,从谷歌的AOSP并建有自己的变种相应地其制造过程中,随着改变框架允许的地方。

简单地说,另一种方法是有根的手机并创建电话插座层上的中间人,做拦截之前的Andr​​oid栈曾经看到的事件......但在它的面前,它太复杂,不值得做的事情。

现在,ICS是出来了,并且允许仍保持不变,这样的东西要牢记。同时GB源是留给收集灰尘如谷歌前进,很少能尽管做请解决这个问题,在15031发行...

I can intercept incoming and outgoing calls. My problem is that it does not work in version 2.3.x

here my code:

public class PhoneCallReceiver extends BroadcastReceiver {

/**
 * Call back which fires off when the phone changes state.
 */
@Override
public void onReceive(Context context, Intent intent) {


    //TODO
    //===========
    //here i need to chack the number

    //      Bundle b = intent.getExtras();
    //      String incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
    // Additional Step
    // Check whether this number matches with your defined Block List
    // If yes, Reject the Call
    //===========


    /* examine the state of the phone that caused this receiver to fire off */
    String phone_state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING))
    {
        //                    if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_CALL_ANSWER_TOOLS_KEY, true))
        //                    {
        logMe("Phone Ringing: the phone is ringing, scheduling creation call answer screen activity");
        Intent i = new Intent(context, CallAnswerIntentService.class);
        i.putExtra("delay", 100L);
        context.startService(i);
        logMe("Phone Ringing: started, time to go back to listening");
        //                    } else {
        //                            logMe("Phone Ringing: Call Answer tools disabled by user");
        //                    }
    }
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK))
    {
        //                    if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_SCREEN_GUARD_TOOLS_KEY, true))
        //                    {

        //TODO
        Intent i = new Intent(context,InCallScreenGuardService.class);
        i.putExtra("delay", 100L);
        logMe("Phone Offhook: starting screen guard service");
        context.startService(i);
        //                    } else {
        //                            logMe("Phone Offhook: In-Call Screen Guard disabled by user");
        //                    }
    }
    if (phone_state.equals(TelephonyManager.EXTRA_STATE_IDLE))
    {
        //                    if (context.getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_SCREEN_GUARD_TOOLS_KEY, true))
        //                    {
        //TODO
        Intent i = new Intent(context,InCallScreenGuardService.class);
        logMe("Phone Idle: stopping screen guard service");
        context.stopService(i);
        //                    } else {
        //                            logMe("Phone Idle: In-Call Screen Guard disabled by user");
        //                    }
    }

    return;
}

this send intent to service and servic send intent to the following activity:

public class CallAnswerActivity extends Activity {
/**
 * whether or not to use the AIDL technique or
 * the HEADSET_HOOK/package restart techniques
 */
private static final boolean USE_ITELEPHONY = true;

/**
 * internal phone state broadcast receiver
 */
protected BroadcastReceiver r;

/**
 * TelephonyManager instance used by this activity
 */
private TelephonyManager tm;

/**
 * AIDL access to the telephony service process
 */
private com.android.internal.telephony.ITelephony telephonyService;

// ------------------------------------------------------------------------
// primary life cycle call backs
// ------------------------------------------------------------------------

/**
 * main() :)
 */
@Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    debugLog("onCreate called");
    setContentView(R.layout.callanswerscreen);

    // grab an instance of telephony manager
    tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);

    // connect to the underlying Android telephony system
    if (USE_ITELEPHONY)
        connectToTelephonyService();

    // turn our idle phone state receiver on
    registerReciever();



    // touch screen return button
    Button returnToCallScreen = (Button) findViewById(R.id.returnToCallScreen);
    returnToCallScreen.setOnClickListener(new ReturnButtonOnClickListener());

    // touch screen reject/ignore call button
    Button rejectCall = (Button) findViewById(R.id.rejectCallButton);
    //            if (getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_ALLOW_REJECT_KEY, true))
    rejectCall.setOnLongClickListener(new RejectCallOnLongClickListener());
    //            else
    //                    rejectCall.setVisibility(View.GONE);

    // touch screen answer button
    Button answerButton = (Button) findViewById(R.id.answerCallButton);
    //            if (getSharedPreferences(Hc.PREFSNAME,0).getBoolean(Hc.PREF_ANSWER_WITH_BUTTON_KEY, true))
    answerButton.setOnLongClickListener(new AnswerCallOnLongClickListener());
    //            else
    //                    answerButton.setVisibility(View.GONE);
}

/**
 * (re)register phone state receiver on resume, exit if the phone is idle
 */
@Override protected void onResume() {
    super.onResume();

    registerReciever();

    if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
        debugLog("phone is idle, stopping.");
        exitCleanly();
    }
}

/**
 * unregister phone state receiver, schedule restart if not exiting at the users request
 */
@Override protected void onPause() {
    super.onPause();

    unHookReceiver();

    if (!isFinishing())
    {
        debugLog("system forced pause occured, scheduling delayed restart");
        Intent i = new Intent(getApplicationContext(), CallAnswerIntentService.class);
        i.putExtra("delay", Hc.RESTART_DELAY);
        startService(i);
    }
}

// ------------------------------------------------------------------------
// Input event handler call backs
// ------------------------------------------------------------------------

/**
 * Track ball press event handler that will answer a call
 */
@Override public boolean onTrackballEvent(MotionEvent event) {

    switch(event.getAction())
    {
    case MotionEvent.ACTION_MOVE: return true;
    case MotionEvent.ACTION_DOWN: answerCall(); return true;
    default: debugLog("trackball event: "+event);
    }
    return super.dispatchTrackballEvent(event);
}

/**
 * Camera button press event handler that will answer a call
 */
@Override public boolean dispatchKeyEvent(KeyEvent event) {

    switch (event.getKeyCode())
    {
    case KeyEvent.KEYCODE_FOCUS: return true;
    case KeyEvent.KEYCODE_CAMERA: answerCall(); return true;
    default: debugLog("Unknown key event: "+event);
    }
    return super.dispatchKeyEvent(event);
}

/**
 * Return button click listener will exit back to the
 * phones stock answer call application.
 */
private class ReturnButtonOnClickListener implements OnClickListener {
    public void onClick(View v) {
        debugLog("returnToCallScreen onClick event");
        exitCleanly();
    }
}

/**
 * Reject button long click listener will reject the
 * incoming call.
 */
private class RejectCallOnLongClickListener implements OnLongClickListener {
    public boolean onLongClick(View v){
        debugLog("touch screen ignore call button onClick event");
        ignoreCall();
        exitCleanly();
        return true;
    }
}

/**
 * Answer button long click listener will answer the
 * incoming call.
 */
private class AnswerCallOnLongClickListener implements OnLongClickListener {
    public boolean onLongClick(View v){
        debugLog("touch screen answer button onClick event");
        answerCall();
        return true;
    }
}

// ------------------------------------------------------------------------
// broadcast receivers
// ------------------------------------------------------------------------

/**
 * register phone state receiver
 */
private void registerReciever() {
    if (r != null) return;

    r = new BroadcastReceiver() {
        @Override
        public void onReceive(Context c, Intent i)      {
            String phone_state = i.getStringExtra(TelephonyManager.EXTRA_STATE);
            if (!phone_state.equals(TelephonyManager.EXTRA_STATE_RINGING))
            {
                debugLog("received "+phone_state+", time to go bye bye, thanks for playing!");
                        exitCleanly();
            }
        }
    };

    registerReceiver(r, new IntentFilter("android.intent.action.PHONE_STATE"));
}

/**
 * unregister phone state receiver
 */
private void unHookReceiver() {
    if (r != null)
    {
        unregisterReceiver(r);
        r = null;
    }
}

// ------------------------------------------------------------------------
// application methods
// ------------------------------------------------------------------------

/**
 * get an instance of ITelephony to talk handle calls with
 */
@SuppressWarnings("unchecked") private void connectToTelephonyService() {
    try
    {
        // "cheat" with 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);
          telephonyService = (com.android.internal.telephony.ITelephony) m.invoke(tm);
    } catch (Exception e) {
        e.printStackTrace();
        debugLog("FATAL ERROR: could not connect to telephony subsystem");
        debugLog("Exception object: "+e);
        finish();
    }
}

//
// answer call
//

/**
 * answer incoming calls
 */
private void answerCall() {
    if (USE_ITELEPHONY)
        try {
            answerCallAidl();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    else
        answerCallHeadsetHook();

    exitCleanly();
}

/**
 * ACTION_MEDIA_BUTTON broadcast technique for answering the phone
 */
private void answerCallHeadsetHook() {
    KeyEvent headsetHook =  new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.KEYCODE_HEADSETHOOK);
    Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
    mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, headsetHook);
    sendOrderedBroadcast(mediaButtonIntent, null);
}

/**
 * AIDL/ITelephony technique for answering the phone
 */
private void answerCallAidl() throws RemoteException {
    telephonyService.silenceRinger();
    telephonyService.answerRingingCall();
}

//
// ignore call
//

/**
 * ignore incoming calls
 */
private void ignoreCall() {
    if (USE_ITELEPHONY)
        try {
            ignoreCallAidl();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    else
        ignoreCallPackageRestart();
}

/**
 * package restart technique for ignoring calls
 */
private void ignoreCallPackageRestart() {
    ActivityManager am = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
    am.restartPackage("com.android.providers.telephony");
    am.restartPackage("com.android.phone");
}

/**
 * AIDL/ITelephony technique for ignoring calls
 */
private void ignoreCallAidl() throws RemoteException {
    telephonyService.silenceRinger();
    telephonyService.endCall();
}

/**
 * cleanup and exit routine
 */
private void exitCleanly() {
    unHookReceiver();
    moveTaskToBack(true);
    finish();
}

I need help to make it work on 2.3
thanks

this exeptions:

java.lang.SecurityException: Neither user 10156 nor current process has android.permission.MODIFY_PHONE_STATE.
at android.os.Parcel.readException(Parcel.java:1322)
at android.os.Parcel.readException(Parcel.java:1276)
at com.android.internal.telephony.ITelephony$Stub$Proxy.silenceRinger(ITelephony.java:1231)
at com.y_y_full.photo_dailer.CallAnswerActivity.answerCallAidl(CallAnswerActivity.java:281)
at com.y_y_full.photo_dailer.CallAnswerActivity.answerCall(CallAnswerActivity.java:256)
at com.y_y_full.photo_dailer.CallAnswerActivity.access$3(CallAnswerActivity.java:253)
at com.y_y_full.photo_dailer.CallAnswerActivity$AnswerCallOnLongClickListener.onLongClick(CallAnswerActivity.java:181)
at android.view.View.performLongClick(View.java:2556)
at android.widget.TextView.performLongClick(TextView.java:8358)
at android.view.View$CheckForLongPress.run(View.java:9128)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
解决方案

The reason it does not work in Gingerbread 2.3.x is this 15031 issue, and 15872 issue Google changed the framework surrounding the permissions for the telephony, much to the annoyance of developers. Although it is not guaranteed, some phone makers leave the permission in place (Sony is one that comes to mind!), others have pulled down the code from Google's AOSP and built their own variants accordingly to their manufacture process, with the changed framework permission in place.

Simply put, the alternative is to have the handset rooted and create a MITM on the telephony socket layer and do the interception before the Android Stack ever sees the events... but on the face of it, its too complicated and not worth doing.

Now that ICS is out now, and the permission is still unchanged so that's something to bear in mind. Meanwhile GB source is left to gather dust as Google moves forward and very little can be done despite "Please fix this" in the 15031 issue page...

这篇关于如何拦截来电的Andr​​oid 2.3.x的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 17:09