Ahora vamos a hacer un ejemplo donde vamos a estar consultando un content provider. Nuestro content provider de log de llamadas, donde tendremos pues todas las llamadas que hemos hecho en nuestro dispositivo. Este proyecto también lo vamos a estar probando en nuestro teléfono, en nuestro dispositivo físico en vez de utilizar el emulador. Si quisieras probarlo en el emulador, bueno, te pido por favor que ejecutes algún par de llamadas. Y también pues estés emulando un par de llamadas de entrada para que puedas poder ver el log de llamadas del emulador. Entonces, vamos a comenzar colocando el nombre a nuestro proyecto. Nuestro proyecto se va a llamar "MiLogdeLlamadas", mi log de llamadas. Y le voy a dar siguiente, la misma API. Vamos a definir un empty activity. Vamos a dejar los valores tal cual como están por default y empezaremos a crear nuestro proyecto. De nueva cuenta, tengo por aquí mi visualizador donde está mi teléfono. Porque pues bueno, como les platiqué vamos a estar probando nuestro proyecto en nuestro dispositivo físico. Entonces mi proyecto you se ha creado, aquí está, mi log de llamadas está a punto de estar listo. Lo que voy hacer como interfaz, lo que voy a hacer como interfaz es que voy a tener un título de mi aplicación. Además, voy a tener un botón que, cuando alguien le de click a ese botón, automáticamente nos va a mostrar las llamadas. Y entonces, necesito tener también un lugar en donde estar mostrando nuestras llamadas. Entonces para eso voy a utilizar un text view. Entonces, tengo aquí el text view. Para el título, voy a cambiar primeramente el tipo de layout. Me conviene ahorita estar utilizando un linear layout. Un linear layout que tenga una orientación vertical para que estos elementos se estén acomodando de una mejor forma, una forma más sencilla. Entonces voy a colocar el id y le voy a poner a este el título. Y vamos a colocarle un text size. Recuerda que estas variables de preferencia deben estar ubicadas en tu archivo dimens. Entonces, voy a colocarle eso, además voy a decir que esto tenga una gravedad que esté centrado. Que esté centrado respecto al layout. Y además le vamos a quitar el texto que dice hello world, se lo vamos a cambiar. Esto si lo vamos a declarar en nuestro archivo strings, se lo vamos a cambiar y le vamos a decir strings y le vamos a poner "Llamadas". Vamos a ponerlo así y le vamos a poner "Llamadas". Muy bien, esto es lo que vamos a estar mostrando en cómo el título. Llamadas puse por ahí, bueno, nada más hay que modificarle esto así. Listo, perfecto. you están mis llamadas. Ahora, a continuación, vamos hacer un botón, vamos a decirle "match_parent", "wrap_content" y vamos a utilizar aquí la propiedad id. El id y le vamos a poner btn, vamos a decir "MostrarLlamadas", mostrar llamadas. Además, también debe tener un texto que diga mostrar log de llamadas. String, "botón_llamadas", y le vamos a decir aquí "Mostrar Log Llamadas". Entonces, lo que vamos a estar haciendo es consultar un content provider que nos va ayudar a entrar a la base de datos de nuestro teléfono. Precisamente la base de datos que esté manejando las llamadas. Entonces, es éste el que quiero, el del botón, botón de llamadas. Ahí está perfecto. Y, por último, voy a colocar un elemento scroll view. Scroll, vamos ponerlo con S mayúscula, ScrollView. Y éste va tener "match_parent", y "match_parent". Vamos a dejarlo así, y adentro un scrollView debe tener un layout, un layout definido y entonces le vamos a poner aquí un "LinearLayout" también. Un LinearLayout que va a ser como en ambos casos "match_parent". Entonces ahora sí, dentro de "LinearLayout" you podemos definir nuestro text view. Entonces, recuerda que este text view nos va a funcionar, le vamos a poner ahorita "wrap_content" y "wrap_content". Este text view nos va a funcionar o nos va a ayudar para poder estar insertando el resultado de la consulta de nuestro log de llamadas, y le vamos a poner así, "tvLlamadas". Le vamos a poner un texto domi, podemos poner el texto domi que esté por aquí, el app_name, mi log de llamadas, el nombre de la aplicación y listo. Con esto you está listo. La idea es que metemos esto en un scroll view porque de pronto el log de llamadas puede estar muy muy grande. Imagínate, vamos a ver todas las llamadas que hemos hecho en la historia de nuestro teléfono. Entonces, por eso necesitamos un elemento scroll, para poder estar scrolleando todas esas llamadas. Igualmente, podrías utilizar un listView para estar insertando los datos ahí, un recyclerView o cualquier view en particular. Perfecto, tenemos nuestro text view. Entonces vamos a nuestro main activity. Ahí en nuestro main activity vamos a declarar primeramente nuestro método que va a estar reaccionando cuando alguien le dé clic en mostrar llamadas. Vamos a poner ese método. Y recuerda que este debe recibir un view, que en este caso es el botón que estamos dando click. Vamos a asignar este método de una vez, a nuestro botón android on click para no perderlo de vista, no olvidarnos de él. you está listo, you está adentro. Y bien, hasta ahorita voy a dejar esto de mostrar llamadas. Como vamos a estar consultando el log de llamadas de un usuario. Bueno, déjame decir que esto se considera un dato privado del usuario. Es decir, nosotros tendremos que solicitar permiso para poder consultar el log de llamadas. Y más aún, si además de consultar el número telefónico de la llamada, el número telefónico, quisieras consultar también el nombre que ahorita vas a ver que también lo tenemos disponible. Necesitarás también solicitar permiso para leer tus contactos en caso de que también ese número esté asignado a un contacto que you tengas dado de alta. Entonces, necesitaremos estar gestionando permisos. Entonces, lo primero que voy a estar gestionando es la solicitud de permiso. Si solamente queremos asignar, si solamente queremos ver los números, entonces vamos a gestionar dos permisos. En el primer permiso voy a declarar aquí mi método public void. Puedes echar mano del ejemplo del ejercicio que hicimos en nuestro proyecto de permisos. Y entonces bueno, para eso recuerda que tenemos por aquí tres métodos que catchar. El primero es para solicitar un permiso, el segundo es para checar el estatus, entonces aquí nos devuleve un boolean. Entonces tenemos que checar el status del permiso. Ok, checarStatusPermiso. Muy bien. Ahorita no le vamos a poner nada de return. El siguiente método tenemos que onRequestPermissionsResult. Es decir, catchar el call back de cuando el permiso you haya sido asignado y entonces, bueno, ejecutar una acción. Entonces tengo estos tres métodos que me van a ayudar a gestionar mi permiso. Adicional a estos tres métodos, voy a colocar un método más, voy a definir un método más y le voy a decir public void. Y este método me va ayudar a estar gestionando la parte de la consulta al content provider. Entonces es muy bueno estar modularizando nuestro proyecto de esta forma, porque así podemos estar reutilizando código cada vez que querramos. Entonces voy a colocar aquí, consultar content provider de llamadas. Aquí dentro de este método estará toda la lógica, todo el código que necesitamos para consultar un log de llamadas o consultar un content provider. En este caso para las llamadas. Perfecto, you tenemos nuestros cinco métodos que vamos a estar utilizando. Y entonces voy a comenzar por el primero. El primero de la solicitud del permiso. Muy bien, recuerda que teníamos que hacer por aquí un chequeo para ver si el permiso es otorgado o no, y además pasar un arreglo de nuestros permisos. Entonces ahorita, en el ejemplo de permisos solamente estuvimos gestionando un permiso. Aquí vamos a gestionar dos. Entonces le voy a poner una variable booleana y le voy a decir solicitar permiso de Read Call Log. Esto significa, vamos a poner aquí Read Call Log, ésta será nuestro primer permiso. Nuestro siguiente permiso vamos a poner Write Call Log. you sé, me vas a decir que no estamos escribiendo en el log de llamadas, pero aunque solamente lo estemos leyendo Android nos solicita este permiso también. Ok, entonces vamos a primeramente gestionar el primer persimo. Y aquí vamos a colocar ActivityCompat y vamos a poner shouldShowRequestPermissionRationale. Y recuerdas que necesitabamos pasar nuestro objeto actividad que le asignábamos un valor en el método onCreate. Entonces voy a declarar mi variable de activity, que es la que le vamos a poner por aquí. Le vamos a poner activity igual a this. Perfecto. Aquí también podrías colocar this directamente pero bueno, lo hacemos así para poder estar reutilizando código. Entonces lo siguiente es colocar Manifest.permission, colocar nuestro permiso que el primero que necesitamos es READ_CALL_LOG, este que está aquí. Le damos punto y coma, ok. Entonces esto nos va devolver un booleano, nos va responder si el permiso fue otorgado o no. Vamos a definir otra variable, vamos a poner aquí solicitar, ahí está. Y ahora lo siguiente solicitar, en vez de read será write call log. Ok, y voy a copiar exactamnete lo mismo, simplemente voy a cambiar el permiso,ok. En vez de poner darle READ_CALL_LOG. Vamos a poner WRITE_CALL_LOG. Por supuesto, podríamos optimizar esto en un método que únicamente reciba como parámetro el permiso. Y entonces you no tener que estar copiando y pegando nuestras líneas de código. Entonces ahora vamos a hacer aquí el chequeo, precisamente que necesito que solicitar permiso sea true. Y también solicitar permiso de write call log, ambos sean true. Para entonces mostrar un mensaje y entonces decir que el permiso you fue otorgado. Entonces voy a poner por aquí un Toast. Si ambos permisos you fueron otorgados entonces you puedo decir, los permisos fueron otorgados. Podrías gestionar uno a uno y decir el permiso de write call log you fue otorgado. Y el permiso de read call log también you fue otorgado. Podrías gestionarlo uno a uno si es que así lo quieres. Entonces si ambos permisos no están, entonces los solicitaremos con la clase ActivityCompat. Pondremos .RequestPermission. Colocaremos nuestro activity. Y en seguida colocamos nuestro arreglo de String que tendrá los permisos, los dos permisos que hemos solicitado. Colocamos Manifest.permission. Primero es el de read, necesitamos READ_CALL_LOG, ahí está. Coma, vamos a meter un segundo permiso. Manifest.permission., ahora seguiría WRITE_CALL_LOG. Perfecto. Y no olvides también que necesitamos por acá nuestra variable de permisos. Nuestra variable de nuestro código. Entonces voy a poner aquí CODIGO_SOLICITUD_PERMISO. Si no lo tenemos lo creamos, le decimos create constant field, ahí está. Si queremos un tipo entero, le vamos a decir que sea uno. Solicitud de permisos. Muy bien, entonces esto es lo que tenemos hasta el momento. Y hasta el momento you hemos solicitado, hemos creado nuestro método para solicitar permisos. Ahora vamos a sobrescribir, más bien vamos a definir, a implementar el método checar estatus del permiso. De la misma forma, voy a estar trabajando por acá. Aquí estamos. Dos variables booleanas y vamos a poner permiso. Primeramente voy a checar el permiso de ReadCallLog y a este le voy a asignar ActivityCompat.CheckSelfPermissions, le vamos a poner this. Y el permiso que debemos checar es Manifest.permission. Primeramente para READ_CALL_LOG. Ok, READ_CALL_LOG le damos punto y coma, y todavía no hemos terminado. Tenemos que checar si el permiso ha sido otorgado. Entonces esto debe ser igual a PackageManager.PERMISSION_GRANTED. Recuerda que esta línea lo que hace es ir con sus respectivos códigos y entonces checar si el permiso you fue otorgado o no. Entonces esta comparación nos devuelve un booleano. Un booleano que será true o false, dependiendo de si los códigos concuerdan. Seleccionaré mi segunda variable. Vamos a poner aquí permiso para WriteCallLog. Y la misma línea de código que tenemos aquí, esta misma línea la vamos a poner acá. Y simplemente vamos a cambiar el nombre del permiso. WRITE_CALL_LOG. Listo, permiso WRITE_CALL_LOG. Así es como va quedando nuestros permisos. Y ahora tenemos que hacer nuestra respectiva comparación, nuestro if. Vamos a hacer nuestro if, donde digamos que el permiso, aquí ambos tienen que estar otorgados. Por acá también me falta el de write. Ahí está, ambos. Entonces si ambos están otorgados devolveremos true. En el caso contrario, acá vamos a poner else. En el caso contrario, entonces devolveremos false. Return false. Return false. Muy bien, you tenemos la solicitud del permiso. Estamos gestionando varios permisos y también estamos checando el estatus del permiso. Estamos checando ahora el estatus de varios permisos. Una vez que el permiso haya sido otorgado. Es decir, una vez que por aquí esto se haya ejecutado correctamente, entonces irá a nuestro call back que será onRequestPermissionResult. Y lo que tenemos que estar checando ahí es nuestro código de permiso. El código de solicitud de permiso que nosotros definimos. Recuerda que teníamos un switch y le vamos a poner nuestro requestCode, es la variable a examinar dentro del switch. Colocaremos case y diremos que si nuestro código, si coincide con nuestro código de solicitud. Entonces se supone que pues si coniciden ambos permisos, entonces checamos de nuevo, checamos el estatus del permiso. Si el estatus del permiso nos devulve un verdadero, un true, ok. Es decir, si los permisos you fueron condedidos, entonces enviaremos un mensaje a nuestro usuario y le diremos, you está activo el permiso. you está activo el permiso o you están activos los permisos, como gustes manejarlo. Y entonces si you están activos los permisos, you estamos listos. Es hasta este momento que you estamos listos para consultar el content provider. Es muy importante que esta consulta del content provider lo coloquemos dentro del callBack, porque únicamente en el callBack es donde vamos a estar controlando que los permisos you se hayan dado de alta. Bien. Si el permiso you se dio de alta entonces consultaré el content provider que en un momento lo vamos a definir. Entonces voy a colocar else si es que no, entonces podríamos definir por acá que, no se activó el permiso. Excelente. Entonces, vamos a estar gestionando cómo es que va funcionar nuestro botón de mostrar llamadas. Ok, you tenemos nuestro callBack, you tenemos el chequeo de los permisos. Entonces vamos a estar por acá gestionando nuestro botón de mostrar llamadas. Es muy importante que para poder ejecutar nuestra consulta, el content provider, es muy importate primeramente ver si nuestro permiso you está habilitado. Para que no nos esté a cada momento que estemos dándole clic a ese botón, no nos esté habilitando los permisos. Entonces vamos a tener dos estatus, si el permiso you fue otorgado entonces únicamente debemos consultar el content provider de llamadas. Entonces aquí estaría nuestro método consultar content providers. Pero si checar estatus de permiso nos dejó algun falso, es decir, el permiso no ha sido otorgado, entonces debemos ejecutar el método solicitar permiso. Que el método solicitar permiso dentro de sí activa, recuerda, nuestro call back onRequestPermissionsResult. Y dentro de ste callBack aquí está llamandose nuestro content provider. Entonces en ambos casos se va ejecutar el content provider, simplemente en momentos distintos.