Tutoriel Android : apprendre à gérer les fichiers

Image non disponible
Android2ee

L'auteur

Site personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Le cœur du système

I-A. Les fichiers

Les fichiers se scindent en deux groupes : ceux qui sont fournis par l'application (et sont donc read only) et ceux qui sont créés sur le terminal.

I-A-1. Fichiers internes à l'application

Ces fichiers sont déposés par convention dans le dossier res\raw\ et on y accède dans le code de la manière usuelle par R.RAW.MonFichier :

 
Sélectionnez
1.
InputStream inputStream = getResources().openRawResource(R.raw.internal_file);

Vous pouvez alors le lire en toute simplicité :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
/***************************************************************************************/
/** Simple File reader *****************************************************************/
/***************************************************************************************/
// First implement the textView
TextView textViewSelected = (TextView) findViewById(R.id.TextViewSeletedFile);
textViewSelected.setText(fileName);

// First implement the textView
TextView textViewFile = (TextView) findViewById(R.id.TextViewFileReader);

// Read the file :open a InputStream on it
InputStream inputStream = getResources().openRawResource(R.raw.internal_file);
try {
    if (inputStream != null) {
        // open a reader on the inputStream
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        
        // String used to store the lines
        String str;
        StringBuilder buf = new StringBuilder();
        
        // Read the file
        while ((str = reader.readLine()) != null) {
            buf.append(str + "\r\n");
        }
        // Close streams
        reader.close();
        inputStream.close();
        textViewFile.setText(buf.toString());
    }
} catch (java.io.FileNotFoundException e) {
    Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
} catch (IOException e) {
    Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
}

Si votre fichier est un fichier XML, l'exemple suivant permet de comprendre comment le manipuler :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
/************************************************************************************/
/** Xml File reader *****************************************************************/
/************************************************************************************/

// First implement the textView
TextView textViewXmlSelected = (TextView) findViewById(R.id.TextViewSeletedXmlFile);
textViewXmlSelected.setText(xmlFileName);

// First implement the textView
TextView textViewXmlFile = (TextView) findViewById(R.id.TextViewXmlFileReader);

// Read the file
inputStream = getResources().openRawResource(R.raw.internal_xml_file);
try {
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.parse(inputStream, null);
    NodeList nodes = doc.getElementsByTagName("string");
    StringBuilder buf = new StringBuilder();
    Element element;
    for (int i = 0; i < nodes.getLength(); i++) {
        element = (Element) nodes.item(i);
        buf.append("Node name:"+element.getNodeName());
        buf.append("\r\n\t Node Attribute name :"+element.getAttribute("name"));
        buf.append("\r\n\t Node Text Content:"+element.getTextContent());
        buf.append("\r\n\t node type:"+element.getNodeType());                
        buf.append("\r\n");
    }
    inputStream.close();
    textViewXmlFile.setText(buf.toString());
} catch (java.io.FileNotFoundException e) {
    Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
} catch (IOException e) {
    Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
} catch (ParserConfigurationException e) {
    e.printStackTrace();
} catch (SAXException e) {
    e.printStackTrace();
}

Où le fichier XML est de ce type (et se nomme internal_xml_file.xml) :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<resources>
    <!--Simple string-->
    <string name="hello">Hello World, ResourcesTuto!</string>
    <string name="app_name">ResourcesTuto</string>
    <string name="simpleString">Good Morning My name is Bond, James Bond</string>
    <!--String with parameters ($s for string, $d for decimal (any decimal:integer, double, float...)-->
    <string name="param_message">Hello, i love %1$s, i hate %2$s, i am %3$d years old</string>
    <string name="spinner">Do you like: </string>
    <!--String array-->
    <string-array name="i_like_array">
        <item>chocolate</item>
        <item>television</item>
        <item>internet</item>
        <item>nicotine</item>
        <item>hug</item>
        <item>Santa Claus</item>
    </string-array>
    <!--Plurals String-->
    <plurals name="singleOrPlural">
        <item quantity="one">I am alone on moon</item>
        <item quantity="other">I am 6 900 000 000 on earth</item>
    </plurals>
    <string name="button">An image on the button</string>
</resources>

I-A-2. Fichiers externes à l'application propre à votre activité

Ces fichiers sont privés à votre activité. Vous pouvez les ouvrir en lecture ou en écriture (mais pas les deux) via les méthodes openFileInput(String filename) ou openFileOutput(String fileName). Comme ces fichiers sont propres à votre activité, Android gère leur emplacement, il est donc interdit d'utiliser des chemins pour le fileName et leur extension. Il faut juste mettre le nom du fichier toto et pas .\DossierToto\toto.txt.

Quand les fichiers ont fini d'être utilisés, il faut les fermer, dans la méthode onPause de votre activité. Celle dont on est sûr qu'elle sera appelée avant la destruction de votre activité.

Pour parcourir la liste des fichiers de votre application, la méthode String[] fileList() est à votre disposition. Pour supprimer un fichier, utilisez la méthode deleteFile(FileName). Ces méthodes peuvent être utiles pour nettoyer vos fichiers dans les cas où votre application se termine de manière inopinée (i.e. potentiellement tout le temps).

Un dernier détail d'importance : deux modes d'ouverture sont disponibles pour l'ouverture en écriture des fichiers, le mode Private qui écrase le contenu existant du fichier et le mode Append qui concatène vos données à la fin du fichier :

openFileOutput(NOTES, Context.MODE_PRIVATE)

openFileOutput(NOTES, Context.MODE_APPEND)

Ainsi nous obtenons le code suivant

pour la lecture :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
// First instanciate and fill the spinner with existing files
spinner = (Spinner) findViewById(R.id.SpinnerFiles);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, fileList());
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

