Come abbiamo visto nella lezione precedente, l’oggetto SharedPreferences consente di memorizzare informazioni sotto forma di coppie nome/valore. Tuttavia in molti casi è preferibile utilizzare il tradizionale file system per la memorizzazione dei nostri dati.
Uno dei modi di salvare informazioni in un’applicazione Android è quello di scriverli all’interno di un file nella memoria interna del sistema. Per capire come effettuare quest’operazione creiamo un nuovo progetto su Android Studio denominato TestMemoriaInterna.
Nel seguente esempio vedremo come salvare sulla memoria interna del dispositivo una stringa inserita dall’utente.
Modifichiamo il file activity_main.xml nel modo seguente
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Inserire una stringa qui" />
<EditText
android:id="@+id/txtStringa"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btnSalva"
android:text="Salva"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClickSalva" />
<Button
android:id="@+id/btnCarica"
android:text="Carica"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onClickCarica" />
</LinearLayout>
Il risultato grafico di questo codice dovrebbe essere simile al seguente
Andiamo ad impostare il file MainActivity.java nel modo seguente
package com.example.test.testmemoriainterna;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.Activity;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
EditText textBox;
static final int READ_BLOCK_SIZE = 150;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textBox = (EditText) findViewById(R.id.txtStringa);
}
public void onClickSalva(View view) {
String str = textBox.getText().toString();
try
{
FileOutputStream fOut = openFileOutput("mio_file.txt",MODE_WORLD_READABLE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write(str);
osw.flush();
osw.close();
Toast.makeText(getBaseContext(),
"Dati salvati correttamente.",
Toast.LENGTH_SHORT).show();
textBox.setText("");
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
public void onClickCarica(View view) {
try
{
FileInputStream fIn = openFileInput("mio_file.txt");
InputStreamReader isr = new InputStreamReader(fIn);
char[] inputBuffer = new char[READ_BLOCK_SIZE];
String s = "";
int charRead;
while ((charRead = isr.read(inputBuffer))>0)
{
String readString = String.copyValueOf(inputBuffer, 0,charRead);
s += readString;
inputBuffer = new char[READ_BLOCK_SIZE];
}
textBox.setText(s);
Toast.makeText(getBaseContext(),
"Dati caricati correttamente.",
Toast.LENGTH_SHORT).show();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Fatto questo avviamo la nostra applicazione sull’emulatore
Inseriamo nel campo testuale una stringa (nel mio caso ‘Ciao a tutti!’) e clicchiamo su Salva. Se tutto funziona correttamente verrà mostrato il messaggio Dati salvati correttamente ed il testo inserito scomparirà
Se adesso clicchiamo su Carica vedremo che il testo inserito precedentemente verrà visualizzato nuovamente nella casella di testo e comparirà il messaggio Dati caricati correttamente
Come al solito adesso andiamo ad analizzare i dettagli di quello che abbiamo fatto. Per salvare il testo in un file abbiamo utilizzato la classe FileOutputStream. Il metodo openFileOutput istanzia un oggetto di tale classe corrispondente ad un file su cui scrivere. In questo esempio abbiamo utilizzato la costante MODE_WORLD_READABLE per indicare che il file è leggibile anche da altre applicazioni
FileOutputStream fOut = openFileOutput("mio_file.txt",MODE_WORLD_READABLE);
Altre costanti disponibili sono:
MODE_PRIVATE – L’accesso al file è consentito solo all’applicazione che l’ha creato
MODE_APPEND – Per aggiungere dati all’interno di un file esistente
MODE_WORLD_WRITEABLE – – L’accesso al file in scrittura è consentito a tutte le altre applicazioni
Per convertire uno flusso di caratteri in un flusso di byte abbiamo utilizzato un oggetto della classe OutputStreamWriter, passandogli come parametro l’istanza dell’oggetto FileOutputStream creato precedentemente
OutputStreamWriter osw = new OutputStreamWriter(fOut);
Abbiamo poi utilizzato il metodo write per scrivere il testo all’interno del file
osw.write(str);
Invece per caricare il testo memorizzato nel file abbiamo utilizzato gli oggetti FileInputStream e InputStreamReader
FileInputStream fIn = openFileInput("mio_file.txt");
InputStreamReader isr = new InputStreamReader(fIn);
Poichè teoricamente non conosciamo la lunghezza del file che andiamo a leggere, il suo contenuto viene letto in blocchi di 150 caratteri (valore della variabile READ_BLOCK_SIZE) e posto in un buffer. Successivamente i caratteri immagazzinati vengono copiati in un oggetto String
char[] inputBuffer = new char[READ_BLOCK_SIZE];
String s = "";
int charRead;
while ((charRead = isr.read(inputBuffer))>0)
{
String readString = String.copyValueOf(inputBuffer, 0, charRead);
s += readString;
inputBuffer = new char[READ_BLOCK_SIZE];
}
textBox.setText(s);
Il metodo read dell’oggetto InputStreamReader controlla il numero di caratteri letti e restituisce il valore -1 se viene raggiunta la fine del file.