"android de la a a la z" -- unidad 11

11

Click here to load reader

Upload: android-unam

Post on 13-Jun-2015

1.936 views

Category:

Technology


0 download

DESCRIPTION

***Proyecto PAPIIT IN102210*** UNAM. Facultad de Ingeniería. Integrantes: JUAN JOSE CARREON J. ULISES GONZALEZ MEDINA ANA LAURA GARCÍA ACOSTA OMAR SIBAJA BAUTISTA ROBERTO SOSA HIGAREDA

TRANSCRIPT

Page 1: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

1 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

Conceptos preliminares

Telefonía es un término genérico que hace referencia a los detalles

relacionados con las comunicaciones electrónicas de voz a través de redes

telefónicas. Nuestro ámbito será, evidentemente, la red de telefonía móvil

en la que participan los dispositivos de Android, en concreto la red GSM

(Sistema Global para Comunicaciones Móviles).

El término teléfono significa habla a distancia. Proviene del griego tele,

que significa lejos, y fonos, que significa discurso.

GSM es una red de teléfonos móviles. Los dispositivos se comunican por

ondas de radio y frecuencias concretas por medio de repetidores

telefónicos. Esto significa que el estándar GSM debe definir diferentes

aspectos como identidades para dispositivos y móviles, así como todas las

reglas para establecer la comunicación.

No nos adentraremos en los detalles de GSM pero conviene recordar que

es el estándar empleado por Android para admitir llamadas de voz, y el

más utilizado por los operadores y dispositivos de todo el mundo. Todos

los dispositivos GSM utilizan una tarjeta SIM para almacenar la

configuración de la red y del usuario.

Una tarjeta SIM es una pequeña tarjeta inteligente, extraíble y segura. Todos los dispositivos que operan en

una red GSM disponen de identificadores exclusivos, que se almacenan en la tarjeta SIM:

ICCID (ID de Tarjeta de Circuito Integrado): Identifica la tarjeta

SIM (también denominado Número de Serie SIM o SSN).

IMEI (Identidad de Equipamiento Móvil Internacional):

Identifica un dispositivo móvil. (El número suele aparecer

impreso bajo la batería.)

IMSI (Identidad Internacional del Suscriptor Móvil): Identifica

al suscriptor (y a la red a la que pertenece).

LAI (Identidad de Área de Ubicación): Identifica la región del

proveedor de red del dispositivo.

KI (Clave de Autenticación): En esta red se utiliza una clave de

128 bits para autenticar la tarjeta SIM.

Estos números son importantes para validar y autenticar una tarjeta SIM, al dispositivo en que se encuentra

y al suscriptor en la red (y entre redes si fuera necesario).

Junto con el almacenamiento de identificadores y claves de autenticación, las tarjetas SIM permiten

guardar contactos y mensajes SMS. Es muy útil para los usuarios, ya que pueden extraer sus tarjetas y

disponer de sus datos de contactos y mensajes en otros dispositivos. En la actualidad no existen APIs

públicas para interactuar con la tarjeta SIM directamente en el dispositivo Android, aunque puede que

Page 2: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

2 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

aparezcan en el futuro. (Actualmente, la plataforma controla la interacción SIM y los programadores

pueden obtener acceso de sólo lectura a través de las API de telefonía.)

La base para trabajar con los paquetes de telefonía para Android es así de breve y sencilla. No olvide que

estamos trabajando con una red GSM y que puede encontrar términos como IMSI e IMEI, almacenados en

la SIM. Para acceder a esta información y realizar otras operaciones, se utiliza la clase TelephonyManager.

Obtener información sobre el teléfono

Android proporciona una clase de administración que proporciona información sobre muchos detalles del

dispositivo relacionados con la telefonía. Por medio de esta clase, TelephonyManager, puede acceder a

muchas de las propiedades GSM/SIM mencionadas anteriormente y puede obtener información de estado

de red y actualizaciones.

Para que las aplicaciones sepan cuándo está disponible un

