Desarrollo de aplicaciones para dispositivos móviles Android
Almacenamiento local
Johnattan Jaramillo G.
jjaramillo238@misena.edu.co
Contenido del curso
1- Introducción
2- Layouts y widgets
3- Actividades y fragmentos
4- Almacenamiento local
5- Almacenamiento remoto
6- Material design
7- Publicación y marketing de apps
ALMACENAMIENTO LOCAL
- Contenedores
- DataStorage
- SQLite
- Ejercicio
Contenedores
Listview
Es un grupo de vistas (ViewGroup) que muestra una lista de elementos desplazable
Definición
Listview
Adaptadores
Los elementos de la lista son insertados de un origen de datos usando un adaptador de clase (Class Adapter)
Origen de Datos
Adaptador
ListView
Listview
Adaptadores
ORIGEN DE DATOS (DATA SOURCE)
- Es responsable de indicar de donde se obtienen los datos
- Puede ser desde un arreglo hasta una base de datos
ADAPTADOR (ADAPTER)
- Es responsable de construir una vista para cada elemento de la lista obtenido desde el origen de datos
- Actúa como puente entre el ListView y el DataSource
VISTA DE ADAPTADOR (LISTVIEW)
- Es responsable de presentar la lista de elementos al usuario
Listview
1- Definir el origen de datos (array)
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, dias);
2- Definir el adaptador y proporcionarle
- Origen de datos
- Layout de una vista simple (layout por defecto disponible en Android para mostrar un listview)
String[] dias = {"Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"};
3- Establecer el adaptador del ListView
ListView lv = (ListView) findViewById(R.id.idListView);
lv.setAdapter(adapter);
Implementación
Listview
4- Asociar un onItemClickListener para definir que acción se debería ejecutar al momento de dar click sobre un elemento de la lista
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView adapterView, View view, int i, longo l){
//Acciónes a ejecutar al seleccionar el elemento
}
}
Implementación
Listview personalizado
- Los ListView Personalizados (Custom ListView) son usados para mostrar más de una vista en cada fila
- Por defecto, los adaptadores (ArrayAdapter) asumen cada fila en la lista de elementos como un elemento de texto simple (TextView).
- El layout por defecto para mostrar listas en Android (android.R.layout.simple_list_item_1) usa una vista simple (TextView) para cada fila
- Si queremos mostrar más de una vista en cada fila necesitamos crear nuestro propio layout
Definición
Listview personalizado
1- Preparar los orígenes de datos
2- Crear un layout personalizado (custom_row.xml) el cual definirá como los elementos de la lista aparecerán en cada fila.
String[] artistas = {"Nach","ZPU","Canserbero","Lil Supa","Rocca"};
String[] descripciones = {"MC Español","MC Español","MC Venezolano","MC Venezolano","MC Colombiano"};
int [] imagenes ={R.drawable.img1,R.drawable.img2,R.drawable.img3,R.drawable.img4,R.drawable.img5};
Implementación
Listview personalizado
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView android:id="@+id/idImagen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<TextView android:id="@+id/idArtista"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Artista"
android:textSize="20sp"
android:layout_toRightOf="@id/idImagen"/>
<TextView android:id="@+id/idDescripcion"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Descripción"
android:layout_below="@id/idArtista"
android:layout_toRightOf="@id/idImagen"/>
</RelativeLayout>
Implementación
Listview personalizado
3- Definir un adaptador personalizado (Custom Adapter) que extienda el adaptador por defecto (Array Adapter) ya que el adaptador por defecto muestra solo un TextView en cada fila
Implementación
4- Crear una clase de Java (Custom Adapter) que extienda de la clase del adaptador por defecto (Array Adapter)
5- Sobrescribir el constructor por defecto del adaptador por defecto (Array Adapter)
6- Inflar el layout personalizado en el método getView() el cuál obtendrá la vista de una posición específica
7- Obtener referencias a objetos de la vista (XML) y asignarle a cada uno un elemento de la lista (Data Source)
Listview personalizado
class MyAdapter extends ArrayAdapter{
int[] arrayImagenes;
String[] arrayArtistas;
String[] arrayDescripciones;
public MyAdapter(Context context, String[] artistas, String[] descripciones, int[] imagenes){
//Sobrescribir el constructor por defecto del ArrayAdapter
super(context, R.layout.custom_row,R.idArtista,artistas);
this.arrayImagenes = imagenes;
this.arrayArtistas = artistas;
this.arrayDescripciones = descripciones;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent){
//Inflar el layout
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.custom_row,parent,false);
//Obtener la referencia a los objetos de la vista
ImageView myImage = (ImageView) row.findViewById(R.id.idImagen);
TextView myArtist = (TextView) row.findViewById(R.id.idArtista);
TextView myDescription = (TextView) row.findViewById(R.id.idDescripcion);
//Proporcionar un elemento del arreglo especificando su posición
myImage.setImageResource(arrayImagenes[position]);
myArtist.setText(arrayArtistas[position]);
myDescription.setText(arrayDescripciones[position]);
return row;
}
}
Implementación
Listview personalizado
Implementación
MyAdapter adapter = new MyAdapter (this, artistas, descripciones, imagenes);
8- Definir el adaptador personalizado y proporcionarle sus parámetros
9- Establecer el adaptador del ListView
ListView lv = (ListView) findViewById(R.id.idListView);
lv.setAdapter(adapter);
Listview Expandible
- Los ListView Expandibles (Expandable ListView) son usados para agrupar los elementos de la lista en categorías
- Por defecto, los ListView solo muestran un grupo de elementos de una lista
Definición
Listview expandible
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<ExpandableListView android:id="@+id/idListView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Implementación
1- Crear archivo XML con el ExpandableListView
Listview expandible
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<TextView android:id="@+id/idTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Title"
android:padding="2dp"/>
</RelativeLayout>
Implementación
2- Crear archivo XML para mostrar el encabezado de categorías (Categories header)
Listview expandible
<?xml version="1.0" encoding="utf-8" ?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<TextView android:id="@+id/idChildItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Child"
android:padding="2dp"/>
</RelativeLayout>
Implementación
3- Crear archivo XML para mostrar los elementos de cada categoría (Categories items)
Listview expandible
Implementación
4- Crear una clase de Java (Adapter Class) que extienda de la clase base del adaptador de lista expandible (BaseExpandableListAdapter) e implemente todos sus métodos
package sena.android.com.expandablelistview;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
public class MyAdapter extends BaseExpandableListAdapter{
@Override
public int getGroupCount(){
return 0;
}
@Override
public int getChildrenCount(int i){
return 0;
}
@Override
public Object getGroup(int i){
return null;
}
@Override
public Object getChild(int i, int i1){
return null;
}
@Override
public Object getGroupId(int i){
return 0;
}
@Override
public Object getChildId(int i, int i1){
return 0;
}
@Override
public boolean hasStableIds(){
return false;
}
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewgroup){
return null;
}
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewgroup){
return null;
}
@Override
public boolean isChildSelectable(int i, int i1){
return false;
}
}
Listview expandible
Implementación
5- Sobrescribir el constructor por defecto (Default Constructor) de la clase adaptador (Adapter Class) con tres parámetros
- Context
- Listado de ChildViews (o HashMap)
- Listado de HeaderViews
private Context ctx;
private HashMap<String,List<String>> ChildTitles;
private List<String> HeaderTitles;
MyAdapter(Context ctx, HashMap<String,List<String>> ChildTitles, List<String> HeaderTitles){
this.ctx=ctx;
this.ChildTitles = ChildTitles;
this.HeaderTitles = HeaderTitles;
}
Listview expandible
Implementación
6- Pasar la cuenta del encabezado de categorías (Categories header) en el método getGroupCount()
public int getGroupCount(){
return HeaderTitles.size();
}
7- Pasar la cuenta de los elementos de las categorías (Categories items) de cada encabezado de grupo (Group header) en el método getChildrenCount()
public int getChildrenCount(int i){
return ChildrTitles.get(HeaderTitles.get(i)).size();
}
Listview expandible
Implementación
8- Pasar la posición de cada vista de encabezado (Header view)
public Object getGroup(int i){
return HeaderTitles.get(i);
}
9- Pasar la posición de cada elemento hijo (Children) para cada vista de encabezado (Header view) respectiva
public int getChild(int i, int i1){
return ChildTitles.get(HeaderTitles.get(i)).get(i1);
}
Listview expandible
Implementación
10- Inflar el layout para la vista de encabezado (HeaderView) y las vistas de elementos (ChildViews).
Convertir las vistas XML en objetos de Java
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup){
String title = (String) this.getGroup(i);
if(view == null){
LayoutInflater inflater = (LayoutInflater) this.ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_header, null);
}
TextView txt = (TextView) view.findViewById(R.id.idTitle);
txt.setTypeface(null, Typeface.BOLD);
txt.setText(title);
return view;
}
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup){
String child = (String) this.getChild(i, i1);
if(view == null){
LayoutInflater inflater = (LayoutInflater) this.ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.custom_child, null);
}
TextView txt = (TextView) view.findViewById(R.id.idChildItem);
txt.setText(child);
return view;
}
Listview expandible
Implementación
11- Crear el proveedor de datos (DataProvider) para proporcionar la información a las vistas
public class DataProvider {
public static HashMap> getInfo(){
HashMap> HeaderDetails = new HashMap>();
List ChildDetails1 = new ArrayList();
ChildDetails1.add("This id Children11");
ChildDetails1.add("This id Children12");
ChildDetails1.add("This id Children13");
ChildDetails1.add("This id Children14");
List ChildDetails2 = new ArrayList();
ChildDetails2.add("This id Children21");
ChildDetails2.add("This id Children22");
ChildDetails2.add("This id Children23");
ChildDetails2.add("This id Children24");
List ChildDetails3 = new ArrayList();
ChildDetails3.add("This id Children31");
ChildDetails3.add("This id Children32");
ChildDetails3.add("This id Children33");
ChildDetails3.add("This id Children34");
List ChildDetails4 = new ArrayList();
ChildDetails4.add("This id Children41");
ChildDetails4.add("This id Children42");
ChildDetails4.add("This id Children43");
ChildDetails4.add("This id Children44");
HeaderDetails.put("Header 1",ChildDetails1);
HeaderDetails.put("Header 2",ChildDetails2);
HeaderDetails.put("Header 3",ChildDetails3);
HeaderDetails.put("Header 4",ChildDetails4);
return HeaderDetails;
}
}
Listview expandible
Implementación
MyAdapter adapter = new MyAdapter (this, myHeader, MyChild);
13- Definir el adaptador personalizado y proporcionarle sus parámetros
14- Establecer el adaptador del ListView
ExpandableListView expList = (ExpandableListView ) findViewById(R.id.idListView);
expList.setAdapter(adapter);
HashMap> myHeader = DataProvider.getInfo();
List myChild = new ArrayList(myHeader.keySet());
12- Preparar origen de datos (Data Source)
GridView
- Son ViewGroups que disponen los elementos en una rejilla bidimensional desplazable
- Los elementos son insertados automáticamente al layout usando un adaptador (Adapter)
- Son similares a los ListView
Definición
Gridview
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<GridView android:id="@+id/idGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2"/>
</LinearLayout>
Implementación
1- Agregar el GridView en el archivo XML
Gridview
String[] data = {"data1","data2","data3","data4","data5","data6","data7","data8"};
Implementación
2- Crear el origen de datos (Data Source) para el GridView en la actividad (Activity)
3- Instanciar el GridView XML en un objeto de Java
GridView gridView = (GridView) findViewById(R.id.idGridView);
4- Definir un adaptador (Adapter) para el GridView y asignárselo
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout_simple_list_item1,data);
gridView.setAdapter(adapter);
WebView
- Es una vista que presenta una página web al interior de un contenedor, esto permite que nuestra aplicación se convierta en una aplicación web
- Véase
- Aplicaciones híbridas
- Ionic 2
Definición
Webview
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<WebView android:id="@+id/idWebView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
Implementación
1- Agregar el elemento <WebView> en el archivo XML
Webview
WebView browser = (WebView) findViewById(R.id.idWebView);
Implementación
2- Instanciar el WebView XML en un objeto de Java
3- Asignar la URL del WebView
browser.loadUrl("https://www.google.com.co");
Webview
Permisos
- Si se desea acceder a un archivo alojado en un servidor se necesitará de una conexión a internet
- En estos casos, es necesario incluir el permiso de conexión en el archivo AndroidManifest.xml de la siguiente manera
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Webview
JavaScript
- JavaScript se encuentra deshabilitado en el WebView por defecto
- Se puede habilitar a través de los WebSettings del WebView
- Los WebSettings se pueden recuperar con el método getSettings() y entonces habilitar JavaScript usando el método setJavaScriptEnabled() de la siguiente manera
WebView browser = (WebView) findViewById(R.id.idWebView);
WebSettings webSettings = browser.getSettings();
webSettings.setJavaScriptEnabled(true);
SearchView
Es una vista que proporciona una interfaz de usuario que permite ingresar una búsqueda y enviar la solicitud a un proveedor de búsquedas
Definición
SearchView
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/idLayout">
<SearchView android:id="@+id/idSearchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false">
<requestFocus />
</SearchView>
</LinearLayout>
Implementación
1- Agregar el elemento <SearchView> en el archivo XML
SearchView
SearchView searchView = (SearchView) findViewById(R.id.idSearchView);
Implementación
2- Instanciar el SearchView XML en un objeto de Java
3- Ejecutar la consulta y agregar el método setOnQueryTextListener() al searchView
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
@Override
public boolean onQueryTextSubmit(String s){
return false;
}
@Override
public boolean onQueryTextChange(String s){
return false;
}
});
Data Storage
Android proporciona diferentes opciones para manejar la persistencia de los datos de la aplicación
Depende de las necesidades, escogeremos que opción de almacenamiento es más conveniente para los nuestros datos
Data Storage
Preferencias compartidas
Almacena información privada en pares clave-valor
Almacenamiento Interno
Almacena información privada en la memoria del dispositivo
Almacenamiento Externo
Almacena información pública en el almacenamiento externo compartido
Base de datos SQLite
Almacena información estructurada en una base de datos privada. Permite guardar la información en tablas relacionadas
Remoto
Almacena información en tu propio servidor
Preferencias compartidas
- Para recuperar un valor (value) de las preferencias compartidas debemos solicitarla a través de su clave (key)
- Los datos persistirán a lo largo de las sesiones (incluso si la aplicación se cierra)
Shared preferences
Almacena información privada en pares clave-valor
Usuario
Contraseña
admin
123
Clave (key)
Valor (value)
Preferencias compartidas
data/data/<nombre_paquete>/shared-prefs
Ubicación
La información se almacena en un archivo XML en el directorio
Tipos de datos
- Boolean
- Int
- Float
- Long
- String
Shared preferences
Preferencias compartidas
Acceso
Existen dos métodos para obtener un objeto con las preferencias de usuario
-
getSharedPreferences(String name, int mode)
- Se usa cuando se necesitan múltiples archivos de preferencias (identificados por un nombre). El nombre se especifica en el primer parámetro
-
getPreferences(int mode)
- Se usa cuando solo se necesita un archivo de preferencias. Como solo existe un archivo de preferencias, no es necesario especificar su nombre
Preferencias compartidas
Modos
Modos de operación
MODE_PRIVATE
0 - Por defecto. Solo la aplicación puede acceder al archivo
Modo
Uso
MODE_READABLE
MODE_WRITEABLE
MODE_MULTI_PROCESS
Todas las aplicaciones pueden leer el archivo
Todas las aplicaciones pueden escribir el archivo
Múltiples procesos pueden modificar el mismo archivo de preferencias compartidas
Preferencias compartidas
Usos
- Verificar si un usuario está usando tu aplicación
- Verificar cuando fue actualizada tu aplicación
- Recordar credenciales de usuario
- Recordar configuraciones de usuario
- Caché de ubicaciones
getPreferences(int mode);
Guardar información
1- Obtener una referencia al objeto de preferencias compartidas
Preferencias compartidas
getSharedPreferences(String name, int mode);
- Para un archivo simple
- Para varios archivos
2- Llamar al editor
SharedPreference.Editor editor = sharedpreferences.edit();
editor.putString("nombre","johnattan");
editor.putString("contraseña","ultrasecreta");
Guardar información
3- Usar el editor para agregar información en pares clave-valor
Preferencias compartidas
4- Ejecutar los cambios del editor
editor.commit();
getPreferences(int mode);
Obtener información
1- Obtener una referencia al objeto de preferencias compartidas
Preferencias compartidas
getSharedPreferences(String name, int mode);
- Para un archivo simple
- Para varios archivos
Obtener información
2- Usar la clave (key) proporcionada previamente para obtener el valor (value)
Preferencias compartidas
3- Proporcionar un valor por defecto en caso que el valor no se encuentre
String nombre = sharedPreferences.getString("nombre","N/A");
String contraseña = sharedPreferences.getString("contraseña","N/A");
Almacenamiento interno
Internal Storage
- Guarda archivos directamente en el almacenamiento interno del dispositivo
- Por defecto, los archivos son privados para la aplicación, es decir, otras aplicaciones no pueden acceder a éstos
- Los archivos son borrados cuando el usuario desinstala la aplicación
Almacenamiento Interno
data/data/<nombre_paquete>/files
Ubicación
La información se almacena en un archivo XML en el directorio
Tipos de datos
- Archivos de texto
- Archivos de imagen
- Archivos de video
- Archivos de audio
Shared preferences
Escribir información
1- Llamar al método openFileOutput(String filename, int mode) especificando:
- Nombre del archivo
- Modo de operación
Este retorna un FileOutputStream
Almacenamiento interno
Crear y escribir un archivo privado en el almacenamiento interno
Escribir información
Almacenamiento interno
Context.MODE_PRIVATE
0 - Por defecto. Solo la aplicación puede acceder al archivo
Modo
Uso
Agregar información al contenido existente
Context.MODE_APPEND
Escribir información
2- Escribir en el archivo usando el método write()
Almacenamiento interno
3- Cerrar el flujo de escritura usando el método close()
String FILENAME = "archivo_prueba";
String string = "Hola mundo!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Leer información
1- Llamar al método openFileInput(String filename) especificando:
- Nombre del archivo
Este retorna un FileInputStream
Almacenamiento interno
2- Leer los bytes del archivo usando el método read(). La lectura se ejecuta byte por byte para agregar cada caracter
3- Cerrar el flujo de lectura usando el método close()
Leer información
Almacenamiento interno
FileInputStream fis = openFileInput(FILENAME);
int read = -1;
StringBuffer buffer = new StringBuffer();
read = fis.read();
while( read != -1){
buffer.append((char) read);
}
fis.close();
Almacenamiento externo
External Storage
- Guarda u obtiene información desde un dispositivo de memoria externo (Memoria SD)
- Por defecto, los archivos guardados en el almacenamiento externo son públicos y pueden ser modificados por el usuario cuando este habilite la transferencia de archivos al computador
Escribir información
1- Agregar permisos
Almacenamiento externo
WRITE_EXTERNAL_STORAGE
- Para lectura
- Para escritura
- Para lectura y escritura
READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
Agregar en el archivo AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Escribir información
2- Verificar disponibilidad de acceso al almacenamiento
Almacenamiento externo
Llamar al método getExternalStorageState() para verificar si el acceso al almacenamiento está disponible
//Disponible para escritura
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
//Disponible para lectura
public boolean isExternalStorageReadable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
Escribir información
3- Obtener los archivos del directorio usando los métodos
Almacenamiento externo
a- getExternalStorageFilesDir(String type)
Archivos específicos a tu app, son eliminados al desinstalarla
File folder = getExternalStorageFilesDir("MyFolder");
File myfile = new File(folder, "mydata.txt");
Escribir información
3- Obtener los archivos del directorio usando los métodos
Almacenamiento externo
b- getExternalStoragePublicDirectory(String type)
Archivos no específicos a tu app, son deberían ser eliminados al desinstalarla
File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File myfile = new File(folder, "mydata.txt");
Escribir información
4- Usar el FileInputStream y el FileOutputStream para realizar la operación requerida
Almacenamiento externo
String string = "Hola mundo!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Leer información
1- Obtener los archivos del directorio usando los métodos
Almacenamiento externo
a- getExternalStorageFilesDir(String type)
Archivos específicos a tu app, son eliminados al desinstalarla
File folder = getExternalStorageFilesDir("MyFolder");
File myfile = new File(folder, "mydata.txt");
Leer información
1- Obtener los archivos del directorio usando los métodos
Almacenamiento externo
b- getExternalStoragePublicDirectory(String type)
Archivos no específicos a tu app, son deberían ser eliminados al desinstalarla
File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File myfile = new File(folder, "mydata.txt");
Leer información
Almacenamiento externo
FileInputStream fis = openFileInput(FILENAME);
int read = -1;
StringBuffer buffer = new StringBuffer();
read = fis.read();
while ( read != -1) {
buffer.append((char) read);
}
fis.close();
2- Leer los bytes del archivo usando el método read(). La lectura se ejecuta byte por byte para agregar cada caracter
3- Cerrar el flujo de lectura usando el método close()
Almacenamiento en caché
Cache Storage
- Guarda datos de la aplicación en la memoria RAM
- Por defecto, los datos guardados en el almacenamiento en caché no son permanentes y son borrados automáticamente por el sistema si siente que se encuentra escaso de memoria RAM
Almacenamiento en caché
data/data/<nombre_paquete>/cache
Ubicación
La información se almacena en un archivo XML en el directorio
Cache Storage
Almacenamiento en caché
Guardar datos
1- Usar el método getCacheDir() para abrir un archivo (File) que represente el directorio interno donde tu aplicación debería guardar los archivos (en caché)
2- Usar la clase archivo (File) para crear un archivo dentro de la carpeta cache
3- Llamar al método openFileOutput(String filename) con el nombre del archivo
Almacenamiento en caché
Obtener datos
1- Usar el método getCacheDir() para abrir un archivo (File) que represente el directorio interno donde tu aplicación debería leer los archivos (en caché)
2- Obtener el archivo usando la clase archivo (File) especificando su nombre
3- Usar la clase FileInputStream para leer la información de los archivos
SQLite
Database
- Base de datos de código abierto
- Ligera
- Soporta todas las características pertenecientes a las bases de datos relacionales (Sintaxis SQL, transacciones y sentencias precompiladas)
- Se encuentra embebida en el sistema operativo Android (no requiere instalación)
data/data/<nombre_paquete>/databases
Ubicación
La información se almacena en un archivo XML en el directorio
SQLite
Crear base de datos y tabla
1- Crear una nueva clase de Java llamada DataBaseHelper
2- Extender la clase con SQLiteOpenHelper
public class DataBaseHelper extends SQLiteOpenHelper{
}
public class DataBaseHelper extends SQLiteOpenHelper{
@Override
public void onCreate(SQLiteDatabase db){
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
}
}
3- Implementar los métodos
SQLite
Crear base de datos y tabla
4- Crear el contructor por defecto
5- Definir el nombre de la base de datos y la tabla
public static final String DATABASE_NAME = "Empresa.db";
public static final String TABLE_NAME = "tblEmpleado";
public class DataBaseHelper extends SQLiteOpenHelper{
public DataBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db){
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
}
}
SQLite
Crear base de datos y tabla
6- Definir los nombres de las columnas (campos de la tabla)
public static final String COL_1 = "ID";
public static final String COL_2 = "NOMBRE";
public static final String COL_3 = "APELLIDO";
public class DataBaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "Empresa.db";
public static final String TABLE_NAME = "tblEmpleado";
public static final String COL_1 = "ID";
public static final String COL_2 = "NOMBRE";
public static final String COL_3 = "APELLIDO";
public DataBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version){
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db){
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
}
}
El código luce así hasta ahora
SQLite
Crear base de datos y tabla
7- Modificar el constructor para tomar solo el nombre de la base de datos y la versión para la superclase (Context.Provide)
public DataBaseHelper(Context context){
super(context, DATABASE_NAME, null, 1);
}
8- En el método onCreate escribir la sentencia para crear la tabla
void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE " + DATABASE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, NOMBRE TEXT, APELLIDO TEXT)");
}
SQLite
Crear base de datos y tabla
9- En el método onUpgrade escribir la sentencia para borrar la tabla en caso de que esta exista
void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
10- Crear la base de datos usando el método getWritableDatabase() al interior del constructor
public DataBaseHelper(Context context){
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase db = this.getWritableDatabase();
}
SQLite
Crear base de datos y tabla
public class DataBaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "Empresa.db";
public static final String TABLE_NAME = "tblEmpleado";
public static final String COL_1 = "ID";
public static final String COL_2 = "NOMBRE";
public static final String COL_3 = "APELLIDO";
public DataBaseHelper(Context context){
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase db = this.getWritableDatabase();
}
@Override
void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE " + DATABASE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, NOMBRE TEXT, APELLIDO TEXT)");
}
@Override
void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
}
El código luce así hasta ahora
SQLite
Crear base de datos y tabla
11- Crear un objeto de la clase DataBaseHelper en MainActivity y pasarle el contexto su constructor
DataBaseHelper myDb = new DataBaseHelper(this);
Al crear este objeto, la llamada a su método constructor permite crear la base de datos y sus tablas
SQLite
Insertar
1- Seguir los pasos anteriores para crear la base de datos y sus tablas
public boolean insertData(){
}
2- Crear un método en la clase DatabaseHelper para guardar datos en la tabla
3- Especificar en el método que datos se guardarán en la tabla
public boolean insertData(String nombre, String Apellido){
}
SQLite
Insertar
4- Crear una instancia de la clase ContentValues y usar el método put para guardar los datos en el objeto
ContentValues contentValues = new ContentValues():
contentValues.put(COL_2,nombre);
contentValues.put(COL_3,apellido);
5- Guardar la información en la tabla usando el método insert de la instancia de la clase SQLiteDatabase
long insert (String table, String nullColumnHack, ContentValues values)
Parámetro | Uso |
---|---|
table | La tabla en la que se insertará la fila actual |
nullColumnHack | Opcional. Valores por defecto en caso que el parámetro values esté vacío |
values | Mapeo que contiene los datos a insertar (nombres de columna y sus valores) |
SQLite
Insertar
public class DataBaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "Empresa.db";
public static final String TABLE_NAME = "tblEmpleado";
public static final String COL_1 = "ID";
public static final String COL_2 = "NOMBRE";
public static final String COL_3 = "APELLIDO";
public DataBaseHelper(Context context){
super(context, DATABASE_NAME, null, 1);
}
@Override
void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE " + DATABASE_NAME + "(ID INTEGER PRIMARY KEY AUTOINCREMENT, NOMBRE TEXT, APELLIDO TEXT)");
}
@Override
void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
}
public boolean insertData(String nombre, String Apellido){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues():
contentValues.put(COL_2,nombre);
contentValues.put(COL_3,apellido);
long result = db.insert(TABLE_NAME, null, contentValues);
db.close();
//Verificar si la información fue guardada en la base de datos
if(result == -1){
Toast.makeText(this, "No guardado", Toast.LENGTH_SHORT).show();
return false;
}else{
Toast.makeText(this, "Guardado correctamente", Toast.LENGTH_SHORT).show();
return true;
}
}
}
Tenemos entonces
SQLite
Insertar
6- Ahora en MainActivity
DataBaseHelper myDb;
myDb.insertData(nombre,apellido);
- Obtener los valores de las cajas de texto (textFields) con los datos que serán guardados en la tabla
- Crear un objeto de la clase DataBase Helper e invocar su método insertData
EJERCICIO
Listar
Modificar
Eliminar
Copy of Aplicaciones móviles - Almacenamiento local
By juan david ramirez londoño
Copy of Aplicaciones móviles - Almacenamiento local
Curso Desarrollo de aplicaciones para dispositivos móviles
- 648