Exception: 'open failed: EACCES (Permission refusée)' sur Android
je suis
échec de l'ouverture:
EACCES (Permission denied)
sur la ligne OutputStream myOutput = new FileOutputStream(outFileName);
j'ai vérifié la racine, et j'ai essayé android.permission.WRITE_EXTERNAL_STORAGE
.
Comment puis-je corriger ce problème?
try {
InputStream myInput;
myInput = getAssets().open("XXX.db");
// Path to the just created empty db
String outFileName = "/data/data/XX/databases/"
+ "XXX.db";
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
buffer = null;
outFileName = null;
}
catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
24 réponses
j'ai eu le même problème... Le <uses-permission
était au mauvais endroit. C'est juste:
<manifest>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
...
<application>
...
<activity>
...
</activity>
</application>
</manifest>
l'étiquette uses-permission
doit se trouver à l'extérieur de l'étiquette application
.
pour API 23+ vous devez demander les permissions de lecture / écriture même si elles sont déjà dans votre manifeste.
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* @param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
pour la documentation officielle sur la demande de permissions pour API 23+, cochez https://developer.android.com/training/permissions/requesting.html
j'ai observé une fois lors de l'exécution de l'application à l'intérieur de l'émulateur. Dans les paramètres de l'émulateur, vous devez spécifier la taille de stockage externe (Carte SD"") correctement. Par défaut, le champ" Stockage externe " est vide, ce qui signifie probablement qu'il n'y a pas de tel dispositif et que les EACCES sont lancées même si les permissions sont accordées dans le manifeste.
en plus de toutes les réponses, assurez-vous que vous n'utilisez pas votre téléphone comme un stockage USB.
j'avais le même problème sur la Sensation HTC sur le mode de stockage USB activé. Je peux toujours déboguer/exécuter l'application, mais je ne peux pas sauver au stockage externe.
mon problème était avec" TargetApi(23) " qui est nécessaire si votre minSdkVersion est inférieur à 23.
donc, j'ai demandé la permission avec l'extrait suivant
protected boolean shouldAskPermissions() {
return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1);
}
@TargetApi(23)
protected void askPermissions() {
String[] permissions = {
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE"
};
int requestCode = 200;
requestPermissions(permissions, requestCode);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ...
if (shouldAskPermissions()) {
askPermissions();
}
}
il s'est avéré, c'était une erreur stupide puisque j'avais mon téléphone toujours connecté à L'ordinateur de bureau et je ne m'en suis pas rendu compte.
donc j'ai dû éteindre la connexion USB et tout a bien fonctionné.
J'ai eu le même problème sur Samsung Galaxy Note 3, Avec CM 12.1. Le problème pour moi était que j'avais
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
, et à l'utiliser pour prendre et stocker des photos. Quand J'ai essayé de charger ces mêmes photos dans ImageLoader j'ai eu l'erreur (Permission denied)
. La solution était d'ajouter explicitement
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
puisque la permission ci-dessus ne limite la permission d'écriture que jusqu'à la version 18 de L'API, et avec elle la permission de lecture.
je vis la même chose. Ce que j'ai trouvé est que si vous allez à Paramètres -> Gestionnaire D'Application -> votre application -> Permissions -> activer le stockage , il résout le problème.
en plus de toutes les réponses, si les clients utilisent Android 6.0, Android a ajouté le nouveau modèle de permission pour (Marshmallow).
Trick: si vous ciblez la version 22 ou moins, votre application demandera toutes les permissions au moment de l'installation tout comme il le ferait sur n'importe quel appareil exécutant un OS sous Marshmallow. Si vous essayez de l'émulateur, puis à partir de android 6.0, vous devez explicitement aller le Paramètres - > apps - > YOURRAPP - > permissions et modifier la permission si vous en avez donné.
Je m'attendrais à ce que tout ce qui est en dessous de /data
appartienne au"stockage interne". Cependant, vous devez être en mesure d'écrire à /sdcard
.
j'ai eu le même problème et aucune des suggestions n'a aidé. Mais j'ai trouvé une raison intéressante pour cela, sur un appareil physique, Galaxy Tab .
lorsque le stockage USB est activé, les permissions externes de lecture et d'écriture de stockage n'ont aucun effet. Il suffit de désactiver le stockage USB, et avec les bonnes permissions, vous aurez le problème résolu.
modifier une propriété de permission dans votre /system/etc/permission/platform.xml
et groupe mentionné comme indiqué ci-dessous.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
<group android:gid="sdcard_rw" />
<group android:gid="media_rw" />
</uses-permission>
lorsque votre application appartient à l'application système, elle ne peut pas accéder à la carte SD.
j'ai eu la même erreur quand j'ai essayé d'écrire une image dans le dossier DCIM/camera sur Galaxy S5 (android 6.0.1) et j'ai compris que seul ce dossier est restreint. Je pourrais tout simplement écrire dans DCIM/n'importe quel dossier mais pas à la caméra. Il doit s'agir d'une restriction ou d'une personnalisation fondée sur la marque.
étrangement après avoir mis une barre oblique "/" avant mon nouveau mon problème a été résolu. J'ai changé ceci:
File myFile= new File(Environment.getExternalStorageDirectory() + "newFile");
à ceci:
File myFile= new File(Environment.getExternalStorageDirectory() + "/newFile");
peut-être que la réponse est la suivante:
sur L'API > = 23 périphériques, si vous installez app (l'application n'est pas l'application système), vous devriez vérifier la permission de stockage dans "Paramètres-applications", Il y a une liste de permission pour chaque application, vous devriez La vérifier! essayez
dans mon cas, j'utilisais une " file picker library qui renvoyait le chemin au stockage externe mais qui commençait par /root/
. Et même avec la WRITE_EXTERNAL_STORAGE permission accordée à l'exécution j'ai toujours eu l'erreur EACCES (Permission denied) .
Ainsi, utilisez Environment.getExternalStorageDirectory()
pour obtenir le chemin correct vers le stockage externe.
exemple:
ne peut pas écrire: /root/storage/emulated/0/newfile.txt
peut écrire: /storage/emulated/0/newfile.txt
boolean externalStorageWritable = isExternalStorageWritable();
File file = new File(filePath);
boolean canWrite = file.canWrite();
boolean isFile = file.isFile();
long usableSpace = file.getUsableSpace();
Log.d(TAG, "externalStorageWritable: " + externalStorageWritable);
Log.d(TAG, "filePath: " + filePath);
Log.d(TAG, "canWrite: " + canWrite);
Log.d(TAG, "isFile: " + isFile);
Log.d(TAG, "usableSpace: " + usableSpace);
/* Checks if external storage is available for read and write */
public boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
sortie 1:
externalStorageWritable: true
filePath: /root/storage/emulated/0/newfile.txt
isFile: false
usableSpace: 0
sortie 2:
externalStorageWritable: true
filePath: /storage/emulated/0/newfile.txt
isFile: true
usableSpace: 1331007488
je crée un dossier sous /data/ dans mon init.rc (curage autour avec le psba sur la Nexus 7) et eu exactement ce problème.
il s'est avéré que donner la permission du dossier rw (666) n'était pas suffisant et il devait être rwx (777) puis tout a fonctionné!
l'application post 6.0 des permissions de stockage peut être contournée si vous avez un périphérique enraciné via ces commandes adb:
root@msm8996:/ # getenforce
getenforce
Enforcing
root@msm8996:/ # setenforce 0
setenforce 0
root@msm8996:/ # getenforce
getenforce
Permissive
ajouter Permission dans le manifeste.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
j'ai eu le même problème (API >= 23).
la solution https://stackoverflow.com/a/13569364/1729501 a fonctionné pour moi, mais il n'était pas pratique de déconnecter l'application pour le débogage.
ma solution a été d'installer le pilote de périphérique adb approprié sur Windows. Le pilote USB de google n'a pas fonctionné pour mon appareil.
étape 1: Téléchargez des pilotes adb pour votre marque de périphérique.
étape 2: Aller à gestionnaire de périphérique - > autres périphériques -> rechercher les entrées avec le mot "adb" - > sélectionner le pilote de mise à jour - > indiquer l'emplacement à l'étape 1
après avoir ajouté la permission résolu mon problème
<uses-permission android:name="android.permission.INTERNET"/>
ajouter Grad dependencies
implementation 'com.karumi:dexter:4.2.0'
Ajouter le code ci-dessous dans votre activité principale.
import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
checkMermission();
}
}, 4000);
}
private void checkMermission(){
Dexter.withActivity(this)
.withPermissions(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.INTERNET
).withListener(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.isAnyPermissionPermanentlyDenied()){
checkMermission();
} else if (report.areAllPermissionsGranted()){
// copy some things
} else {
checkMermission();
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
token.continuePermissionRequest();
}
}).check();
}
suite à la réponse de user462990
pour être averti lorsque l'utilisateur répond à la boîte de dialogue de demande de permission, utilisez ceci: (code en kotlin)
override fun onRequestPermissionsResult(requestCode: Int,
permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
// If request is cancelled, the result arrays are empty.
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return
}
// Add other 'when' lines to check for other
// permissions this app might request.
else -> {
// Ignore all other requests.
}
}
}