servicio y cuándo se inician llamadas, se mantienen activas y

finalizan, se añade un oyente de eventos al teléfono,

PhoneListener, a través del administrador.

A continuación examinaremos distintas partes de la aplicación

de un ejemplo denominado TelephoneManager para analizar

estas clases y conceptos. Para empezar, obtendremos una

instancia de TelephonyManager y la utilizaremos para consultar

información de telefonía.

Propiedades de telefonía

El paquete android. telephony contiene la clase TelephonyManager, así como detalles de toda la

información que ofrece. En este ejemplo obtendremos y mostraremos un pequeño subconjunto de dicha

información para ilustrar este enfoque. La primera actividad, no la pantalla principal, de la aplicación es una

sencilla pantalla que muestra parte de la información que podemos obtener a través de TelephonyManager

La clase TelephonyManager constituye el centro de información de los datos relacionados con telefonía de

Android. El código muestra cómo obtener una referencia a esta clase y utilizarla para recuperar datos

public class TelephonyManagerExample extends Activity {

private TextView telMgrOutput;

@Override

public void onCreate(final Bundle icicle) {

Log.d(Constants.LOGTAG, "TelephonyManagerExample onCreate");

super.onCreate(icicle);

this.setContentView(R.layout.telmgrexample);

this.telMgrOutput = (TextView) findViewById(R.id.telmgroutput);

}

@Override

Page 3: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

3 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

public void onStart() {

super.onStart();

// TelephonyManager

final TelephonyManager telMgr = (TelephonyManager)

getSystemService(Context.TELEPHONY_SERVICE);

this.telMgrOutput.setText(telMgr.toString());

// PhoneStateListener

PhoneStateListener phoneStateListener = new PhoneStateListener() {

@Override

public void onCallStateChanged(final int state, final String incomingNumber)

{

telMgrOutput.setText(getTelephonyOverview(telMgr));

Log.d(Constants.LOGTAG, "phoneState updated - incoming number - " +

incomingNumber);

}

};

telMgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

String telephonyOverview = getTelephonyOverview(telMgr);

this.telMgrOutput.setText(telephonyOverview);

}

@Override

public void onPause() {

super.onPause();

}

/**

* Parse TelephonyManager values into a human readable String.

*

* @param telMgr

* @return

*/

public String getTelephonyOverview(final TelephonyManager telMgr) {

int callState = telMgr.getCallState();

String callStateString = "NA";

switch (callState) {

case TelephonyManager.CALL_STATE_IDLE:

callStateString = "IDLE";

break;

case TelephonyManager.CALL_STATE_OFFHOOK:

callStateString = "OFFHOOK";

break;

case TelephonyManager.CALL_STATE_RINGING:

callStateString = "RINGING";

break;

}

GsmCellLocation cellLocation = (GsmCellLocation) telMgr.getCellLocation();

String cellLocationString = cellLocation.getLac() + " " + cellLocation.getCid();

String deviceId = telMgr.getDeviceId();

String deviceSoftwareVersion = telMgr.getDeviceSoftwareVersion();

String line1Number = telMgr.getLine1Number();

Page 4: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

4 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

String networkCountryIso = telMgr.getNetworkCountryIso();

String networkOperator = telMgr.getNetworkOperator();

String networkOperatorName = telMgr.getNetworkOperatorName();

int phoneType = telMgr.getPhoneType();

String phoneTypeString = "NA";

switch (phoneType) {

case TelephonyManager.PHONE_TYPE_GSM:

phoneTypeString = "GSM";

break;

case TelephonyManager.PHONE_TYPE_NONE:

phoneTypeString = "NONE";

break;

}

String simCountryIso = telMgr.getSimCountryIso();

String simOperator = telMgr.getSimOperator();

String simOperatorName = telMgr.getSimOperatorName();

String simSerialNumber = telMgr.getSimSerialNumber();

String simSubscriberId = telMgr.getSubscriberId();

int simState = telMgr.getSimState();

String simStateString = "NA";

switch (simState) {

case TelephonyManager.SIM_STATE_ABSENT:

simStateString = "ABSENT";

break;

case TelephonyManager.SIM_STATE_NETWORK_LOCKED:

simStateString = "NETWORK_LOCKED";

break;

case TelephonyManager.SIM_STATE_PIN_REQUIRED:

simStateString = "PIN_REQUIRED";

break;

case TelephonyManager.SIM_STATE_PUK_REQUIRED:

simStateString = "PUK_REQUIRED";

break;

case TelephonyManager.SIM_STATE_READY:

simStateString = "STATE_READY";

break;

case TelephonyManager.SIM_STATE_UNKNOWN:

simStateString = "STATE_UNKNOWN";

break;

}

StringBuilder sb = new StringBuilder();

sb.append("telMgr - ");

sb.append(" \ncallState = " + callStateString);

sb.append(" \ncellLocationString = " + cellLocationString);

sb.append(" \ndeviceId = " + deviceId);

sb.append(" \ndeviceSoftwareVersion = " + deviceSoftwareVersion);

sb.append(" \nline1Number = " + line1Number);

sb.append(" \nnetworkCountryIso = " + networkCountryIso);

sb.append(" \nnetworkOperator = " + networkOperator);

sb.append(" \nnetworkOperatorName = " + networkOperatorName);

sb.append(" \nphoneTypeString = " + phoneTypeString);

sb.append(" \nsimCountryIso = " + simCountryIso);

sb.append(" \nsimOperator = " + simOperator);

sb.append(" \nsimOperatorName = " + simOperatorName);

Page 5: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

5 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

sb.append(" \nsimSerialNumber = " + simSerialNumber);

sb.append(" \nsimSubscriberId = " + simSubscriberId);

sb.append(" \nsimStateString = " + simStateString);

return sb.toString();

}

}