// Instanciate the first element
String fileName = (String) spinner.getSelectedItem();

// if there is a selected file, then read it
if (fileName != null) {
    try {
        //open the file and retrieve the inputStream
        InputStream inputStream = openFileInput(fileName);
        if (inputStream != null) {
            // open a reader on the inputStream
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            
            // String to use to store read lines
            String str;
            StringBuilder buf = new StringBuilder();
            
            // Read the file
            while ((str = reader.readLine()) != null) {
                buf.append(str + "\r\n");
            }
            // Close the reader
            reader.close();
            // Close the inputStream
            inputStream.close();
            // Affect the text to the textView
            textViewFile.setText(buf.toString());
        }
    } catch (java.io.FileNotFoundException e) {
        Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
    } catch (IOException e) {
        Toast.makeText(this, "FileNotFoundException", Toast.LENGTH_LONG);
    }
}

pour l'écriture :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
String fileNameStr="MyFileName";
String fileContentStr="The content of the file ";
try {
    
    // To open you can choose the mode MODE_PRIVATE, MODE_APPEND, 
    // MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE
    // This is the creation mode (Private, World Readable et World Writable), 
    // Append is used to open the file and write at its end 
    FileOutputStream fos= openFileOutput(fileNameStr, Context.MODE_PRIVATE);
    // Open the writer
    OutputStreamWriter outputStreamWriter=new OutputStreamWriter(fos);
    // Write
    outputStreamWriter.write(fileContentStr);
    // Close streams
    outputStreamWriter.close();
    fos.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

I-A-3. Fichiers partagés externes à l'application

L'accès aux fichiers externes de votre application s'effectue au moyen d'un Content Provider qui encapsule cet accès.

L'exemple ci-dessous montre l'utilisation du MediaStore pour récupérer la liste des chansons du lecteur externe :

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
// Define the URI for the external audio files
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

// Define the data you want to gather
String[] projection = { MediaStore.Audio.Media._ID,         // 0                                       
                        MediaStore.Audio.Media.ARTIST,      // 1
                        MediaStore.Audio.Media.TITLE,       // 2
                        MediaStore.Audio.Media.ALBUM};      // 3

// Define the where clause (which audio files do you want)
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

// Make the query 
Cursor cursor = getContentResolver().query(media,projection,selection,null,null);
StringBuilder strbuilder= new StringBuilder();

// Browse the result of the query and do something with it:
while(cursor.moveToNext()) {
    strbuilder.append("A new song from ");
    strbuilder.append(cursor.getString(1));
    strbuilder.append(" called ");
    strbuilder.append(cursor.getString(2));
    strbuilder.append(" in the Album ");
    strbuilder.append(cursor.getString(3));
    strbuilder.append("\r\n");
}

// Display that list
AlertDialog.Builder alertDialog=new AlertDialog.Builder(this);
alertDialog.setMessage(strbuilder.toString());
alertDialog.setPositiveButton("Close", new Dialog.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    }
});
alertDialog.show();

II. Conclusion et remerciements

Ce tutoriel s'est intéressé à expliquer comment accéder aux fichiers internes et externes à votre application.

Nous tenons à remercier Claude Leloup pour la relecture orthographique, puis Malick SECK pour la mise au gabarit.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2016 MathiasSeguy. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.