2017-05-03 1 views
3

ContextCompat.getExternalFilesDirs(context, null) dit:Pourquoi certains ContextCompat.getExternalFilesDirs ne sont-ils pas accessibles?

retours chemins absolus vers des répertoires spécifiques à l'application sur tous les périphériques de stockage externes où l'application peut placer des fichiers persistants dont il est propriétaire.

Par exemple, un Huawei Honor exécutant Android 5.1.1 renvoie les éléments suivants de cette méthode:

/storage/emulated/0/Android/data/my.package.name/files 
/storage/sdcard1/Android/data/my.package.name/files 

Le deuxième répertoire est une carte SD amovible. Toutefois, si j'essaie de lire ou d'écrire dans ce répertoire, j'obtiens une exception: android.system.ErrnoException: open failed: EACCES (Permission denied)

L'application dispose de WRITE_EXTERNAL_STORAGE. Et cela fonctionne très bien sur un Samsung Galaxy Note 4 fonctionnant sous Android 4.4.4. Ceci n'est pas lié aux autorisations optionnelles d'Android 6.0, car il s'agit d'un problème sur 5.1.1.

L'API dit the application can place persistent files it owns mais cela ne semble pas être le cas.

J'ai également entendu parler d'autres appareils, y compris des appareils Samsung plus modernes. Est-ce que seuls les OEM ne l'implémentent pas correctement ou y a-t-il quelque chose qui me manque dans les frameworks de stockage complexes d'Android?

Voici un code qui va le démontrer sur ceci et sur certains appareils. Toute tentative de création, de déplacement ou de déplacement de fichiers mkdir dans ce répertoire échoue.

+0

« si je tente de lire ou d'écrire dans ce répertoire » - quel répertoire? Vous en indiquez deux. "L'application a WRITE_EXTERNAL_STORAGE" - ce qui n'est pas pertinent pour ces emplacements sur Android 4.4+. – CommonsWare

+0

Oups. Mis à jour ci-dessus Le second, qui est une carte SD amovible. – cottonBallPaws

+0

Eh bien, vous devriez avoir un accès en lecture/écriture à cela. Vous pouvez envisager d'envoyer le code qui échoue, ainsi qu'une trace de pile complète. À mon humble avis, il est plus probable qu'un fabricant bousiller le stockage amovible un que le stockage externe. – CommonsWare

Répondre

1

Eh bien, j'enveloppai votre code dans cette activité:

package com.commonsware.myapplication; 

import android.app.Activity; 
import android.os.Bundle; 
import android.support.v4.content.ContextCompat; 
import android.util.Log; 
import android.widget.Toast; 
import java.io.File; 
import java.io.IOException; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    File removable = ContextCompat.getExternalFilesDirs(this, null)[1]; 
    if (removable.exists() && removable.canRead() && removable.canWrite()) { 
     File test = new File(removable, "test"); 
     try { 
     test.createNewFile(); // Throws the exception mentioned above 
     } 
     catch (IOException e) { 
     Log.e(getClass().getSimpleName(), "Exception creating file", e); 
     Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); 
     } 
    } 
    } 
} 

Il fonctionne très bien sur un Huawei Honor 5X, fonctionnant sous Android 6.0.1:

$ adb shell ls -al /storage/1A30-3598/Android/data/com.commonsware.myapplication/files 
-rwxrwx--x u0_a29 sdcard_rw  0 2017-05-03 18:02 test 

Donc, je suppose que ce est une incompatibilité spécifique à l'appareil.

+0

semble de cette façon alors ... – cottonBallPaws

+0

@CommonsWare Voir ma réponse qui est un genre de question comme – Grendel

0

Pour un certain nombre de raisons, je voudrais savoir comment @CommonsWare a obtenu le code pour exécuter sans ArrayIndexOutOfBoundsException: longueur = 1; index = 1 ERREUR le [0] doit être paramétré sur [0] Nous testons ce concept depuis quelque temps maintenant pour écrire une méthode permettant à l'utilisateur de sélectionner le stockage interne ou externe. Quelqu'un peut-il expliquer comment cela fonctionne ou pourquoi cela ne fonctionne pas? pour nous La réponse ci-dessus doit être formaté de cette façon

 File removable = ContextCompat.getExternalFilesDirs(this,null)[0]; 
    if (removable.exists() && removable.canRead() && removable.canWrite()) { 

     THE_PATH = String.valueOf(removable); 
     THE_PATH = THE_PATH + "/Documents/"; 

    }else { 
     Toast.makeText(getApplicationContext(),"NO SD CARD", 
    Toast.LENGTH_LONG).show(); 

    } 
+0

Cela ne fournit pas une réponse à la question. Pour critiquer ou demander des éclaircissements à un auteur, laissez un commentaire sous son article.- [À revoir] (/ review/low-quality-posts/18983815) –

+0

Si vous avez une nouvelle question, posez-la en cliquant sur le bouton [Poser une question] (https://stackoverflow.com/questions/ask). Incluez un lien vers cette question si cela aide à fournir un contexte. - [De l'examen] (/ review/low-quality-posts/18983815) –