Se utiliza Context de Android, a través del método getSystemService con una constante, para obtener una

instancia de la clase TelephonyManager. Tras ello, se utiliza para obtener la información necesaria. En este

caso hemos creado un método de ayuda para obtener datos del administrador y devolverlos como cadena

para mostrarla posteriormente en la pantalla.

El administrador le permite acceder a datos de estado del teléfono, como por ejemplo si hay o no una

llamada en curso, información de ubicación, el ID del dispositivo y la versión del software, el número de

teléfono registrado en el usuario o SIM actuales, y otros muchos detalles SIM como el ID del suscriptor

(IMSI). Existen otras propiedades adicionales que no utilizamos en este ejemplo (consulte la

documentación).

Fíjese en otro detalle no incluido en el listado. Para que la clase funcione, es necesario establecer el

permiso READ_PHONE_STATE en el manifiesto (sin su presencia, se generan excepciones de seguridad al

intentar leer datos desde el administrador). En un apartado posterior veremos los permisos relacionados

con la telefonía.

Este control a la información telefónica, incluidos metadatos sobre el dispositivo, red y tarjeta SIM, es uno

de los principales objetos de la clase TelephonyManager. El otro es permitir que se añada un

PhoneStateListener.

Información del teléfono

Evidentemente, un teléfono muestra diferentes estados. Los más habituales son en reposo, en una llamada

o en proceso de iniciar una llamada. Al crear aplicaciones para un dispositivo móvil, en ocasiones no sólo

debe conocer el estado actual del teléfono sino también saber cuándo cambia. Para estos casos puede

adjuntar un oyente al teléfono y suscribirse para recibir notificaciones de los cambios publicados. En

Android, se utiliza PhoneStateListener, que se añade al teléfono a través de TelephonyManager. El código

muestra un ejemplo de uso de ambas clases.

@Override

