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 :
InputStream inputStream =
getResources
(
).openRawResource
(
R.raw.internal_file);
Vous pouvez alors le lire en toute simplicité :
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 :
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) :
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 :
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 :
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 :
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.