Cómo hacer llamadas y usar SMS en aplicaciones de Android

En este tutorial, aprenderá sobre la telefonía de Android y la API de SMS. Aprenderá cómo hacer una llamada desde su aplicación y cómo controlar los eventos de llamadas telefónicas, así como también cómo enviar y recibir SMS..

1. Cómo hacer una llamada 

Para comenzar, le mostraré cómo iniciar una llamada desde su aplicación usando la aplicación de marcación telefónica o directamente desde su aplicación para que sea más fácil para sus usuarios..

Crear un nuevo proyecto de Android Studio

Inicie Android Studio y cree un nuevo proyecto con una actividad vacía llamada Actividad principal.


Extienda la pantalla

Por ahora, nuestro diseño solo tendrá un Editar texto campo y un Marcar botón:

   

Modificar el Actividad principal Clase

En el bloque de código de abajo, estamos creando un ACTION_DIAL intento de mostrar el marcador del teléfono. El número de teléfono se analiza de nuestra tel Esquema de URI: tel: XXXXXXXX. Tenga en cuenta que no necesita ningún permiso para que esto funcione:

import android.content.Intent; importar android.net.Uri; importar android.os.Bundle; importar android.support.v7.app.AppCompatActivity; importar android.text.TextUtils; importar android.view.View; importar android.widget.Button; importar android.widget.EditText; importar android.widget.Toast; la clase pública MainActivity extiende AppCompatActivity @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Button mDialButton = (Button) findViewById (R.id.btn_dial); final EditText mPhoneNoEt = (EditText) findViewById (R.id.et_phone_no); mDialButton.setOnClickListener (new View.OnClickListener () @Override public void onClick (View view) String phoneNo = mPhoneNoEt.getText (). toString (); : "+ phoneNo; startActivity (nueva intención (Intent.ACTION_DIAL, Uri.parse (marcar))) else Toast.makeText (MainActivity.this," Ingrese un número de teléfono ", Toast.LENGTH_SHORT) .show (); ); 

Si ejecuta la aplicación y hace clic en el botón de marcar, se lo llevará a la aplicación de marcación y, desde allí, debe marcar el número. Puede cambiar este flujo para realizar la llamada desde su aplicación simplemente cambiando el ACTION_DIAL intentar ACTION_CALL en lugar. Esto requerirá la android.permission.CALL_PHONE permiso, aunque. 

2. Monitoreo de eventos de llamadas telefónicas

En esta sección, vamos a aprender cómo monitorear eventos de llamadas telefónicas en el sistema Android. El teléfono puede estar en tres estados: 

  1. inactivo (cuando no se usa)
  2. timbre (cuando hay una llamada entrante)
  3. descolgado (cuando se contesta la llamada)

Añadir el permiso 

Necesitamos el permiso READ_PHONE_STATE Para poder controlar el estado del teléfono. Agregarlo a AndroidManifest.xml:

Crear el PhoneStateListener Objeto

Creamos un objeto de la PhoneStateListener clase, y luego anular su onCallStateChanged () Método (en IntelliJ es fácil hacerlo con Control-O, y luego seleccione o busque el método para anular). Manejaremos los cambios a los cambios del estado de la llamada al mostrar un tostada. Tenga en cuenta que también podemos acceder a los números de teléfono entrantes cuando se activa este método:

//… PhoneStateListener mPhoneStateListener = new PhoneStateListener () @Override public void onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); switch (estado) caso TelephonyManager.CALL_STATE_IDLE: Toast.makeText (MainActivity.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); descanso; caso TelephonyManager.CALL_STATE_RINGING: Toast.makeText (MainActivity.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); descanso; caso TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (MainActivity.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); descanso; ; //… 

Dependiendo de las necesidades de su aplicación, también podría anular uno de estos otros métodos de evento: onCellInfoChanged ()onCallForwardingIndicatorChanged ()onCellLocationChanged (), o onSignalStrengthChanged ().

Escuchando el estado de la llamada telefónica

Para comenzar a escuchar el estado de la llamada telefónica, necesitamos obtener el Gestor de telefonia desde el servicio del sistema e inicializarlo en onCreate ().

// ... privado TelephonyManager mTelephonyManager; @Override protected void onCreate (Bundle savedInstanceState) //… mTelephonyManager = (TelephonyManager) getSystemService (getApplicationContext (). TELEPHONY_SERVICE); 

En el En resumen() Método, podemos empezar a escuchar usando el Gestor de telefonia escucha() método, pasandolo PhoneStateListener instancia y la estática LISTEN_CALL_STATE. Dejamos de escuchar en el onStop () método pasando el LISTEN_NONE como el segundo argumento para escucha().

// ... @Override protected void onResume () super.onResume (); mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);  @ Anular la protección de vacío onStop () super.onStop (); mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_NONE);  //… 

Otras opciones de escucha son posibles LISTEN_CELL_LOCATIONLISTEN_SIGNAL_STRENGTHLISTEN_CALL_FORWARDING_INDICATOR, y LISTEN_CELL_INFO.

Finalmente, ejecute la aplicación y asegúrese de recibir una llamada entrante. 

Esta supervisión solo funcionará cuando la aplicación esté en primer plano. Para que esto funcione en segundo plano (cuando nuestra aplicación no se está ejecutando), deberíamos crear un Receptor de radiodifusión de modo que incluso si la aplicación no se está ejecutando, podemos monitorear los estados de las llamadas telefónicas. Dependiendo de los requisitos de su aplicación, esa podría ser una forma mucho mejor de escuchar los cambios de estado de las llamadas telefónicas. Te mostraré cómo hacer esto en la siguiente sección..

Tenga en cuenta que solo estamos monitoreando las llamadas entrantes. Para que podamos monitorear las llamadas salientes, necesitamos permisos adicionales. Para monitorear las llamadas salientes, incluya la siguiente línea en su AndroidManifest.xml expediente.

 

Cómo usar el emulador para hacer llamadas y enviar mensajes SMS

Puede usar su emulador para simular hacer una llamada o enviar un mensaje SMS, pero tendrá que hacer una pequeña configuración. Abra su emulador, haga clic en el último botón en la barra de navegación del lado derecho para abrir el cuadro de diálogo de control extendido, y luego seleccione el botón de control del teléfono. 

3. Monitoreo de eventos de llamadas telefónicas en el fondo

Crear un BroadcastReceiver

Al igual que en la sección anterior, necesitamos crear un detector de eventos para monitorear los cambios de estado del teléfono. La principal diferencia es que esta vez vamos a extender el Receptor de radiodifusión clase base para que podamos escuchar el estado de la llamada telefónica incluso si la aplicación no se está ejecutando. ¡Asegúrese de no registrar al oyente más de una vez! Nuestro cheque para esto está en la línea 36..

import android.content.BroadcastReceiver; importar android.content.Context; import android.content.Intent; importar android.telephony.PhoneStateListener; importar android.telephony.TelephonyManager; importar android.widget.Toast; la clase pública PhoneCallStateReceiver extiende BroadcastReceiver privado TelephonyManager mTelephonyManager; booleano estático público isListening = false; @Override public void onReceive (contexto de contexto final, intención de intento) mTelephonyManager = (TelephonyManager) context.getSystemService (context.TELEPHONY_SERVICE); PhoneStateListener mPhoneStateListener = new PhoneStateListener () @Override public void onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); switch (estado) caso TelephonyManager.CALL_STATE_IDLE: Toast.makeText (contexto, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); descanso; caso TelephonyManager.CALL_STATE_RINGING: Toast.makeText (contexto, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); descanso; caso TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (contexto, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); descanso; ; if (! isListening) mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); isListening = true; 