public void onStart() {

super.onStart();

// TelephonyManager

final TelephonyManager telMgr = (TelephonyManager)

getSystemService(Context.TELEPHONY_SERVICE);

this.telMgrOutput.setText(telMgr.toString());

// PhoneStateListener

Page 6: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

6 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

PhoneStateListener phoneStateListener = new PhoneStateListener() {

@Override

public void onCallStateChanged(final int state, final String incomingNumber)

{

telMgrOutput.setText(getTelephonyOverview(telMgr));

Log.d(Constants.LOGTAG, "phoneState updated - incoming number - " +

incomingNumber);

}

};

telMgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

String telephonyOverview = getTelephonyOverview(telMgr);

this.telMgrOutput.setText(telephonyOverview);

}

Para comenzar a trabajar con PhoneStateListener, necesita una instancia de TelephonyManager para poder

asignar posteriormente el oyente. PhoneStateListener es una interfaz, de modo que debe crear una

implementación, con el método obligato¬rio onCallStateChanged, para poder utilizarla. Una vez obtenida la

instancia de PhoneStateListener (una implementación propia de la interfaz), se asigna al administrador por

medio del método listen.

En el ejemplo del código anterior, escuchamos todos los cambios PhoneStateListener . LISTEN_CALL_STATE

del estado del teléfono. Es un valor constante de una lista de estados disponibles que puede ver en la clase

PhoneStateListener. Puede utilizarlo como valor al asignar un oyente al método listen, como hemos hecho

aquí, o puede combinar varios valores. Si se produce un cambio de estado, restablecemos los detalles en

pantalla con el método getTelephonyOverview que utilizamos inicialmente para establecer el estado inicial

en el código que se presentó al inicio de este capítulo La acción realizada se define en el método

onCallStateChanged de PhoneStateListener. Puede filtrar este método (además de los tipos de eventos que

escuche) en función del int state pasado.

Realizando llamadas

Como vimos en un capítulo anterior, basta con utilizar la acción Intent. ACTION_ CALL y tel :Uri para invocar

la aplicación incorporada de marcado y realizar una llamada. Este enfoque invoca la aplicación de marcado,

la completa con el número de teléfono proporcionado (obtenido de Uri) e inicia la llamada.

Junto con esta acción, también puede invocar la aplicación con la acción Intent. ACTION_DIAL, que de

nuevo completa la aplicación con el número proporcionado pero se detiene después de iniciar la llamada.

this.dialintent = (Button) findViewById(R.id.dialintent_button);

this.dialintent.setOnClickListener(new OnClickListener() {

public void onClick(final View v) {

Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" +

Main.NUMBER));

startActivity(intent);

}

});

Page 7: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

7 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

this.callintent = (Button) findViewById(R.id.callintent_button);

this.callintent.setOnClickListener(new OnClickListener() {

public void onClick(final View v) {

Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" +

Main.NUMBER));

startActivity(intent);

}

});

Llegado a este punto, ya hemos visto el uso delntentyel diseño de la plataforma Android. En el listado 7.3

volvemos a utilizar este diseño para realizar llamadas a nú-meros concretos.

La realización de llamadas a través de los intent incorporados es muy sencilla, como hemos visto en

ejemplos anteriores. Básicamente necesita definir la acción que realizar, ya sea completando el marcador

con ACTION_DIAL o completándolo e iniciando la lla¬mada con ACTION_CALL. En cualquier caso, debe

especificar el número de teléfono que utilizar por medio de Intent Uri.

Otro aspecto relación con las llamadas que tener en cuenta son los permisos. El manifiesto de la aplicación

debe incluir los permisos correctos para poder acceder y modificar el estado del teléfono o interceptar

llamadas.

Mensajes SMS

El servicio de mensajes cortos o SMS (Short Message Service) es un

servicio disponible en los teléfonos móviles que permite el envío de

mensajes cortos (también conocidos como mensajes de texto, o más

coloquialmente, textos o mensajitos) entre teléfonos móviles,

teléfonos fijos y otros dispositivos de mano. SMS fue diseñado

originariamente como parte del estándar de telefonía móvil digital

GSM, pero en la actualidad está disponible en una amplia variedad

de redes, incluyendo las redes 3G.

Definiciones técnicas en GSM

Un mensaje SMS es una cadena alfanumérica de hasta 140 caracteres o de

