viernes, 20 de febrero de 2015

WebView: Cargando desde la caché

Operación a realizar

Una de las cosas que quería hacer era mostrar un enlace a una web desde la caché(siempre y cuando esa web haya sido visto con internet anteriormente).

Problema

Apenas sabía nada sobre los WebView y menos sobre como cargar un enlace desde la caché.

Búsqueda

Tanto a través de Google como de un libro que tengo "El gran libro de Android Avanzado" me puse a investigar si alguien anteriormente había intentando cargar un enlace desde la caché(obviamente sí).

Solución

Aunque me llevó un par de días hallar con la solución, en realidad es bastante simple indicar cuando quieres que intente cargar de caché.

Lo 1º es detectar si el usuario tiene tanto el WiFi como los datos del móvil activados. Si los tiene, el enlace se cargará con normalidad, pero sino tiene ninguna de las 2 es cuando podemos indicar como cargar desde la caché.

Vamos con el código de detectar si tiene o no internet y dentro habilitando caché o no:

ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Activity.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
try {
    if((info == null || !info.isConnected() || !info.isAvaliable()) {
         web.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
    } else
    {
         web.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
    }
catch(Exception e) {
     Log.e("ERROR", e.toString());
}
Con el ConnectivityMannager obtenemos el servicio que nos permite comprobar a través del NetworkInfo si tenemos WiFi o datos activados o sino los tenemos activados.

En el if se comprueba tanto si en "info"(info != null) está vacío, si no está conectado(!isConnected()) y si no tenemos disponible esa red(!isAvaliable()).

Justo dentro del if ponemos que si queremos que cargue de caché .setCacheMode(WebSettings.LOAD_CACHE_ONLY); o si cargar por defecto cuando tenemos internet(setCacheMode(WebSettings.LOAD_DEFAULT).

En internet ponen que para cargar de caché deberíamos poner (WebSettings.LOAD_CACHE_ELSE_NETWORK) que quiere decir que:
Aunque nuestros recursos de la caché hayan expirado, los vamos a utilizar si no hay internet.
Para mí es mucho mejor la solución que está en el código de antes porque aunque la que ponen por internet es buena, a mí en mi app no me cargaba todo lo que se vería si se cargara el enlace desde un navegador, y con el "LOAD_CACHE_ONLY" sí se mostraba todo.

El cargar la url del enlace(web.loadUrl("http://miweb.com"); os llega con ponerlo en el onCreate() y el resto de propiedades que le queráis poner lo poner en una función que creéis vosotros aparte.

jueves, 19 de febrero de 2015

WebView responsive de una web no responsive

Operación a realizar

Lo que quería realizar era un WebView de una página web que me gusta entrar todas las semanas.

Problema

Esa web no era responsive así que conseguir que el WebView se viera de correctamente en todos los dispositivos, necesité hacer múltiples búsquedas en internet para ver como hacer que se adaptara correctamente.

Búsqueda

Lo que más buscaba era como ver la página web en el móvil sin que tuviera ningún zoom puesto, para que nos entendamos, que la web se viera tal cual se vería desde un navegador recién instalado.
Solución

Una de las soluciones para casi todos lo móviles es utilizar estas líneas en el WebSetting del WebView:

web.setInitialScale(1);
webSet.setUseWideViewPort(true);
webSet.setLoadWithOverviewMode(true);

Vamos por partes, el setInitialScale(1); es el porcentaje de zoom que le queremos hacer.

2º el setUseWideViewPort(true); se utiliza para que si la web tiene un meta tag con el valor "viewport" coge ese valor y lo utiliza para mostrar el WebView con el tamaño que hay en ese meta tag. Si es false, la web se pone con el ancho del WebView.
En mi caso, si se pone a false, se ve la pantalla completamente en negro.

3º el webSet.setLoadWithOverviewMode(true); sirve para que el WebView salga sin zoom y así el contenido de la web que queremos mostrar encaje con el ancho de la web.

Ésto sería válido para la mayoría de lo móviles, pero en mi caso a un par de amigos se les veía con zoom la web(aunque podían quitarlo y quedaba perfectamente) y por eso seguí buscando hasta que encontré otra solución que complementa la anterior.

La solución complementaria es que en vez de cargar la url con web.loadUrl("http://miweb.com") lo que hago es un archivo index.html que lo agrego a la carpeta "assets" del proyecto.

En ese index.html tengo este código:

<html>
        <head>
               <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
               <meta name="viewport" content="user-scalable=yes"/>
               <script type="text/javascript">
                      function poponload()
                      {
                             window.open("http://miweb.com/", "_self");
                      }
               </script>
               </head>
        <body onload="javascript: poponload()">
        </body>
</html>
En ese index.html lo más importante que hago es que el meta le pongo el valor "viewport" para que así el método .setUseWidePort(true) encuentre ese meta tag y la web se pueda adaptar al móvil.

Para cargar ahora este archivo "index.html" al WebView hay que poner esta línea:

web.loadUrl("file:///android_asset/index.html");

viernes, 6 de febrero de 2015

Como evitar reinicio de actividad al girar el dispositivo.

Cuando cambiamos la orientación de nuestro dispositivo, nuestra actividad se reinicia y se vuelve a crear. Esto puede resultar molesto cuando, por ejemplo, tenemos un componente WebView en nuestra aplicación, en el que al girar el dispositivo se volvería a cargar la web.

Para evitar esto, en el AndroidManifest dentro de la etiqueta <activity> de nuestra actividad debemos añadir la siguiente línea de código:

android:configChanges="orientation|screenSize"

Como bien podemos consultar en la documentación de Android, el parámetro orientation evita que la actitividad se reinicie al girar el dispositivo, y el parámetro screenSize evita también que se recargue la pantalla al cambiar la relación de aspecto de nuestra pantalla (en la que se cambia la disposición de nuestros controles). Aunque ésto parezca redundante, hay nuevos dispositivos como por ejemplo los relojes Android Wear cuya pantalla tiene una relación de aspecto 1:1 y esta no varía al girar el dispositivo. Además también hay veces que cambiamos la relación de aspecto sin girar nuestro dispositivo, como cuando le damos a un vídeo que se vea a pantalla completa.

Otro parámetro interesante que podemos añadir además de orientation y screenSize es keyboardHidden para evitar que nuestra actividad se reinicie al mostrar y ocultar el teclado.