А где у него кнопочки?
Каким бы ни было приложение, официальным или негласным (только для личного пользования в целях исследования, естественно), одинаково плохо, если оно будет падать из-за отсутствия на устройстве телефонных функций (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 } } }
Такой подход и следует использовать на практике.