Comment obtenir l'URI d'un fichier d'actif?


127

J'ai essayé d'obtenir le chemin URI d'un fichier d'actif.

uri = Uri.fromFile(new File("//assets/mydemo.txt"));

Quand je vérifie si le fichier existe, je vois que ce fichier n'existe pas

File f = new File(filepath);
if (f.exists() == true) {
    Log.e(TAG, "Valid :" + filepath);
} else {
    Log.e(TAG, "InValid :" + filepath);
}

Quelqu'un peut-il me dire comment je peux mentionner le chemin absolu d'un fichier existant dans le dossier d'actifs

Réponses:


160

Il n'y a pas de "chemin absolu pour un fichier existant dans le dossier de ressources". Le contenu du assets/dossier de votre projet est emballé dans le fichier APK. Utilisez un AssetManagerobjet pour obtenir un InputStreamsur un actif.

Pour WebView, vous pouvez utiliser le file Urischéma de la même manière que vous utiliseriez une URL. La syntaxe des actifs est file:///android_asset/...(note: trois barres obliques) où les points de suspension sont le chemin du fichier à partir du assets/dossier.


32
file://android_asset/..., où ...est le chemin relatif dans le assets/répertoire de votre projet .
CommonsWare

4
Voici un exemple de projet à l' aide file://android_asset/, mais pas pour Uri: github.com/commonsguy/cw-advandroid/tree/master/WebView/GeoWeb1
CommonsWare

20
@CommonsWare, il semble que vous ayez manqué un «/» dans votre URI. Ça devrait être file:///.
ThomasW

7
J'ai essayé ceci comme new File("file:///android_asset/sounds/beep.mid");, mais le fichier de résultat n'existe pas. Des idées? Le fichier PS est dans le assets/sounds/dossier.
oncle Lem

3
Est-il vrai que «file: ///android_asset/... »ne fonctionne que dans WebView et n'est pas possible d'obtenir InputStream en utilisant URI / URL / Uri en dehors de WebView?
Lubbo

74

L'URL correcte est:

file:///android_asset/RELATIVEPATH

où RELATIVEPATH est le chemin d'accès à votre ressource par rapport au dossier des actifs.

Notez les 3 / dans le schéma. La vue Web ne chargerait aucun de mes actifs sans le 3. J'ai essayé 2 comme (précédemment) commenté par CommonsWare et cela ne fonctionnerait pas. Ensuite, j'ai regardé la source de CommonsWare sur github et j'ai remarqué la barre oblique supplémentaire.

Ce test n'a cependant été effectué que sur l'émulateur Android 1.6, mais je doute que ce soit différent sur un appareil réel ou une version supérieure.

EDIT: CommonsWare a mis à jour sa réponse pour refléter ce petit changement. J'ai donc édité ceci pour que cela ait toujours du sens avec sa réponse actuelle.


Ne fonctionne plus String fileName = "file:///android_asset/file.csv"; System.out.println(new File(fileName).exists()); // prints false
Elgirhath

@Elgirhath le constructeur pour Filequi accepte une chaîne attend un chemin pas un URI . Je n'ai pas codé pour Android depuis quelques années et les choses ont peut-être changé. Je ne sais pas si vous pouvez accéder au dossier des actifs intégrés à l'aide d'une classe de fichier Java normale. Il me semble que vous devez utiliser un AssetManager . Les fichiers dans le dossier des ressources sont placés sur l'appareil dans l'APK en lecture seule et compressés (les APK sont en fait des fichiers zip), donc plus de travail pour le relire. Essayez quelque chose commenew File(new URI(filename))
Russ

10

Veuillez essayer que ce code fonctionne correctement

 Uri imageUri = Uri.fromFile(new File("//android_asset/luc.jpeg"));

    /* 2) Create a new Intent */
    Intent imageEditorIntent = new AdobeImageIntent.Builder(this)
            .setData(imageUri)
            .build();

8

Enfin, j'ai trouvé un moyen d'obtenir le chemin d'un fichier présent dans les actifs à partir de cette réponse dans Kotlin. Ici, nous copions le fichier de ressources dans le cache et obtenons le chemin du fichier à partir de ce fichier de cache.

@Throws(IOException::class)
    fun getFileFromAssets(context: Context, fileName: String): File = File(context.cacheDir, fileName)
            .also {
               if (!it.exists()) {
                it.outputStream().use { cache ->
                    context.assets.open(fileName).use { inputStream ->
                            inputStream.copyTo(cache)
                    }
                  }
                }
            }

