← Назад к вопросам

Как совершить телефонный звонок в Android

1.3 Junior🔥 102 комментариев
#Android компоненты#Сетевое взаимодействие

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Осуществление телефонного звонка в Android

В Android для совершения телефонного звонка используется механизм неявных интентов (Implicit Intents), поскольку прямая работа с телефонией через API требует специальных разрешений и закрыта для прямого вызова из приложений из соображений безопасности. Основной подход — запрос на совершение вызова через системное приложение "Набор номера".

Ключевые элементы реализации

  1. Разрешение (Permission):
    *   Для приложений с `targetSdkVersion` < 31 необходимо объявить в `AndroidManifest.xml` разрешение `CALL_PHONE`:
    ```xml
    <uses-permission android:name="android.permission.CALL_PHONE" />
    ```
        Это **опасное разрешение** (dangerous permission), поэтому начиная с Android 6.0 (API 23) его также нужно запрашивать во время выполнения (runtime permission).
    *   Для приложений с `targetSdkVersion` >= 31 разрешение `CALL_PHONE` заменяется на более **ограниченное** разрешение `MANAGE_OWN_CALLS` или использованием альтернативного метода `ACTION_DIAL` (см. ниже). `MANAGE_OWN_CALLS` предназначено для приложений-телефонов и, как правило, не предоставляется обычным приложениям.

  1. Основной Intent: ACTION_CALL:
    *   Прямой вызов с переходом в режим набора и автоматическим совершением звонка. Требует разрешения `CALL_PHONE`.
```kotlin
val phoneNumber = "tel:+71234567890"
val intent = Intent(Intent.ACTION_CALL, Uri.parse(phoneNumber))
startActivity(intent)
```

3. Альтернативный Intent: ACTION_DIAL:

    *   **Рекомендуемый** и более безопасный способ. Открывает системное приложение "Набор номера" с предзаполненным номером, но **не совершает звонок автоматически**. Пользователь сам должен нажать кнопку вызова. Не требует опасных разрешений.
```kotlin
val phoneNumber = "tel:+71234567890"
val intent = Intent(Intent.ACTION_DIAL, Uri.parse(phoneNumber))
startActivity(intent)
```
    Формат номера должен соответствовать схеме URI `tel:` (можно также использовать `voicemail:` для голосовой почты). Рекомендуется указывать номер в формате E.164 (с кодом страны `+7` для России).

Полный пример с обработкой разрешений (Kotlin)

Вот пример реализации с проверкой разрешений для ACTION_CALL для приложений с targetSdkVersion < 31:

1. Объявление разрешения в AndroidManifest.xml:

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

2. Код Activity/Fragment:

import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    private companion object {
        private const val PERMISSION_REQUEST_CALL_PHONE = 101
        private const val PHONE_NUMBER = "tel:+74951234567"
    }

    fun makePhoneCall() {
        val intent = Intent(Intent.ACTION_CALL, Uri.parse(PHONE_NUMBER))

        // Проверяем разрешение для Android 6.0+
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) !=
            PackageManager.PERMISSION_GRANTED) {
            // Запрашиваем разрешение
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.CALL_PHONE),
                PERMISSION_REQUEST_CALL_PHONE
            )
        } else {
            // Разрешение уже предоставлено
            startActivity(intent)
        }
    }

    // Обработка результата запроса разрешений
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            PERMISSION_REQUEST_CALL_PHONE -> {
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    // Разрешение получено
                    val intent = Intent(Intent.ACTION_CALL, Uri.parse(PHONE_NUMBER))
                    startActivity(intent)
                } else {
                    // Разрешение отклонено
                    Toast.makeText(this, "Разрешение на звонок отклонено", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}

Рекомендации и современный подход (Android 12+, API 31+)

  1. Используйте ACTION_DIAL вместо ACTION_CALL, если возможно. Это:
    *   Не требует опасных разрешений.
    *   Дает пользователю контроль (он видит номер и сам инициирует вызов).
    *   Работает на всех версиях Android без проблем с разрешениями.

  1. Проверка доступности функции телефона:

    fun isPhoneCallSupported(): Boolean {
        val intent = Intent(Intent.ACTION_DIAL)
        return intent.resolveActivity(packageManager) != null
    }
    
  2. Обработка особых номеров:

    *   Экстренные номера (112, 911) — используйте `ACTION_DIAL`.
    *   Номера с дополнительными символами (пауза `,`, ожидание `;`):
    ```kotlin
    val numberWithPause = "tel:+74951234567,1234" // Пауза после основного номера
    ```

4. Для targetSdkVersion >= 31:

    *   Разрешение `CALL_PHONE` практически недоступно для обычных приложений.
    *   Используйте `ACTION_DIAL` или новое разрешение `MANAGE_OWN_CALLS` (если ваше приложение является приложением-телефоном).
    *   Альтернатива — использование **API связи** (`TelecomManager`), но это требует сложной интеграции и предназначено для VoIP-приложений.

Итог

  • Для большинства приложений: используйте Intent(Intent.ACTION_DIAL, Uri.parse("tel:номер")) — безопасно и без разрешений.
  • Для прямого вызова: используйте ACTION_CALL с запросом разрешения CALL_PHONE (актуально для старых приложений).
  • Всегда проверяйте наличие приложения для обработки телефонных вызовов с помощью resolveActivity().
  • Форматируйте номера правильно, используя код страны.

Такой подход обеспечивает безопасность, соблюдение политик Google Play и дает пользователям контроль над телефонными вызовами.

Как совершить телефонный звонок в Android | PrepBro