Отслеживание входящих на Android

А где у него кнопочки?

Каким бы ни было приложение, официальным или негласным (только для личного пользования в целях исследования, естественно), одинаково плохо, если оно будет падать из-за отсутствия на устройстве телефонных функций (Wi-Fi-планшет). Поэтому первое, что стоит сделать, — проверить таковые:

PackageManager pm = getPackageManager();
boolean isTelephonySupported = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
boolean isGSMSupported = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_GSM);

Как видишь, мы воспользовались методом hasSystemFeature из объекта PackageManager, указав константу FEATURE_TELEPHONY в качестве параметра. Кроме того, имеет смысл дополнительно проверить поддержку GSM-модуля константой FEATURE_TELEPHONY_GSM.

Если обе константы лживы, то мы ошиблись устройством, ничего не поделаешь. В этом случае стоит завершить работу приложения, а на выходе попросить пользователя сменить девайс ;).

***************************

Принимаем звонок

Когда состояние телефона изменяется (например, в результате приема звонка), объект TelephonyManager начинает транслировать намерение (Intent) с действием ACTION_PHONE_STATE_CHANGED.

Намерения — межпрограммный фреймворк для обмена сообщениями. Намерения широко используются в Android для запуска/остановки активностей и сервисов, трансляции сообщений по всей системе, неявного вызова активностей, сервисов и широковещательных приемников.

Широковещательные приемники — компоненты, с помощью которых приложение может отслеживать намерения и реагировать на любые полученные действия. Приемники реализуют событийную модель взаимодействия приложений и системы. Более подробно тема создания широковещательного приемника рассмотрена в статье «Хакерский Cron на Android».

Как и в предыдущем случае, приложение должно получить разрешение READ_PHONE_STATE в манифесте:

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

Там же регистрируется и широковещательный приемник, способный отслеживать трансляцию намерения:

<receiver android:name="PhoneStateChangedReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.PHONE_STATE" />
    </intent-filter>
</receiver>

При таком подходе мы всегда можем получать информацию о входящих звонках, даже если приложение в данный момент не запущено.

Намерение, сообщающее об изменении состояния телефона, будет содержать два параметра: EXTRA_STATE_RINGING — признак входящего звонка и EXTRA_INCOMING_NUMBER — телефонный номер звонящего.

public class PhoneStateChangedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String phoneState = intent.getStringExtra (TelephonyManager.EXTRA_STATE);
        if (phoneState.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            doMagicWork(incomingNumber); // Поступил звонок с номера incomingNumber
        }
    }
}

Такой подход и следует использовать на практике.

https://xakep.ru/2017/03/14/android-hidden-call/