2011-01-28 13 views
17

Sto provando a selezionare un file immagine dalla galleria fotografica e scrivere sulla sdcard. Di seguito è riportato il codice che genera un'eccezione. Sembra lanciare questa eccezione quando si tenta di creare FileOutputStream. Ho aggiunto la seguente riga al file manifest nidificata all'interno dell'elemento dell'applicazione. Non riesco a trovare una soluzione al problema:java.io.FileNotFoundException (Autorizzazione negata) Durante il tentativo di scrittura sulla sdcard Android

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

public boolean saveSelectedImage(Uri selectedImage, int imageGroup, 
     int imageNumber) 
{ 
    boolean exception = false; 
    InputStream input = null; 
    OutputStream output = null; 
    if(externalStorageIsWritable()) 
    { 
     try 
     { 
      ContentResolver content = ctx.getContentResolver(); 
      input = content.openInputStream(selectedImage); 
      if(input != null) Log.v(CLASS_NAME, "Input Stream Opened successfully"); 
      File outFile = null; 

      File root = Environment.getExternalStorageDirectory(); 
      if(root == null) Log.v(CLASS_NAME, "FAILED TO RETRIEVE DIRECTORY"); 
      else Log.v(CLASS_NAME, "ROOT DIRECTORY is:"+root.toString()); 

      output = new FileOutputStream(root+"/Image"+ imageGroup + "_" + imageNumber + ".png"); 

      if(output != null) Log.e(CLASS_NAME, "Output Stream Opened successfully"); 
      // output = new FileOutputStream 
      // ("/sdcard/Image"+imageGroup+"_"+imageNumber+".png"); 

      byte[] buffer = new byte[1000]; 
      int bytesRead = 0; 
      while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) 
      { 
       output.write(buffer, 0, buffer.length); 
      } 
     } catch (Exception e) 
     { 

      Log.e(CLASS_NAME, "Exception occurred while moving image: "); 
      e.printStackTrace(); 

      exception = true; 
     } finally 
     { 
      // if(input != null)input.close(); 
      // if(output != null)output.close(); 
      // if (exception) return false; 
     } 

     return true; 
    } else 
     return false; 

} 
+0

Hai richiesto il permesso di scriverlo nel tuo manifest? –

+1

Ho trovato la risposta al mio problema L'elemento uses-permission deve essere all'esterno dell'elemento dell'applicazione nel file manifest. – joefischer1

risposta

0

Si può provare con:

String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png"; 

File myFile = new File();  
input = new FileInputStream(myFile); 
7

È inoltre necessario assicurarsi che il sottosistema di archiviazione esterna è nello stato corretto ; utilizzare Environment.getExternalStorageState() e cercare Environment.MEDIA_MOUNTED che è l'unico stato sicuro.

È anche consigliabile restringere la gestione delle eccezioni a IOException attorno a tali sezioni, in modo da non eseguire il recupero eccessivo da problemi specifici dell'IO, ad es. media non montata.

Se sono necessari eventi, sono presenti intenti di trasmissione (Intent.ACTION_MEDIA_xxx) con le stesse informazioni che è possibile registrare con IntentListener.

Si noti inoltre che la memoria esterna può essere disattivata quando si utilizza l'USB per il debug!

C'è anche un periodo prolungato durante l'avvio del dispositivo, dove la memoria esterna non è disponibile. Se fai qualcosa nei servizi all'avvio, questo è un problema.

In generale, l'applicazione deve essere a conoscenza dello stato di archiviazione esterna durante l'accesso e gestire i casi in cui non è disponibile o non è disponibile durante l'accesso.

+0

Giusto per essere precisi, è necessario verificare che Environment.getExternalStorageState() restituisca Environment.MEDIA_MOUNTED. Questo è l'unico stato di archiviazione che consente la scrittura. – RenniePet

+0

grazie ho modificato la mia risposta per riflettere questo. –

24

Questo è il modo in cui il file manifesto dovrebbe essere simile

<application android:icon="@drawable/icon" android:label="@string/app_name"> 
    <activity android:name=".WriteCBTextToFileActivity" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

+0

Grazie mille. Funziona bene :) –

+8

Ciao, il mio Manifest sembra così e ho ancora questo errore ... – MichalK

+0

Puoi condividere il file manifest – Saurabh

3

Se si dispone delle autorizzazioni necessarie fissati nel manifesto, assicurarsi che il dispositivo non è in "Disco Drive "mode quando si collega a un PC. Cambialo in modalità "Solo carica" ​​e dovrebbe funzionare.

9

Ho avuto questo problema e le risposte qui non lo hanno risolto, perché avevo commesso un errore piuttosto stupido.

Assicurati di fornire al tuo emulatore Android una scheda SD ... Avevo lasciato la dimensione della scheda SD vuota e quindi ovviamente non è stato possibile trovare nulla. Inoltre, stavo specificando una directory all'interno di detta scheda SD che non era ancora stata creata, quindi assicurati di prendere in considerazione anche quel caso.

(È possibile modificare le impostazioni della scheda SD di un AVD andando al Android virtuale Gestione dispositivi, modificando il tuo emulatore di scelta, e inserendo un valore per la dimensione della scheda SD)

+1

Perchè dovrebbero lasciarlo vuoto per impostazione predefinita ... Tante app oggi dipendono dalla SDCard . –

0

tenta di utilizzare openFileOutput("filename") per restituire un FileOutputStream invece di specificare la posizione da solo.

Controllare il doc here

+0

Funziona solo con file privati ​​(accessibili solo dall'applicazione chiamante). –

2

Si noti che, oltre a Saurabh risposta, dal momento che API 23 è necessario richiedere le autorizzazioni a run-time.

Vedi qui: https://developer.android.com/training/permissions/requesting.html

E la risposta di Justin Fiedler qui: https://stackoverflow.com/a/33288986/328059

Inoltre, ho avuto diversi casi in cui dopo aver cambiato permesso e rieseguire l'applicazione utilizzando Immediata Eseguire le autorizzazioni non sono state aggiornate . Quindi, come best practice, dopo aver modificato manifest, disinstalla l'app dal dispositivo di destinazione e la ricostruzione.

Problemi correlati