2012-10-12 23 views
7

Durante la scrittura di un file nella scheda SD esterna, viene visualizzato un messaggio di errore EACCESS negato. Ho impostato il permesso <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Ma quando leggo il file riesco a leggerlo ma non riesco a scrivere il file. Il codice che sto usando per scrivere il file nella scheda SD è:EACCESS Autorizzazione negata in Android

String path="mnt/extsd/Test"; 

       try{ 
        File myFile = new File(path, "Hello.txt");    //device.txt 
        myFile.createNewFile(); 
        FileOutputStream fOut = new FileOutputStream(myFile); 

        OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); 
        myOutWriter.append(txtData.getText()); 
        myOutWriter.close(); 
        fOut.close(); 
        Toast.makeText(getBaseContext(),"Done writing SD "+myFile.getPath(),Toast.LENGTH_SHORT).show(); 
       } catch (Exception e) { 
        Toast.makeText(getBaseContext(), e.getMessage(),Toast.LENGTH_SHORT).show(); 
        System.out.println("Hello"+e.getMessage()); 
       } 
      } 

Il percorso per la scheda di memoria esterna è mnt/extsd/. Ecco perché non sono in grado di utilizzare Environment.getExternalStorageDirectory().getAbsolutePath() che mi sta dando un percorso mnt/sdcard e questo percorso è per percorso di archiviazione interno nel mio tablet. Si prega di suggerire perché questo è così n come posso risolvere questo

risposta

13

Come ricordo che Android ha ottenuto un supporto multi-storage parziale da Honeycomb, e lo storage primario (quello che si ottiene da Environment.getExternalStorageDirectory, solitamente parte dall'interno di eMMC scheda) è ancora protetto dal permesso WRITE_EXTERNAL_STORAGE, ma gli archivi secondari (come la vera scheda SD rimovibile) sono protetti da una nuova autorizzazione android.permission.WRITE_MEDIA_STORAGE e il livello di protezione è signatureOrSystem, vedere anche la discussione in this article.

Se questo è il caso, allora sembra impossibile per un app normale scrivere qualsiasi cosa per il vero sdcard senza firma piattaforma ...

+0

ok .. Allora c'è qualche altro modo di scrivere? – CodingDecoding

+0

Hai accesso root al tuo tablet? Se ancora allora puoi fare un test come questo: 1) permetti alla tua app di utilizzare l'autorizzazione WRITE_MEDIA_STORAGE e quindi ricostruirla; 2) disinstallare la tua app se è già installata, quindi eseguire "adb root", "adb remount", "adb push YouApp.apk /system/app/YouApp.apk" questo renderà la tua app un'app di sistema; 3) avvia la tua app e controlla se il codice di test funziona o meno.In caso affermativo, non sembra esserci un altro modo di procedere se non firmare l'app per certificato di piattaforma o renderla un'app di sistema. O puoi aspettare di vedere se qualcun altro ha un'idea migliore. –

+0

Grazie per le informazioni. Mi ha davvero aiutato :) – CodingDecoding

7

Dal livello di API 19, Google has added API.

  • Context.getExternalFilesDirs()
  • Context.getExternalCacheDirs()
  • Context.getObbDirs()

applicazioni non deve essere permesso di scrittura a dispositivi di memorizzazione esterni secondari, tranne nelle directory specifiche pacchetto come consentito dalle autorizzazioni sintetizzati. Limitare le scritture in questo modo garantisce che il sistema possa ripulire i file quando le applicazioni vengono disinstallate.

Di seguito è riportato l'approccio per ottenere la directory specifica dell'applicazione su scheda SD esterna con percorsi assoluti.

Context _context = this.getApplicationContext(); 

File fileList2[] = _context.getExternalFilesDirs(Environment.DIRECTORY_DOWNLOADS); 

if(fileList2.length == 1) { 
    Log.d(TAG, "external device is not mounted."); 
    return; 
} else { 
    Log.d(TAG, "external device is mounted."); 
    File extFile = fileList2[1]; 
    String absPath = extFile.getAbsolutePath(); 
    Log.d(TAG, "external device download : "+absPath); 
    appPath = absPath.split("Download")[0]; 
    Log.d(TAG, "external device app path: "+appPath); 

    File file = new File(appPath, "DemoFile.png"); 

    try { 
     // Very simple code to copy a picture from the application's 
     // resource into the external file. Note that this code does 
     // no error checking, and assumes the picture is small (does not 
     // try to copy it in chunks). Note that if external storage is 
     // not currently mounted this will silently fail. 
     InputStream is = getResources().openRawResource(R.drawable.ic_launcher); 
     Log.d(TAG, "file bytes : "+is.available()); 

     OutputStream os = new FileOutputStream(file); 
     byte[] data = new byte[is.available()]; 
     is.read(data); 
     os.write(data); 
     is.close(); 
     os.close(); 
    } catch (IOException e) { 
     // Unable to create file, likely because external storage is 
     // not currently mounted. 
     Log.d("ExternalStorage", "Error writing " + file, e); 
    } 
} 

uscita Log dall'alto appare come:

context.getExternalFilesDirs() : /storage/extSdCard/Android/data/com.example.remote.services/files/Download 

external device is mounted. 

external device download : /storage/extSdCard/Android/data/com.example.remote.services/files/Download 

external device app path: /storage/extSdCard/Android/data/com.example.remote.services/files/ 
0

Ho risolto questo problema rimuovendo il android:maxSdkVersion="18" in uses-permission nel file manifesto. I.e. utilizzare questo:

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

invece di:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 
       android:maxSdkVersion="18" /> 
0

Verificare se l'utente sta avendo il permesso di storage esterno oppure no. In caso contrario, utilizzare la directory cache per salvare il file.

final boolean extStoragePermission = ContextCompat.checkSelfPermission(
       context, Manifest.permission.WRITE_EXTERNAL_STORAGE) 
       == PackageManager.PERMISSION_GRANTED; 

      if (extStoragePermission && 
     Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) { 
       parentFile = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES); 
      } 
      else{ 
       parentFile = new File(context.getCacheDir(), Environment.DIRECTORY_PICTURES); 
      }