web-dev-qa-db-fra.com

Écriture sur le stockage privé interne sous Android

J'essaie de sauvegarder certaines données de mon application dans un simple fichier texte dans la zone de stockage privé interne (préférences de l'utilisateur de l'application). J'ai lu de nombreuses questions ici (StackOverflow) et essayé les solutions suggérées sans succès. La solution la plus simple, semble-t-il, serait celle suggérée ici:

http://developer.Android.com/guide/topics/data/data-storage.html#filesInternal

mais je ne peux pas obtenir que cela fonctionne sur mon appareil de test. J'ai également essayé de créer le fichier à l'aide des méthodes disponibles dans Java.io.File avec les méthodes appropriées. J'ai également essayé de créer le fichier sur la carte SD avec le même résultat, échouer. J'ai essayé de nombreuses solutions énumérées dans d'autres réponses, en suivant exactement le code et les instructions suggérées et en obtenant le même résultat. Je commence à sentir qu'il me manque un morceau de code important, ou un indicateur de réglage quelque part, j'ai défini l'autorisation dans le fichier manifeste:

  <uses-permission 
        Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />


Pour être clair, j'essaie d'écrire sur le stockage interne et privé de l'appareil. C'est un petit fichier contenant un nom, un numéro de téléphone et quelques indicateurs de type int. Quelle que soit la méthode que j'utilise, je trouve que le fichier n'a pas été créé (ou modifié si je place le fichier manuellement sur la carte SD) ou j'obtiens une exception NullPointerException lorsque j'essaie de référencer le fichier ou son emplacement:

private              File   fILE = new File("Mydata", main.FILENAME);

ou

private              File   fILE  = getDir("Mydata", 0);


J'utilise le code sur un HTC Hero, mis à jour avec la dernière version du service de Sprint. Toute aide serait grandement appréciée, merci d'avance!

-Steve

Mise à jour (02/02/11): À l'aide d'un EVO (API 8), j'obtiens toujours une exception NullPointerException. Le code générant l'exception est présenté ci-dessous. Avez-vous des idées sur la raison pour laquelle mon application ne peut pas accéder à la mémoire de stockage? J'ai ce problème sur trois périphériques physiques différents utilisant deux niveaux d'API (API 7 et 8).

    File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");

UPDATE 2: 2/4/11 - J'ai constaté que je ne pouvais jamais voir la structure de fichier sur le périphérique physique (répertoire de données). Quelqu'un a un avis là dessus? L'appareil est correctement configuré et peut exécuter une application à partir d'Eclipse ou d'adb.

UPDATE 3: (2/9/11) - Je pense avoir trouvé le problème, mais je ne suis pas sûr de la manière de le résoudre. J'ai découvert que les autorisations sur le répertoire/data/sur les périphériques physiques sont: drwxrwx--x. Je ne suis pas sûr de savoir pourquoi c'est comme ça, peut-être quelque chose avec Sprint? J'ai trouvé cet ensemble de cette façon sur un HTC Hero, un Samsung Epic (Galaxy S) et un HTC EVO, tous sur Sprint. Le problème semble être que DDMS et mon application ne disposent pas d'un accès r/w au répertoire. Je dois comprendre deux choses ici, pourquoi c'est comme ça et comment surmonter cette question dans la nature. Encore une fois, toute aide serait géniale !!

UPDATE 4: Je pense que le mois de février dernier était un moment total pour moi (voir UPDATE 3). Les dispositifs de test que je possède ne sont pas rootés et donc aucun accès (DUH!). Après toutes les mises à jour effectuées par SGS et le EVO 4G, le résultat est toujours le même. Je travaille toujours sur ce problème et j'essaierai de revenir ici avec une mise à jour bientôt (j'espère moins d'un an la prochaine fois).

9
Kingsolmn

Ce n’est pas une réponse directe à votre question, mais néanmoins: j’ai remarqué que vous ne souhaitiez pas stocker des tonnes de données dans votre fichier. Serait-ce une alternative suffisante pour utiliser les préférences partagées à la place?

Et peut-être encore plus intéressant: le problème survient-il lorsque vous écrivez plutôt dans le fichier de préférences partagées?

http://developer.Android.com/guide/topics/data/data-storage.html#pref

3
dbm

Le répertoire /data/ d'un périphérique physique n'est disponible que pour l'utilisateur root. Étant donné que le seul moyen réaliste d'obtenir cet accès sur un périphérique physique consiste à rooter le périphérique, l'explorateur de fichiers DDMS ne peut pas accéder à cette branche de l'arborescence de répertoires. 

En ce qui concerne les raisons pour lesquelles l’application n’écrira pas, le problème tient probablement au fait que j’ai signé l’application avec des clés de débogage (pas un grand * expert NIX, mais ce qui semble être le cas ici à partir de mes recherches personnelles).

4
Kingsolmn

Essayez de changer la ligne suivante:

File newfile = new File(this.getFilesDir() + "/data/files/", "sample.txt");

à:

File newfile = new File(this.getFilesDir() + "/","sample.txt");
4
Panoli

Je traitais du même problème. Enfin, j’ai constaté qu’il n’était pas vraiment nécessaire de donner tous les chemins de fichiers pour créer un nouveau fichier dans la mémoire de stockage interne. Mentionnez simplement le nom du fichier et il sera créé dans le dossier de packages de votre application sur le périphérique. J'ai mentionné exactement ici

Et ça marche parfaitement. Je dirais qu'il faut éviter de mentionner le chemin de fichier complet tel que:/data/... pour créer un fichier (vous devez disposer des autorisations appropriées pour créer un fichier de cette manière). Laissez le cadre Android faire le travail pour créer un fichier privé pour votre application. 

4
bianca

La zone de stockage interne étant en quelque sorte privée pour l'application, l'utilisateur doit disposer d'un accès root (périphérique racine) pour créer et charger les fichiers. Si vous avez un périphérique root, voici comment écrire un fichier sur la mémoire de stockage interne:

 // Create a file in the Internal Storage

String fileName = "MyFile";
String content = "hello world";

FileOutputStream outputStream = null;
try {
outputStream = openFileOutput(fileName, Context.MODE_APPEND);
outputStream.write(content.getBytes());
outputStream.close();
} catch (Exception e) {
  e.printStackTrace();
}

Cela devrait créer instantanément un fichier appelé MyFile avec le contenu hello world . Le répertoire de stockage interne se trouve généralement dans un emplacement spécial spécifié par le nom du package de notre application. Dans mon cas, il s’agit de/data/data/[nom du paquet] et les fichiers créés sont stockés dans un répertoire appelé fichiers dans ce répertoire.

2
Akash

Comme @bianca le dit, il vaut mieux ne pas utiliser un chemin de fichier. Mais utilisez plutôt le nom de fichier pour créer un fichier. Quelque chose comme ça:

public static void saveTextToFile(Context context, String filename, String content) {
  try {
     FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
     fos.write(content.getBytes());
     fos.close();
  } catch (Exception e) {
     e.printStackTrace();
  }
}

Et pour obtenir le fichier, vous pouvez utiliser:

File file = new File(context.getFilesDir(), filename);

En savoir plus: Sauvegarder des fichiers .