• No se han encontrado resultados

Servicios de la plataforma Android

N/A
N/A
Protected

Academic year: 2021

Share "Servicios de la plataforma Android"

Copied!
26
0
0

Texto completo

(1)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Servicios de la plataforma Android

Sesión 1: Librerías de

compatibilidad y servicios

(2)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Puntos a tratar

• Compatibilidad de versiones

• Fragmentos

• Loaders

• Librería de compatibilidad

• Librería de servicios de Google Play

(3)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Compatibilidad de versiones

• A mayor versión utilizada por nuestras aplicaciones

• Mayores funcionalidades y facilidades

• Menor compatibilidad

• Se especifican dos versiones

• Podemos utilizar de forma opcional funcionalidades avanzadas

• Algunas características no pueden ser utilizadas opcionalmente

• Por ejemplo los fragmentos

<uses-­‐sdk  android:minSdkVersion="4"  android:targetSdkVersion="17"  />

if  (Build.VERSION.SDK_INT  >=  Build.VERSION_CODES.HONEYCOMB)  {        //  Utilizar  características  de  Android  3.0  (Honeycomb) }

(4)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Fragmentos

Característica introducida en Android 3.0 (Honeycomb)

Orientada a la introducción de tablets

• Forma recomendada de estructurar la interfaz

• Nos permiten construir la interfaz de forma modular

• Una actividad puede mostrar varios fragmentos

• Según el tipo de dispositivo se puede variar la disposición

(5)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Creación de fragmentos

• Se crean heredando de Fragment

• Debemos definir el método onCreateView donde contruimos la interfaz

Normalmente la construimos a partir de un layout XML

• No es una actividad, pero puede que necesitemos tener acceso a la actividad contenedora

• Existen fragmentos especializados

• ListFragment, DialogFragment, PreferencesFragment

public  class  DetalleFragment  extends  Fragment  {        @Override

       public  View  onCreateView(LayoutInflater  inflater,  

                                         ViewGroup  container,  Bundle  savedInstanceState)  {                return  inflater.inflate(R.layout.fragmento,  container,  false);

       } }

Button  boton  =  (Button)getActivity().findViewById(R.id.boton);

(6)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Ciclo de vida de los fragmentos

(7)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Añadir el fragmento a la actividad

• Los fragmentos siempre deben estar dentro de una actividad

• Existen dos formas de añadirlos:

Estática

Se añaden en el layout XML

• No pueden ser modificados en tiempo de ejecución

Varios fragmentos al mismo tiempo en pantalla (tablets)

Dinámica

• Se añaden desde el código de la actividad

• Podemos hacer transiciones entre fragmentos

• Útil para dispositivos en los que no se pueden mostrar todos en la

misma pantalla

(8)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Fragments estáticos

Se definen en el layout XML de la actividad

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"

       android:orientation="horizontal"

       android:layout_width="fill_parent"

       android:layout_height="fill_parent">

 

       <fragment  android:name="es.ua.jtech.fragments.PrincipalFragment"

                           android:id="@+id/principal_fragment"

                           android:layout_weight="1"

                           android:layout_width="0dp"

                           android:layout_height="match_parent"  />

 

       <fragment  android:name="es.ua.jtech.fragments.DetalleFragment"

                           android:id="@+id/detalle_fragment"

                           android:layout_weight="2"

                           android:layout_width="0dp"

                           android:layout_height="match_parent"  />

 

</LinearLayout>

(9)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Fragments dinámicos

Definimos en el layout de la actividad un marco vacío

• Si el marco existe, añadimos el fragmento al crear la actividad

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"

       android:id="@+id/fragment_container"

       android:layout_width="match_parent"

       android:layout_height="match_parent"  />

public  class  MainActivity  extends  Activity  {

       public  void  onCreate(Bundle  savedInstanceState)  {                super.onCreate(savedInstanceState);

               setContentView(R.layout.news_articles);

               if  (findViewById(R.id.fragment_container)  !=  null)  {                        if  (savedInstanceState  !=  null)  {

                               return;

                       }

                       PrincipalFragment  ppalFragment  =  new  PrincipalFragment();

                       ppalFragment.setArguments(getIntent().getExtras());

                       getFragmentManager().beginTransaction()

                               .add(R.id.fragment_container,  ppalFragment).commit();

               }        }

Comprobamos si existe el contenedor Si venimos de

una instancia anterior no hace falta volver a

construir

Mostramos el fragmento con

FragmentManager

(10)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Transiciones entre fragmentos

• En caso de haber añadido el fragmento de forma dinámica, podemos hacer transiciones a otro fragmento

DetalleFragment  detalleFragment  =  new  DetalleFragment();

 

//  Pasamos  parametros  al  nuevo  fragmento Bundle  args  =  new  Bundle();

args.putInt(PARAM_POSICION,  posicionSeleccionada);

detalleFragment.setArguments(args);

 

FragmentTransaction  transaction  =  getFragmentManager()

                                                                                       .beginTransaction();

 

transaction.replace(R.id.fragment_container,  detalleFragment);

transaction.addToBackStack(null);

 

transaction.commit();

(11)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Comunicación entre fragmentos

• Siempre se hará a través de la actividad contenedora

Definimos un callback en uno de los fragmentos

public  class  PrincipalFragment  extends  ListFragment  {        OnItemSelectedListener  mCallback;

 

       public  interface  OnItemSelectedListener  {

               public  void  onItemSelected(int  position);

       }  

       @Override

       public  void  onAttach(Activity  activity)  {                super.onAttach(activity);                  

               try  {

                       mCallback  =  (OnItemSelectedListener)  activity;

               }  catch  (ClassCastException  e)  {

                       throw  new  ClassCastException(activity.toString()

                                       +  "  debe  implementar  OnItemSelectedListener");

               }        }

       ...

}

Comprueba que la actividad implemente la interfaz

La actividad debe

implementar esta

interfaz

(12)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Gestión de la comunicación

En la actividad implementamos la comunicación en el listener

public  static  class  MainActivity  extends  Activity

               implements  PrincipalFragment.OnItemSelectedListener  {        ...

       public  void  onItemSelected(int  position)  {    

               DetalleFragment  detalleFragment  =  (DetalleFragment)

                     getFragmentManager().findFragmentById(R.id.detalle_fragment);

 

               if  (detalleFragment  !=  null)  {

                       detalleFragment.setDetalleItem(position);

               }  else  {

                       detalleFragment  =  new  DetalleFragment();

                       Bundle  args  =  new  Bundle();

                       args.putInt(PARAM_POSICION,  position);

                       detalleFragment.setArguments(args);

                 

                       FragmentTransaction  transaction  =  getFragmentManager().beginTransaction();

                       transaction.replace(R.id.fragment_container,  detalleFragment);

                       transaction.addToBackStack(null);

                       transaction.commit();

Tipo estático

Tipo dinámico

Comprobamos

si el fragmento

está en pantalla

(13)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Creación de diálogos

• La forma recomendada de crear diálogos es con fragmentos

• Se crean mediante fragmentos de tipo DialogFragment

• Se puede especificar el título de la ventana del diálogo

• Tiene un método show para mostrarlos

public  View  onCreateView(LayoutInflater  inflater,  ViewGroup  container,                Bundle  savedInstanceState)  {

 

       View  view  =  inflater.inflate(R.layout.dialog,  container);

       getDialog().setTitle("Título");

         

       return  view;

}

FragmentManager  manager  =  getFragmentManager();

MiDialogFragment  dialog  =  new  MiDialogFragment();

dialog.setArguments(bundle);

dialog.show(manager,  "fragment_dialog");

(14)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Loaders

• Se trata de otra característica introducida en Android 3.0

• Gestiona la carga de datos por parte de actividades/fragmentos

• Normalmente carga datos de proveedores de contenidos o servicios web

• Inicia el proceso de carga si no está ya en marcha

• Si detecta un cambio en los datos, los vuelve a recuperar

• Lo iniciamos normalmente en onCreate

• También podemos solicitar reiniciar la carga

getLoaderManager().initLoader(0,  null,  this);

getLoaderManager().restartLoader(0,  null,  this);

(15)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Métodos a definir en el callback

Al implementar el callback se debe especificar el tipo de datos a utilizar

• Utilizamos genéricos

• Los métodos que debemos definir son los siguientes

public  class  MiListFragment  extends  ListFragment

               implements  LoaderManager.LoaderCallbacks<Tipo>  {        ...

 

       public  Loader<Tipo>  onCreateLoader(int  id,  Bundle  args)  {  ...  }  

       public  void  onLoadFinished(Loader<Tipo>  loader,  Cursor  data)  {  ...  }  

       public  void  onLoaderReset(Loader<Tipo>  loader)  {  ...  }  

}

(16)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Callback del loader

• Debemos indicar cómo construir el objeto Loader

• También debemos definir qué hacer cuando obtengamos datos

• Y por último, la forma de reiniciar el contenido

public  Loader<Cursor>  onCreateLoader(int  id,  Bundle  args)  {

       return  new  CursorLoader(getActivity(),  baseUri,  proyeccion,                                                          seleccion,  args,  orden);

}

public  void  onLoadFinished(Loader<Cursor>  loader,  Cursor  data)  {        mAdapter.swapCursor(data);

}

public  void  onLoaderReset(Loader<Cursor>  loader)  {        mAdapter.swapCursor(null);

}

(17)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Loader personalizado

Podemos crear nuestro propio tipo de loader

• Normalmente lo hacemos con una subclase de AsyncTaskLoader

• Debemos implementar el proceso de carga de forma similar a una async task

static  class  MiLoader  extends  AsyncTaskLoader<Tipo>  

{

       Tipo  mDatos  =  null;

         

       public  MiLoader(Context  context)  {                super(context);

       }  

       @Override

       public  Tipo  loadInBackground()  {                return  cargarDatos();

       }        ...

}

Descarga los datos en background

Especificamos el tipo

de los datos a obtener

(18)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Otros métodos de AsyncTaskLoader

static  class  MiLoader  extends  AsyncTaskLoader<Tipo>  {        Tipo  mDatos  =  null;

       ...

       @Override  protected  void  onStartLoading()  {                super.onStartLoading();

               if(mDatos  !=  null)  {

                       deliverResult(mDatos);

               }  else  {

                       forceLoad();                                

               }        }  

       @Override  public  void  deliverResult(Tipo  data)  {                mDatos  =  data;

               super.deliverResult(data);

       }      

       @Override  protected  void  onStopLoading()  {                super.onStopLoading();

               cancelLoad();

       }      

       @Override  protected  void  onReset()  {                super.onReset();

Comprobamos si tenemos los datos ya descargados o si hay que cargarlos

“Entregamos” los

datos, y los retenemos

Cancelamos la descarga

Borramos los

(19)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Uso del loader

Podemos utilizar el loader definido desde nuestro callback

public  class  MiFragmento  implements  LoaderManager.LoaderCallbacks  {          ...

 

       public  Loader<Tipo>  onCreateLoader(int  id,  Bundle  args)  {                  return  new  MiLoader(getActivity());  

       }            

       public  void  onLoadFinished(Loader<Tipo>  loader,  Tipo  data)  {                mAdapter.clear();

               for(Item  item:  data)  {                        mAdapter.add(item);

               }        }            

       public  void  onLoaderReset(Loader<Tipo>  loader)  {                  mAdapter.clear();

       }             }

Introduce los datos

cargados en el adaptador

(20)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Librería de compatibilidad

Fragmentos y loaders son características importantes

• Es importante seguir dando soporte a dispositivos antiguos

• Existen librerías de compatibilidad

• Incorporan estas características a dispositivos a partir de 1.6

(21)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Uso de la librería de compatibilidad

• Copiamos la librería de compatibilidad al directorio libs

Utilizamos los imports de la librería de compatibilidad

• La actividad debe heredar de FragmentActivity

Usamos métodos alternativos para obtener los managers

$ANDROID_SDK/extras/android/support/v4/android-­‐support-­‐v4.jar

import  android.support.v4.app.Fragment;

import  android.support.v4.app.FragmentManager;

import  android.support.v4.app.FragmentTransaction;

import  android.support.v4.app.LoaderManager;

public  class  MainActivity  extends  FragmentActivity  {        ...

}

FragmentManager  manager  =  getSupportFragmentManager();

LoaderManager  manager  =  getSupportLoaderManager();

(22)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Librerías de servicios

• Podemos también añadir librerías para acceso a servicios

• Los servicios de Google se añaden mediante librería externa

• Aporta mayor flexibilidad para suministrar actualizaciones

Debemos descargar la librería desde Google Play

• Soporta Android 2.2 y superiores

• Para desarrollar un proyecto con ella debemos

Descargar la librería de servicios Google Play con SDK Manager

Importar la librería (Existing Android Code into Workspace)

$ANDROID_SDK/extras/google/google_play_services/

(23)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Configuración de los permisos

• Añadir permisos para los servicios

<uses-­‐permission  android:name="android.permission.INTERNET"/>

<uses-­‐permission  android:name=

       "android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-­‐permission  android:name=

       "com.google.android.providers.gsf.permission.READ_GSERVICES"/>

<uses-­‐permission  android:name=

       "android.permission.ACCESS_COARSE_LOCATION"/>

<uses-­‐permission  android:name=

       "android.permission.ACCESS_FINE_LOCATION"/>

<permission

       android:name="es.ua.jtech.permission.MAPS_RECEIVE"

       android:protectionLevel="signature"/>

<uses-­‐permission  android:name="es.ua.jtech.permission.MAPS_RECEIVE"/>

Sustituimos es.ua.jtech por el

paquete de nuestra aplicación

(24)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Clave de desarrollador y OpenGLES 2.0

Google Maps v2 necesita OpenGLES 2.0

Se debe indicar en el manifest

• También debemos indicar nuestra clave de desarrollador

• La obtendremos de la siguiente dirección

<uses-­‐feature

   android:glEsVersion="0x00020000"

   android:required="true"/>

<meta-­‐data

       android:name="com.google.android.maps.v2.API_KEY"

       android:value="pon_aqui_tu_clave"/>

https://developers.google.com/maps/documentation/android/start#the_google_maps_api_key

(25)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

Integración del mapa

Podemos añadirlo al layout como fragmento

• También podemos utilizar la librería de compatibilidad

<?xml  version="1.0"  encoding="utf-­‐8"?>

<fragment  xmlns:android="http://schemas.android.com/apk/res/android"

   android:id="@+id/map"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   class="com.google.android.gms.maps.MapFragment"/>

<?xml  version="1.0"  encoding="utf-­‐8"?>

<fragment  xmlns:android="http://schemas.android.com/apk/res/android"

   android:id="@+id/map"

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   class="com.google.android.gms.maps.SupportMapFragment"/>

(26)

Experto en Desarrollo de Aplicaciones para Dispositivos Móviles

¿Preguntas...?

Referencias

Documento similar

El cambio en la percepción del valor total de los bosques y como deben ser utilizados está marcado por una concienciación creciente sobre la importancia de los servicios ambientales

Casos de coordinacidn econdmica los tenemos, principalmente, entre el ferrocarril y la carretera, cuando ambos se reparten los trâficos entre al mismo origen y el mismo

Para la evaluación de su solicitud de seguro y selección de riesgos y, en su caso, emisión del contrato de seguro, trámite a sus solicitudes de pago de siniestros,

Cuando a consecuencia de cualquier hecho accidental como pérdida, extravío o robo de llaves o inutilización de la cerradura por intento de robo del DOMICILIO del afiliado, no

• La cafeterías prestará sus servicios en horario fijado por la empresa concesionaria. • Se restringe el acceso y uso de los servicios de cafetería y comedor

Potenciar la implicaci ó ó n de todos los empleados p n de todos los empleados p ú ú blicos y estamentos de  blicos y estamentos de 

– Aviso previo al Decano/Director del Centro o Servicio – Presentación del actuario al Responsable del Centro – Actuaciones para verificar la actividad administrativa –

La Carta de Servicios de la AEMPS es el documento que informa a la ciudadanía y a las personas usuarias sobre los servicios que tiene encomendados, sobre los dere- chos que