Modificar AndroidManifest.xml

Un receptor de difusión solo funciona si está registrado. Necesitamos informarle al sistema Android sobre nuestro receptor de difusión registrándolo en el AndroidManifest.xml archivo conectando nuestro PhoneCallStateReceiver clase a la que describe la transmisión del sistema que deseamos recibir, en este caso, PHONE_STATE.

    

Monitoreo de llamadas salientes

Para las llamadas salientes, debe incluir el NEW_OUTGOING_CALL intención de acción  en el del receptor en AndroidManifest.xml

Para obtener el número de teléfono de la llamada saliente prevista, dentro de la onReceive (Contexto, Intención) Método, obtenemos el número de la intención como extra. Para evitar que esa llamada intencionada pase, podemos llamar setResultData () Y pasarle un argumento nulo. los resultadoDatos se utiliza como el número real para llamar. 

@Override public void onReceive (contexto de contexto final, intención de intento) // para la llamada saliente String outphonePhoneNo = intent.getStringExtra (Intent.EXTRA_PHONE_NUMBER) .toString (); // evitar la llamada saliente setResultData (null); 

Puede obtener más información sobre transmisiones y receptores de radiodifusión en nuestro tutorial aquí en Envato Tuts +:

4. Enviando mensajes SMS

Tiene solo dos opciones principales para enviar SMS: usar la aplicación cliente de SMS del dispositivo u omitir el cliente enviando el SMS directamente desde su aplicación. Examinaremos ambos escenarios, y usted puede decidir cuál es el mejor para su caso de uso. Empecemos enviando un SMS utilizando el dispositivo SMS cliente..

