当前位置: 首页 > 知识库问答 >
问题:

Android2.3.x如何拦截来电

慕宏峻
2023-03-14
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;
}
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();
}

这篇文章:

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)

共有1个答案

东方海
2023-03-14

它在Gingerbread 2.3.x中不起作用的原因是15031问题和15872问题谷歌改变了围绕电话权限的框架,这让开发人员非常恼火。虽然不能保证,但一些手机制造商保留了许可权(索尼就是其中之一!),另一些制造商则从谷歌的AOSP中删除了代码,并根据自己的制造过程建立了自己的变体,并保留了修改后的框架许可权。

简单地说,另一种选择是让手机扎根,在电话套接字层上创建一个MITM,并在Android堆栈看到事件之前进行拦截...但从表面上看,它太复杂了,不值得做。

现在ICS已经出来了,权限仍然没有改变,所以这是需要记住的。与此同时,随着谷歌的前进,GB资源被留在尘土中,尽管15031问题页面上“请修复这个”,但几乎无能为力...

 类似资料:
  • 我想为我的Android手机写一个软件,拦截来电,并播放一个简短的音频剪辑,指示来电者按“1”继续通话。这是打电话推销员的。 备注: > 很难得到一个明确的答案,因为在2012年,Android2.3(姜饼)删除了一些与修改手机状态相关的重要API,见这里。然而,Android7(“牛轧糖”)似乎支持呼叫阻塞(见这里),所以我希望当前的API支持拦截呼叫。 我不想像这里建议的那样将呼叫转发到某个服

  • null 任何帮助都是欢迎的,谢谢。

  • 更新:“提醒我”和“消息”按钮不再出现在iOS 10.1上

  • 拦截文件 bp CreateFileA 创建或打开文件 (32位) bp OpenFile 打开文件 (32位) bp ReadFile 读文件 (32位) bp WriteFile 写文件 (32位) bp GetPrivateProfileStringA (ini文件)

  • 拦截时间 bp GetLocalTime 获取本地时间 bp GetSystemTime 获取系统时间 bp GetFileTime 获取文件时间 bp GetTickCount 获得自系统成功启动以来所经历的毫秒数 bp GetCurrentTime 获取当前时间(16位) bp SetTimer 创建定时器 bp TimerProc 定时器超时回调函数

  • 拦截窗口 bp CreateWindow 创建窗口 bp CreateWindowEx(A) 创建窗口 bp ShowWindow 显示窗口 bp UpdateWindow 更新窗口 bp GetWindowText(A) 获取窗口文本