Professional Documents
Culture Documents
SharedPreferences
La plataforma de Android nos da varias facilidades para el almacenamiento permanente de
datos (es decir que los mismos no se borran cuando se apaga la aplicacin)
Cuando tenemos que almacenar una cantidad limitada de datos es adecuado utilizar la clase
SharedPreferences. Por ejemplo configuraciones de la aplicacin como pueden ser colores de
pantalla, nivel actual en un juego, datos iniciales de controles de entrada de dato etc.
Problema:
La interfaz visual a implementar y los Id de los controles visuales son los siguientes:
Es decir:
Disponemos un TextView
Definimos su ID con el nombre tv1.
La propiedad Text con "Ingrese el mail:".
Disponemos un EditText
Definimos su ID con el nombre et1.
Disponemos un Button
Definimos su propiedad Id con el nombre button.
Su propiedad Text con el valor confirmar
Su propiedad OnClic con el valor ejecutar para no usar un OnClickListener
El cdigo java es:
packagecom.cursoandroid.guardarPreferencias;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.content.SharedPreferences;
importandroid.content.SharedPreferences.Editor;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.EditText;
publicclassArchivosSharedPreferencesActivityextendsActivity{
privateEditTextet1;
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.et1);
SharedPreferences
prefe=getSharedPreferences("datos",Context.MODE_PRIVATE);
et1.setText(prefe.getString("mail",""));
}
publicvoidejecutar(Viewv){
SharedPreferences
preferencias=getSharedPreferences("datos",Context.MODE_PRIVATE);
Editoreditor=preferencias.edit();
editor.putString("mail",et1.getText().toString());
editor.commit();
finish();
}
}
MODE_PRIVATE solo
preferencias.
la
aplicacin
puede
acceder
al
archivo
de
Para extraer los datos del archivo de preferencias debemos indicar el nombre a extraer y un
valor de retorno si dicho nombre no existe en el archivo de preferencias (en nuestro ejemplo la
primera vez que se ejecute nuestro programa como es lgico no existe el archivo de
preferencias lo que hace que Android lo cree, si tratamos de extraer el valor de mail retornar el
segundo parmetro es decir el String con una cadena vaca:
et1.setText(prefe.getString("mail",""));
Debemos crear un objeto de la clase Editor y obtener la referencia del objeto de la clase
SharedPreferences que acabamos de crear. Mediante el mtodo putString almacenamos en
mail el valor del String cargado en el EditText. Luego debemos llamar al mtodo commit de la
clase Editor para que el dato quede almacenado en forma permanente en el archivo de
preferencias. Esto hace que cuando volvamos a arrancar la aplicacin se recupere el ltimo
mail ingresado.
Recordemos que el mtodo finish de la clase Activity finaliza la actividad actual (como tenemos
una aplicacin con una sola actividad finalizar completamente nuestro programa.
Cuando los recuperamos debemos indicar tambin que tipo de datos extraemos:
int e=prefe.getInt("edad", 0);
boolean acti=prefe.getBoolean("activo", false);
float alt=prefe.getFloat("altura", 0f);
Problema:
Realizar un programa que permita ingresar el
nombre de un archivo y el contenido. Permitir
grabar los datos ingresados al presionar un botn.
Disponer un segundo botn que permita recuperar
los datos del archivo de texto.
Hacer que los archivos se graben en una tarjeta
SD.
Debemos presionar el botn "Add" seleccionar "Uses Permision" y luego en name seleccionar
"android.permission.WRITE_EXTERNAL_STORAGE".
El cdigo fuente es:
packagecom.cursoandroid.usarArchivosSD;
importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.OutputStreamWriter;
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.view.View;
importandroid.widget.EditText;
importandroid.widget.Toast;
publicclassArchivosEnTarjetaSDActivityextendsActivity{
EditTextet1;
EditTextet2;
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
}
publicvoidgrabar(Viewv){
Stringnomarchivo=et1.getText().toString();
Stringcontenido=et2.getText().toString();
try
{
Filetarjeta=Environment.getExternalStorageDirectory();
File file = new File(tarjeta.getAbsolutePath(),
nomarchivo);
OutputStreamWriter osw =new OutputStreamWriter(new
FileOutputStream(file));
osw.write(contenido);
osw.flush();
osw.close();
Toast.makeText(this,"Los datos fueron grabados
correctamente",Toast.LENGTH_SHORT).show();
et1.setText("");
et2.setText("");
}
catch(IOExceptionioe)
{
}
}
publicvoidrecuperar(Viewv){
Stringnomarchivo=et1.getText().toString();
Filetarjeta=Environment.getExternalStorageDirectory();
Filefile=newFile(tarjeta.getAbsolutePath(),nomarchivo);
try{
FileInputStreamfIn=newFileInputStream(file);
InputStreamReaderarchivo=newInputStreamReader(fIn);
BufferedReaderbr=newBufferedReader(archivo);
Stringlinea=br.readLine();
Stringtodo="";
while(linea!=null)
{
todo=todo+linea+"\n";
linea=br.readLine();
}
br.close();
archivo.close();
et2.setText(todo);
}catch(IOExceptione)
{
}
}
}
El mtodo para grabar los datos en un archivo de texto localizado en una tarjeta SD
comienza obteniendo el directorio raz de la tarjeta a travs del mtodo
getExternalStorageDirectory(), el mismo retorna un objeto de la clase File.
public void grabar(View v) {
String nomarchivo = et1.getText().toString();
String contenido=et2.getText().toString();
try
{
File tarjeta = Environment.getExternalStorageDirectory();
Creamos un nuevo objeto de la clase File indicando el camino de la unidad SD y el nombre del
archivo a crear:
File file = new File(tarjeta.getAbsolutePath(), nomarchivo);
Por ltimo creamos un objeto de la clase OutputStreamWriter:
OutputStreamWriter osw =new OutputStreamWriter(new
FileOutputStream(file));
}
Accesar a los archivos creados en la
tarjeta SD del emulador
Es posible ver el contenido del archivo
guardado en la SD del emulador como si
fuera un dispositivo real.
En eclipse abra la perspectiva DDMS
(Dalvik Debug Monitor Server). Para ello
presione el botn en la esquina superior
derecha que se muestra en la imagen y
seleccione DDMS.
El DDMS le permitir acceder a los
dispositivos, ver la operacin e interactuar
con el emulador. En este caso nos servir
para copiar el contenido de la SD a nuestro
equipo para ver su contenido que
guardamos con la aplicacin anterior.
En el DDMS usaremos el botn para descargar el archivo de la SD card a nuestro equipo para
abrirlo y ver lo que grabamos:
CursorFactory: a veces, podemos usar una clase que extiende la clase Cursor para
implementar algunas validaciones extra u operaciones sobre las consultas a la base de datos.
Si as fuera, pasaramos una instancia de la clase CursorFactory para devolver una referencia
a nuestra clase derivada para ser utilizada en lugar del cursor por defecto. En este ejemplo,
usaremos la interface Cursor por defecto para recoger los resultados de las consultas, por lo
que el parmetro es null.
Version: la versin del esquema de la base de datos. El constructor crea una base de datos
en blanco con el nombre y el nmero de versin especificados.
En el mtodo onUpgrade se llama cuando la base de datos debe ser actualizada. Este mtodo
es invocado cuando cambia el nmero de versin especificado en el constructor de la clase.
Tiene por objetivo eliminar tablas, aadir tablas, o hacer cualquier otra cosa que necesita para
actualizarse.
En nuestro problema implementaremos una nueva clase llamada AdminSQLiteOpenHelper
que herede de la clase SQLiteOpenHelper:
packagecom.cursoandroid.usarSQLite;
importandroid.content.Context;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.database.sqlite.SQLiteDatabase.CursorFactory;
importandroid.database.sqlite.SQLiteOpenHelper;
publicclassAdminSQLiteOpenHelperextendsSQLiteOpenHelper{
publicAdminSQLiteOpenHelper(Contextcontext,Stringnombre,
CursorFactoryfactory,intversion){
super(context,nombre,factory,version);
}
@Override
publicvoidonCreate(SQLiteDatabasedb){
db.execSQL("createtablevotantes(ifeintprimarykey,
nombretext,lugartext,nromesaint)");
}
@Override
publicvoidonUpgrade(SQLiteDatabasedb,intversionAnte,int
versionNue){
db.execSQL("droptableifexistsvotantes");
db.execSQL("createtablevotantes(ifeintprimarykey,
nombretext,lugartext,nromesaint)");
}
}
En el constructor solo llamamos al constructor de la clase padre pasando los datos que llegan
en los parmetros:
public AdminSQLiteOpenHelper(Context context, String nombre,
CursorFactory factory, int version) {
super(context, nombre, factory, version);
}
En el mtodo onCreate procedemos a crear la tabla votantes con los cuatro campos
respectivos y definiendo el campo ife como primary key:
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table votantes(ife int primary key,
nombre text, lugar text, nromesa int)");
}
En el mtodo onUpgrade procedemos a borrar la tabla votantes y crear nuevamente la tabla
(en este caso con la misma estructura pero podra ser otra en un caso ms real:
public void onUpgrade(SQLiteDatabase db, int versionAnte,
int versionNue) {
db.execSQL("drop table if exists votantes");
db.execSQL("create table votantes(ife int primary key,
nombre text, lugar text, nromesa int)");
}
Ahora veamos la otra clase que implementar las altas, bajas, modificaciones y consultas:
packagecom.cursoandroid.usarSQLite;
importandroid.app.Activity;
importandroid.content.ContentValues;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.os.Bundle;
importandroid.view.View;
importandroid.widget.EditText;
importandroid.widget.Toast;
publicclassUsarSQLiteActivityextendsActivity{
privateEditTextet1,et2,et3,et4;
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);
et4=(EditText)findViewById(R.id.editText4);
}
publicvoidalta(Viewv){
AdminSQLiteOpenHelperadmin=newAdminSQLiteOpenHelper(this,
"administracion",null,1);
SQLiteDatabasebd=admin.getWritableDatabase();
Stringife=et1.getText().toString();
Stringnombre=et2.getText().toString();
Stringlugar=et3.getText().toString();
Stringnromesa=et4.getText().toString();
ContentValuesregistro=newContentValues();
registro.put("IFE",ife);
registro.put("nombre",nombre);
registro.put("lugar",lugar);
registro.put("nromesa",nromesa);
bd.insert("votantes",null,registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
Toast.makeText(this,"Secargaronlosdatosdelapersona",
Toast.LENGTH_SHORT).show();
}
publicvoidconsulta(Viewv){
AdminSQLiteOpenHelperadmin=newAdminSQLiteOpenHelper(this,
"administracion",null,1);
SQLiteDatabasebd=admin.getWritableDatabase();
Stringife=et1.getText().toString();
Cursorfila=bd.rawQuery("selectnombre,lugar,nromesafrom
votanteswhereife="+ife+"",null);
if(fila.moveToFirst())
{
et2.setText(fila.getString(0));
et3.setText(fila.getString(1));
et4.setText(fila.getString(2));
}
else
Toast.makeText(this,"Noexisteunapersonacondicho
IFE",Toast.LENGTH_SHORT).show();
bd.close();
publicvoidbaja(Viewv){
AdminSQLiteOpenHelperadmin=newAdminSQLiteOpenHelper(this,
"administracion",null,1);
SQLiteDatabasebd=admin.getWritableDatabase();
Stringife=et1.getText().toString();
intcant=bd.delete("votantes","ife="+ife+"",null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
if(cant==1)
Toast.makeText(this,"Seborrlapersonacondicho
IFE",Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"Noexisteunapersonacondicho
IFE",Toast.LENGTH_SHORT).show();
}
publicvoidmodificacion(Viewv){
AdminSQLiteOpenHelperadmin=newAdminSQLiteOpenHelper(this,
"administracion",null,1);
SQLiteDatabasebd=admin.getWritableDatabase();
Stringife=et1.getText().toString();
Stringnombre=et2.getText().toString();
Stringlugar=et3.getText().toString();
Stringnromesa=et4.getText().toString();
ContentValuesregistro=newContentValues();
registro.put("nombre",nombre);
registro.put("colegio",colegio);
registro.put("nromesa",nromesa);
intcant=bd.update("votantes",registro,"ife="+ife,null);
bd.close();
if(cant==1)
Toast.makeText(this,"semodificaronlosdatos",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"noexisteunapersonacondicho
IFE",Toast.LENGTH_SHORT).show();
}
}
Como en problemas anteriores definimos los cuatro EditText como atributos y en el mtodo
onCreate obtenemos la referencia de los mismos:
public class UsarSQLiteActivity extends Activity {
private EditText et1,et2,et3,et4;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
et1=(EditText)findViewById(R.id.editText1);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);
et4=(EditText)findViewById(R.id.editText4);
}
1 - Alta de datos.
Cuando se presiona el botn alta se ejecuta el mtodo "alta" recordemos inicializar la propiedad
"OnClick" del botn desde la ventana de visualizacin del archivo XML.
Lo primero que hacemos en este mtodo es crear un objeto de la clase que planteamos
anteriormente y le pasamos al constructor this (referencia del Activity actual), "administracion"
(es el nombre de la base de datos que crearemos en el caso que no exista) luego pasamos null
y 1 indicando que es la primer versin de la base de datos (en caso que cambiemos la
estructura o agreguemos tablas por ejemplo podemos pasar un 2 en lugar de un 1 para que se
ejecute el mtodo onUpgrade donde indicamos la nueva estructura de la base de datos).
Luego de crear un objeto de la clase AdminSqLiteOpenHelper procedemos a crear un objeto
de la clase SQLiteDataBase llamando al mtodo getWritableDatabase (la base de datos se
abre en modo lectura y escritura).
Creamos un objeto de la clase ContentValues y mediante el mtodo put inicializamos todos
los campos a cargar. Seguidamente llamamos al mtodo insert de la clase SQLiteDatabase
pasando en el primer parmetro el nombre de la tabla, como segundo parmetro un null y por
ltimo el objeto de la clase ContentValues ya inicializado (este mtodo es el que provoca que
se inserte una nueva fila en la tabla votantes en la base de datos llamada administracion).
Borramos seguidamente los EditText y mostramos un mensaje para que conozca el operador
que el alta de datos se efectu en forma correcta:
public void alta(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String ife=et1.getText().toString();
String nombre=et2.getText().toString();
String colegio=et3.getText().toString();
String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("ife",ife );
registro.put("nombre",nombre );
registro.put("colegio",colegio );
registro.put("nromesa",nromesa );
bd.insert("votantes", null, registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
Toast.makeText(this, "Se cargaron los datos de la persona",
Toast.LENGTH_SHORT).show();
}
2 - Consulta de datos.
Cuando se presiona el botn "Consulta por IFE" se ejecuta el mtodo consulta:
public void consulta(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String ife=et1.getText().toString();
Cursor fila=bd.rawQuery("select nombre, lugar, nromesa from
votantes where ife="+ife+"",null);
if (fila.moveToFirst())
{
et2.setText(fila.getString(0));
et3.setText(fila.getString(1));
et4.setText(fila.getString(2));
}
else
Toast.makeText(this, "No existe una persona con dicho
IFE", Toast.LENGTH_SHORT).show();
bd.close();
}
En el mtodo consulta lo primero que hacemos es crear un objeto de la clase
AdminSQLiteOpenHelper y obtener una referencia de la base de datos llamando al mtodo
getWritableDatabase.
Seguidamente definimos una variable de la clase Cursor y la inicializamos con el valor devuelto
por el mtodo llamado rawQuery.
La clase Cursor almacena en este caso una fila o cero filas (una en caso que hayamos
ingresado un IFE existente en la tabla votantes), llamamos al mtodo moveToFirst() de la
clase Cursor y retorna true en caso de existir una persona con el ife ingresado, en caso
contrario retorna cero.
Para recuperar los datos propiamente dichos que queremos consultar llamamos al mtodo
getString y le pasamos la posicin del campo a recuperar (comienza a numerarse en cero, en
este ejemplo la columna cero representa el campo nombre, la columna 1 representa el campo
colegio y la columna 2 representa el campo nromesa).
3.- Baja o borrado de datos.
Para borrar uno o ms registros la clase SQLiteDatabase tiene un mtodo que le pasamos en
el primer parmetro el nombre de la tabla y en el segundo la condicin que debe cumplirse
para que se borre la fila de la tabla. El mtodo delete retorna un entero que indica la cantidad
de registros borrados:
public void baja(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String ife=et1.getText().toString();
int cant=bd.delete("votantes", "ife="+ife+"",null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
et4.setText("");
if (cant==1)
Toast.makeText(this, "Se borr la persona con dicho
IFE", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "No existe una persona con dicho
IFE", Toast.LENGTH_SHORT).show();
}
4 - Modificacin de datos.
En la modificacin de datos debemos crear un objeto de la clase ContentValues y mediante el
mtodo put almacenar los valores para cada campo que ser modificado. Luego se llama al
mtodo update de la clase SQLiteDatabase pasando el nombre de la tabla, el objeto de la
clase ContentValues y la condicin del where (el cuarto parmetro en este ejemplo no se
emplea).
public void modificacion(View v) {
AdminSQLiteOpenHelper admin=new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd=admin.getWritableDatabase();
String ife=et1.getText().toString();
String nombre=et2.getText().toString();
String lugar=et3.getText().toString();
String nromesa=et4.getText().toString();
ContentValues registro=new ContentValues();
registro.put("nombre",nombre);
registro.put("lugar",lugar);
registro.put("nromesa",nromesa);
int cant = bd.update("votantes", registro, "ife="+ife, null);
bd.close();
if (cant==1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "no existe una persona con dicho
IFE", Toast.LENGTH_SHORT).show();
}