Configurar el diseño

Primero, necesitamos modificar nuestro diseño principal para tener un Editar texto campo para el mensaje y un Enviar mensaje botón.

  

Modificar la actividad principal 

Dentro de nuestro onCreate () método en nuestro Actividad principal clase, crear una intención con ACTION_SENDTO como el primer argumento y un smsto URI como el segundo argumento. El mensaje de texto será el valor de la sms_body extra: 

//… Button sendMessageBtn = (Button) findViewById (R.id.btn_send_message); final EditText messagetEt = (EditText) findViewById (R.id.et_message); sendMessageBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (vista de vista) String message = messagetEt.getText (). toString (); String messageNo = mPhoneNoEt.getText (). TextUtils.isEmpty (mensaje) &&! TextUtils.isEmpty (phoneNo)) Intent smsIntent = new Intent (Intent.ACTION_SENDTO, Uri.parse ("smsto:" + phoneNo)); smsIntent.putExtra ("sms_body", mensaje); startActivity (smsIntent);); //… 

Aquí, el cliente SMS supervisará el estado de la entrega del mensaje. 

Ejecutar la aplicación

Cuando se ingresan todos los campos obligatorios, haga clic en Enviar SMS El botón abrirá el cliente de SMS del usuario o le dará opciones para seleccionar una aplicación si aún no se ha elegido una..

5. Enviando mensajes SMS directamente

A continuación, veamos cómo enviar el SMS directamente desde nuestra aplicación en lugar de usar el dispositivo SMS del cliente. 

Añadir permiso en AndroidManifest.xml

Como de costumbre, necesitamos registrar el permiso en AndroidManifest.xml.

 

Modificar la clase MainActivity 

A continuación, para Android 6.0 (nivel API 23) y superior, debemos solicitar el ENVIAR SMS permiso durante el tiempo de ejecución. 

Para obtener más información sobre los permisos de tiempo de ejecución de Android y cómo han cambiado en la versión 6.0, consulte nuestro tutorial aquí en Envato Tuts +:

Para enviar un SMS, obtenemos el predeterminado SmsManager instancia y luego llamar a su envía un mensaje de texto() Método, pasando el número de teléfono como primer argumento y el mensaje como segundo argumento:

// ... final int SEND_SMS_PERMISSION_REQUEST_CODE = 111; Botón privado mSendMessageBtn; @Override protected void onCreate (Bundle savedInstanceState) //… mSendMessageBtn = (Button) findViewById (R.id.btn_send_message); final EditText messagetEt = (EditText) findViewById (R.id.et_message); mSendMessageBtn.setEnabled (false); if (checkPermission (Manifest.permission.SEND_SMS)) mSendMessageBtn.setEnabled (true);  else ActivityCompat.requestPermissions (this, new String [] Manifest.permission.SEND_SMS, SEND_SMS_PERMISSION_REQUEST_CODE);  mSendMessageBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (View view) String message = messagetEt.getText (). toString (); String messageNo = mPhoneNoEt.getText (). to. ! TextUtils.isEmpty (message) &&! TextUtils.isEmpty (phoneNo)) if (checkPermission (Manifest.permission.SEND_SMS)) SmsManager smsManager = SmsManager.getDefault (); smsManager.sendTextMessage (phoneNo, null, message nulo); else Toast.makeText (MainActivity.this, "Permiso denegado", Toast.LENGTH_SHORT) .show (););  private boolean checkPermission (permiso de cadena) int checkPermission = ContextCompat.checkSelfPermission (this, permission); return (checkPermission == PackageManager.PERMISSION_GRANTED);  @ Anular la anulación pública onRequestPermissionsResult (int requestCode, @NonNull String [] permissions, @NonNull int [] grantResults) switch (requestCode) case SEND_SMS_PERMISSION_REQUEST_CODE: if (grantResults.length)> 0 y casos de información, artículos y servicios con más información. .PERMISSION_GRANTED)) mSendMessageBtn.setEnabled (true);  regreso;  //… 

Para controlar el estado de entrega, el Gestor de SMS envía un mensaje de texto() método tiene dos opcionales PendingIntent parámetros: sententent y deliveryIntent.

void sendTextMessage (String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)

