Переадресуємо повідомлення про вхідні дзвінки та смс на комп’ютер

Крім того, це непогана можливість попрактикуватися у розробці під андроїд. В результаті вийшла маленька програма, яка перехоплює вхідні дзвінки, СМС і відправляє їх по локальній мережі.

Приймачі широкомовних повідомлень

Перше, що нам потрібно для перехоплення дзвінків і СМС це додати відповідні дозволи в AndroidManifest.xml:

Але одних дозволів мало. Ще знадобляться приймачі широкомовних повідомлень. Це спеціальні об'єкти, які виконуються при отриманні якогось спеціального сигналу. Для того, щоб система знала, що у нас є об'єкт, якому потрібно надіслати повідомлення, його необхідно зареєструвати.

Звичайно це можна зробити, додавши відповідні рядки в AndroidManifest.xml:

Але якщо ми хочемо мати можливість вмикати та вимикати наші BroadcastReceiver, то можна їх реєструвати динамічно:

Але якщо ми будемо створювати BroadcastReceiver у коді основної екранної форми (Activity), то вони будуть працювати тільки коли програма активна (не стоїть у паузі і не зупинено). Наш додаток завжди повинен залишатися у фоні. Для цього існують фонові послуги:

Створений таким чином сервіс всіляко чинитиме опір спробам його вбити. При запуску в треї з'явиться повідомлення із заданим текстом та зображенням. Якщо розгорнути трей і торкнутися цього повідомлення, запуститься вказане Activity.

Варто зауважити, що вказаний вище спосіб створення повідомлення сервісу вважається застарілим, і починаючи з API level 11 (Android 3.0.x) необхідно використовувати конструктор Notification.Builder. Але я не став використовувати його для сумісності з більш старими версіями Android.

Так само буде корисно мати можливість запускати фоновий сервіс призапуск системи, для цього можна зареєструвати ще один BroadcastReceiver:

Тепер, коли ми розібралися, як і де потрібно реєструвати BroadcastReceiver, розглянемо докладніше як їх використовувати. Необхідно успадкувати свій клас від BroadcastReceiver та визначити в ньому метод onReceive, який викликається при надходженні широкомовного повідомлення:

Підготовка повідомлення

Для роботи з книгою контактів потрібно додати до AndroidManifest.xml наступну роздільну здатність

Отримати вхідні SMS можна помістивши в onReceive наступний код:

Відправка повідомлення

Телефон знаходиться в одній локальній мережі з ноутбуком та комп'ютером, тому для надсилання підготовленого повідомлення скористаємося звичайними сокетами. Наступний код показує, як надіслати пакет локальної мережі. Увага! Пересилання не шифрованого повідомлення через мережу широкомовним UDP пакетом може бути небезпечним.

Для можливості роботи з мережею додамо дозвіл AndroidManifest.xml

І тут під час тестування з'ясувалося, що метод onReceive в BroadcastReceiver живе дуже невеликий час. Якщо помістити в нього функцію визначення імені абонента за номером та функцію надсилання повідомлення по мережі, то система вб'є його раніше, ніж обидві функції буде виконано. Що характерно, у версії Android 2.3.* цей код успішно встигав відпрацювати, а у версіях 4.* ні. Тому тривалі операції потрібно виконувати в окремому сервісі, що запускається функцією startService().

Прийом повідомлень

Для прийому повідомлення напишемо маленьку програму на C, що використовує ті самі сокети:

Але отримати повідомлення мало, потрібно ще якось показати його собі. У linux існує зручна консольна утиліта notify-send, яка приймає як аргумент повідомлення та виводитьйого користувачеві через панель сповіщення kde або gnome. Використовуючи її, можна вивести повідомлення в пару рядків:

Отриманий додаток Ви можете додати в автозавантаження вашим улюбленим способом.