160 caracteres de 7 bits, y cuyo encapsulado incluye una serie de

parámetros.

En principio, se emplean para enviar y recibir mensajes de texto normal,

pero existen extensiones del protocolo básico que permiten incluir otros

tipos de contenido, dar formato a los mensajes o encadenar varios

mensajes de texto para permitir mayor longitud (formatos de SMS con

imagen de Nokia, tonos IMY de Ericsson, estándar EMS para dar formato al

texto e incluir imágenes y sonidos de pequeño tamaño).

Page 8: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

8 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

En GSM existen varios tipos de mensajes de texto: mensajes de texto "puros", mensajes de configuración

(que contienen los parámetros de conexión para otros servicios, como WAP o MMS), mensajes WAP Push,

notificaciones de mensajes MMS... En este artículo nos limitaremos a lo que especifica el estándar GSM,

puesto que el transporte de todos los tipos de SMS se realiza de la misma forma.

En otros estándares de telefonía móvil (como CDMA2000 o UMTS) el proceso de los mensajes se realiza de

otra forma, pero el funcionamiento es transparente de cara al usuario.

Trabajando con mensajes SMS

Page 9: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

9 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

SMS es un importante medio de comunicación para los dispositivos móviles. Se utiliza para enviar sencillos

mensajes de texto y pequeñas cantidades de datos.

Android incluye una aplicación SMS que permite a los usuarios ver mensajes SMS recibidos y enviarlos

(incluida la respuesta a los recibidos). Junto con esta compatibilidad y el ContentProvider relacionado para

interactuar con el sistema incorporado, el SDK proporciona API para que los programadores puedan enviar

y recibir mensajes mediante programación.

Para explorar esta compatibilidad, analizaremos ambas caras de la moneda, el envío y la recepción.

El subpaquete android.telephony.gsm contiene las clases SmsManager y SmsMessage. SmsManager se

utiliza para definir muchas constantes relacionadas con SMS y contiene los métodos sendDataMessage,

sendMultipartTextMessage y sendTextMessage.