Si quieres usar sententent, ver el código de resultado Actividad.RESULTADO_OK en el éxito, o uno de RESULTADO_ERROR_GENERICO_FAILURERESULTADO_ERROR_RADIO_OFF, y RESULTADO_ERROR_NULL_PDU para indicar un error.

6. Recibir un mensaje SMS

Para que su aplicación comience a recibir mensajes SMS desde el teléfono del usuario, es mejor tener un receptor de difusión registrado para que pueda recibir una alerta cuando llegue un nuevo SMS, incluso si su aplicación no se está ejecutando en primer plano.. 

Añadir el permiso 

Añade el RECEIVE_SMS permiso para AndroidManifest.xml:

Luego, debemos verificar y ver si la aplicación tiene permiso para recibir mensajes SMS en tiempo de ejecución. Así que en el Actividad principal clase, compruebe el RECEIVE_SMS permiso. Si no lo encuentra, solicítelo..

// ... @Override protected void onCreate (Bundle savedInstanceState) // ... if (! CheckPermission (Manifest.permission.RECEIVE_SMS)) ActivityCompat.requestPermissions (this, new String [] Manifest.permission.RECEIVE_SMS, 222);  //… 

Crear un receptor de difusión

Estamos recuperando cada objeto de la Mensaje sms clase usando el método createFromPdu (byte [] pdu), pasándole una PDU (unidad de datos de protocolo). Luego lo estamos agregando a nuestra matriz de mensajes.. 

Para admitir API 23 y superior, debe incluir el formato Cadena extra (ya sea "3gpp" para mensajes GSM / UMTS / LTE en formato 3GPP o "3gpp2" para mensajes CDMA / LTE en formato 3GPP2). 

import android.content.BroadcastReceiver; importar android.content.Context; import android.content.Intent; import android.os.Build; importar android.os.Bundle; importar android.telephony.SmsMessage; importar android.widget.Toast; public class SMSReceiver amplía BroadcastReceiver @Override public void onReceive (Contexto de contexto, Intención) Bundle bundle = intent.getExtras (); if (bundle! = null) Object [] pdus = (Object []) bundle.get ("pdus"); Formato de cadena = bundle.getString ("formato"); SmsMessage final [] messages = new SmsMessage [pdus.length]; para (int i = 0; i < pdus.length; i++)  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) messages [i] = SmsMessage.createFromPdu ((byte []) pdus [i], format);  else messages [i] = SmsMessage.createFromPdu ((byte []) pdus [i]);  String senderPhoneNo = messages [i] .getDisplayOriginatingAddress (); Toast.makeText (contexto, "Mensaje" + mensajes [0] .getMessageBody () + ", de" + senderPhoneNo, Toast.LENGTH_SHORT) .show (); 

Ahora, ejecute la aplicación, ciérrela y envíe un SMS a su teléfono emulado.

Conclusión

En este tutorial, aprendiste sobre:

  • haciendo una llamada desde su aplicación
  • monitorear eventos de llamadas telefónicas
  • enviar mensajes SMS utilizando la aplicación de mensajería del dispositivo o directamente desde su propia aplicación
  • recibir mensajes SMS en el fondo

Hay mucho más que puedes hacer con llamadas telefónicas y mensajes SMS en Android. Visite la API de telefonía de Android y la documentación de la API de SMSManager para obtener más información. 

Mientras tanto, echa un vistazo a algunas de nuestras otras publicaciones sobre el desarrollo de Android!

  • Sensores de Android en profundidad: proximidad y giroscopio

    Los giroscopios y los sensores de proximidad están disponibles en la mayoría de los teléfonos Android en la actualidad. Al usarlos creativamente, puede agregar una nueva dimensión a su usuario ...
    Ashraff Hathibelagal
    SDK de Android
  • 6 Qué hacer y qué no hacer para una excelente experiencia de usuario de Android

    Las aplicaciones de Android más populares tienen algo en común: todas ofrecen una excelente experiencia de usuario. En esta publicación, compartiré algunos consejos que ayudarán a tu aplicación ...
    Jessica thornsby
    SDK de Android
  • Fondo de audio en Android con MediaSessionCompat

    Uno de los usos más populares para dispositivos móviles es la reproducción de audio a través de servicios de transmisión de música, podcasts descargados o cualquier otro número de audio ...
    Paul Trebilcox-Ruiz
    SDK de Android
  • Migrar una aplicación de Android a Material Design

    Hace años, cuando Android aún era un sistema operativo móvil en ciernes, era bastante conocido por su fea interfaz de usuario. Porque no había diseño ...
    Ashraff Hathibelagal
    Androide