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..
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..
Inicie Android Studio y cree un nuevo proyecto con una actividad vacía llamada Actividad principal
.
Por ahora, nuestro diseño solo tendrá un Editar texto
campo y un Marcar botón:
Actividad principal
ClaseEn 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.
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:
Necesitamos el permiso READ_PHONE_STATE
Para poder controlar el estado del teléfono. Agregarlo a AndroidManifest.xml:
PhoneStateListener
ObjetoCreamos 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 ()
.
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_LOCATION
, LISTEN_SIGNAL_STRENGTH
, LISTEN_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.
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.
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;
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
.
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 +:
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..
Primero, necesitamos modificar nuestro diseño principal para tener un Editar texto
campo para el mensaje y un Enviar mensaje botón.
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.
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..
A continuación, veamos cómo enviar el SMS directamente desde nuestra aplicación en lugar de usar el dispositivo SMS del cliente.
Como de costumbre, necesitamos registrar el permiso en AndroidManifest.xml.
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_FAILURE
, RESULTADO_ERROR_RADIO_OFF
, y RESULTADO_ERROR_NULL_PDU
para indicar un error.
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ñ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); //…
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.
En este tutorial, aprendiste sobre:
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!