Android如何检测是否接听拨出电话

时间:2017-01-12 06:34:51

标签: android reflection root

我正在开发一款只会在室内用于测试目的的应用。我已经搜索了很多并尝试了不同的建议,但是似乎没有任何建议对我有效。

我愿意接受任何建议,例如Reflections,Accessibility Service,root或任何其他hack。请帮忙。

此致

3 个答案:

答案 0 :(得分:1)

尝试

在manifest.xml文件中设置所有必需的权限。

在服务中调用此类

public class PhoneListener extends PhoneStateListener {

private static PhoneListener instance = null;

/**
 * Must be called once on app startup
 *
 * @param context - application context
 * @return
 */
public static PhoneListener getInstance(Context context) {
    if (instance == null) {
        instance = new PhoneListener(context);
    }
    return instance;
}

public static boolean hasInstance() {
    return null != instance;
}

private final Context context;
private CallLog phoneCall;

private PhoneListener(Context context) {
    this.context = context;
}

AtomicBoolean isRecording = new AtomicBoolean();
AtomicBoolean isWhitelisted = new AtomicBoolean();


/**
 * Set the outgoing phone number
 * <p/>
 * Called by {@link MyCallReceiver}  since that is where the phone number is available in a outgoing call
 *
 * @param phoneNumber
 */
public void setOutgoing(String phoneNumber) {
    if (null == phoneCall)
        phoneCall = new CallLog();
    phoneCall.setPhoneNumber(phoneNumber);
    phoneCall.setOutgoing();
    // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
    isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
}

@Override
public void onCallStateChanged(int state, String incomingNumber) {
    super.onCallStateChanged(state, incomingNumber);

    switch (state) {
        case TelephonyManager.CALL_STATE_IDLE: // Idle... no call
            if (isRecording.get()) {
                RecordCallService.stopRecording(context);
                phoneCall = null;
                isRecording.set(false);
            }
            break;
        case TelephonyManager.CALL_STATE_OFFHOOK: // Call answered
            if (isWhitelisted.get()) {
                isWhitelisted.set(false);
                return;
            }
            if (!isRecording.get()) {
                isRecording.set(true);
                // start: Probably not ever usefull
                if (null == phoneCall)
                    phoneCall = new CallLog();
                if (!incomingNumber.isEmpty()) {
                    phoneCall.setPhoneNumber(incomingNumber);
                }
                // end: Probably not ever usefull
                RecordCallService.sartRecording(context, phoneCall);
            }
            break;
        case TelephonyManager.CALL_STATE_RINGING: // Phone ringing
            // DO NOT try RECORDING here! Leads to VERY poor quality recordings
            // I think something is not fully settled with the Incoming phone call when we get CALL_STATE_RINGING
            // a "SystemClock.sleep(1000);" in the code will allow the incoming call to stabilize and produce a good recording...(as proof of above)
            if (null == phoneCall)
                phoneCall = new CallLog();
            if (!incomingNumber.isEmpty()) {
                phoneCall.setPhoneNumber(incomingNumber);
                // called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
                isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
            }
            break;
    }

}

}

并使用广播接收器

public class MyCallReceiver extends BroadcastReceiver {

public MyCallReceiver() {
}

static TelephonyManager manager;

@Override
public void onReceive(Context context, Intent intent) {
    Log.i("JLCreativeCallRecorder", "MyCallReceiver.onReceive ");

    if (!AppPreferences.getInstance(context).isRecordingEnabled()) {
        removeListener();
        return;
    }

    if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
        if (!AppPreferences.getInstance(context).isRecordingOutgoingEnabled()) {
            removeListener();
            return;
        }
        PhoneListener.getInstance(context).setOutgoing(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
    } else {
        if (!AppPreferences.getInstance(context).isRecordingIncomingEnabled()) {
            removeListener();
            return;
        }
    }

    // Start Listening to the call....
    if (null == manager) {
        manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    }
    if (null != manager)
        manager.listen(PhoneListener.getInstance(context), PhoneStateListener.LISTEN_CALL_STATE);
}

private void removeListener() {
    if (null != manager) {
        if (PhoneListener.hasInstance())
            manager.listen(PhoneListener.getInstance(null), PhoneStateListener.LISTEN_NONE);
    }
}

}

我希望你能从这段代码中得到一些帮助。

谢谢

答案 1 :(得分:1)

您可以使用辅助功能事件来检测呼叫持续时间,然后您可以检测是否接听了拨出电话。

我已经在Here中详细解答了这个问题。你可以检查一下。

答案 2 :(得分:0)

您需要在清单中使用此权限

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

TelephonyManager有一个听众来获取电话状态。实现这一点,知道手机是在振铃还是在通话中。

TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        PhoneStateListener callStateListener = new PhoneStateListener() {

            public void onCallStateChanged(int state, String incomingNumber) {
                // TODO React to a incoming call.

                try {
                    if (state == TelephonyManager.CALL_STATE_RINGING) {
                        Toast.makeText(getApplicationContext(), "Phone Is Ringing" + incomingNumber, Toast.LENGTH_LONG).show();
                        number = incomingNumber;
                        //g.setPhoneNo(incomingNumber);
                        AndroidNetCommunicationClientActivity.mMsgSendRequest("CommandMsgCallIncoming" + number);
                    } else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                        Toast.makeText(getApplicationContext(), "Phone is Currently in A call" + incomingNumber, Toast.LENGTH_LONG).show();
                        //number = mIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                        number = incomingNumber;


                    } else if (state == TelephonyManager.DATA_DISCONNECTED) {
                        number = "";
                        CallID = "";
                    }
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    //conn.MessageBox(MainActivity.this, e.getMessage());
                    e.printStackTrace();
                }
                super.onCallStateChanged(state, incomingNumber);

            }
        };
        telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);