public class SmsExample extends Activity {

private EditText smsInputText;

private EditText smsInputDest;

private Button smsSend;

private SmsManager smsManager;

@Override

public void onCreate(final Bundle icicle) {

Log.d(Constants.LOGTAG, "SmsExample onCreate");

super.onCreate(icicle);

this.setContentView(R.layout.smsexample);

this.smsInputDest = (EditText) findViewById(R.id.smsinputdest);

this.smsInputText = (EditText) findViewById(R.id.smsinputtext);

this.smsSend = (Button) findViewById(R.id.smssend_button);

this.smsManager = SmsManager.getDefault();

// pending intent request code NOT USED

final PendingIntent sentIntent = PendingIntent.getActivity(this, 0, new

Intent(this, SmsExample.class), 0);

this.smsSend.setOnClickListener(new OnClickListener() {

public void onClick(final View v) {

Log.d(Constants.LOGTAG, "SmsExample sending SMS message via manager");

String dest = smsInputDest.getText().toString();

if (PhoneNumberUtils.isWellFormedSmsAddress(dest)) {

// dest, serviceCenter (null for default), message,

// sentIntent, deliveryIntent

//

// Set the second parameter to null. The scAddress relates

// to the address of the server on the cellular network that will

handle

// the message, it is not the address of the sender.

Page 10: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

10 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

smsManager.sendTextMessage(smsInputDest.getText().toString(), null,

smsInputText.getText()

.toString(), sentIntent, null);

Toast.makeText(SmsExample.this, "SMS message sent",

Toast.LENGTH_LONG).show();

} else {

Toast.makeText(SmsExample.this, "SMS destination invalid - try

again", Toast.LENGTH_LONG).show();

}

}

});

}

@Override

public void onStart() {

super.onStart();

}

@Override

public void onPause() {

super.onPause();

}

}

Lo primero que necesitamos para trabajar con mensajes SMS es obtener una instancia de SmsManager, por

medio del método estático getDefault. Posteriormente utilizaremos el administrador para enviar el

mensaje. Pero antes, es necesario crear Pendinglntent (que utilizaremos como parámetro en el método de

envío).

Pendinglntent puede especificar el elemento Activity, Broadcast o Service que necesite. En nuestro caso,

utilizamos el método getActivity, que denota una actividad, y después el contexto, código de solicitud (que

no se utiliza), Intent e indica¬dores adicionales. Indican si es necesario crear una nueva instancia de la

actividad (o Broadcast o Service) a la que se hace referencia en caso de que no exista.

Una vez obtenido Pendinglntent, comprobarnos que la dirección de destino sea válida para SMS (con otro

método de PhoneNumberUtils) y enviamos el mensaje por medio del método sentTextMessage del

administrador.

Este método de envío acepta varios parámetros, uno de los cuales puede resultar confuso. La firma de este

método es la siguiente:

sendDataMessage (String destinationAddress, String scAddress, short destinationPort,

byte[] data, Pendinglntentsentlntent, Pendinglntent de liveryIntent)

El parámetro destinationAddress es el número de teléfono al que enviar el mensaje. El parámetro

scAddress es el complicado. No es la dirección de origen, sino que indica la dirección del centro de servicios

internos en la red, que en la mayoría de los casos se deja en null (para utilizar el valor predeterminado).

destinationPort es el puerto; data es la carga del mensaje y, por último, sentlntent y deliverylntent son

Page 11: "Android de la A a la Z" -- Unidad 11

Android de la A a la Z

Unidad 11“Telefonía móvil”

11 Elaborado por: J. Ulises González Medina [email protected] Noviembre 2011 Versión 1.2

instancias Pendinglntent independientes que se ejecutan cuando se envía y se recibe satisfactoriamente el

mensaje.

Recibiendo SMS

La recepción de un mensaje SMS mediante programación se realiza a través de una difusión en la

plataforma Android. Para ilustrarlo en nuestra aplicación TelephonyExplorer, volveremos a implementar un

receptor.

public class SmsReceiver extends BroadcastReceiver {

public static final String SMSRECEIVED = "SMSR";

private static final String SMS_REC_ACTION =

"android.provider.Telephony.SMS_RECEIVED";

@Override

public void onReceive(final Context context, final Intent intent) {

Log.v(Constants.LOGTAG, "SmsReceiver onReceive");

if (intent.getAction().equals(SmsReceiver.SMS_REC_ACTION)) {

Log.v(Constants.LOGTAG, "SmsReceiver SMS received");

StringBuilder sb = new StringBuilder();

Bundle bundle = intent.getExtras();

if (bundle != null) {

Object[] pdus = (Object[]) bundle.get("pdus");

for (Object pdu : pdus) {

SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) pdu);

sb.append("body - " + smsMessage.getDisplayMessageBody());

}

}

Toast.makeText(context, "SMS RECEIVED - " + sb.toString(),

Toast.LENGTH_LONG).show();

}

}

}

Para reaccionar a un mensaje SMS entrante, volvemos a crear BroadcastReceiver ampliando la clase.

Nuestro receptor define una constante local para la acción Intent que desea capturar, en este caso

android.provider. Telephony. SMS_RECEIVED.

Una vez configurada la clase, filtramos la acción deseada en el método onReceive y obtenemos los datos

SMS del Intent Bundle con la clave pdus. PDU (Unidad de Datos de Protocolo) es el término que describe el

paquete de datos en mensajes SMS. En este caso, la plataforma utiliza la clave pdus (lo hemos descubierto

por ensayo y error, al obtener el conjunto de claves del Bundle e iterando por el mismo). Por cada objeto

pdu construimos un SmsMessage convirtiendo los datos en una matriz de bytes.

Seguidamente podemos trabajar con los métodos de esa clase, como por ejemplo

getDisplayMessageBody. Con el envío y recepción de mensajes SMS completamos la descripción de las

API de telefonía.