Obtenez le chemin d'accès au fichier comme:

val filePath =  getFileFromAssets(context, "fileName.extension").absolutePath

1
Notez que si le fileNamerépertoire have dir/file. Il plantera avec le chemin qui cache/dir/filen'existe pas. Aussi, je pense qu'il vaut mieux avoir une vérification if(!it.exist)à l'intérieur du alsobloc, alors il ne copiera pas le fichier à chaque fois que même le fichier est déjà sur le cache
Yeung

@ShylendraMadda, @Yeung, if(!it.exist)lance une référence d'erreur non résolue. Toute solution ?
binrebin

Vérifiez que le fichier existe dans votre cache avec ce nom de fichier? @binrebin
Shylendra Madda

@ShylendraMadda, je ne connais que le nom du fichier. Pouvons-nous le charger avec un script sans connaître l'
URI

Je pense qu'il if(!it.exist)faudrait mettre avant it.outputStream()...
Yeung

7

entrez la description de l'image ici

Assurez-vous que votre dossier de ressources est placé dans la bonne position.


Vous pouvez le mettre où vous voulez et définir le chemin dans votre fichier build.gradle comme suitsourceSets { main { assets.srcDirs = ['src/main/assets'] } }
Marcel Bro

2
Comment obtenir le chemin de hello.html? s'il vous plaît ajouter
Rohit Singh

6

Fonctionne pour WebView mais semble échouer URL.openStream(). Vous devez donc distinguer les protocoles file: // et les gérer via AssetManager comme suggéré.


4

Essayez ceci, cela fonctionne:

InputStream in_s = 
    getClass().getClassLoader().getResourceAsStream("TopBrands.xml");

Si vous obtenez une exception de valeur nulle, essayez ceci (avec classe TopBrandData):

InputStream in_s1 =
    TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");

Si cela ne fonctionne pas, veuillez essayer celui-ci: InputStream in_s1 = TopBrandData.class.getResourceAsStream ("/ assets / TopBrands.xml");
Jaspreet Singh

3
InputStream is = getResources().getAssets().open("terms.txt");
String textfile = convertStreamToString(is);
    
public static String convertStreamToString(InputStream is)
        throws IOException {

    Writer writer = new StringWriter();
    char[] buffer = new char[2048];

    try {
        Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        int n;
        while ((n = reader.read(buffer)) != -1) {
            writer.write(buffer, 0, n);
        }
    } finally {
        is.close();
    }

    String text = writer.toString();
    return text;
}

1

essaye ça :

Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat); 

Je l'avais fait et ça a marché


2
En fait ça marche. Vérifier ContentResolver.openAssetFileDescriptor
Hippo Seven

1
Travaillé. Merci beaucoup. Lol, je cherche juste à obtenir le fichier interne de l'URI // CRÉER UN DOSSIER RAW À L'INTÉRIEUR DE RES, PUIS LE FICHIER DE NOM CONTIENT UNIQUEMENT UN caractère..z0..9, PAS DE MAJUSCULES !!!
phnghue le

0

Oui, vous ne pouvez pas accéder à votre dossier de lecteur à partir de votre téléphone ou de votre émulateur Android, car votre ordinateur et Android sont deux systèmes d'exploitation différents.Je choisirais le dossier res d'Android car il dispose de bonnes méthodes de gestion des ressources. Jusqu'à et à moins que vous n'ayez de très bonnes raisons de placer votre fichier dans le dossier des actifs. Au lieu de cela, vous pouvez le faire

try {
      Resources res = getResources();
      InputStream in_s = res.openRawResource(R.raw.yourfile);

      byte[] b = new byte[in_s.available()];
      in_s.read(b);
      String str = new String(b);
    } catch (Exception e) {
      Log.e(LOG_TAG, "File Reading Error", e);
 }

-7

A travaillé pour moi Essayez ce code

   uri = Uri.fromFile(new File("//assets/testdemo.txt"));
   String testfilepath = uri.getPath();
    File f = new File(testfilepath);
    if (f.exists() == true) {
    Toast.makeText(getApplicationContext(),"valid :" + testfilepath, 2000).show();
    } else {
   Toast.makeText(getApplicationContext(),"invalid :" + testfilepath, 2000).show();
 }
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.