web-dev-qa-db-de.com

java.io.FileNotFoundException (Berechtigung abgelehnt) Beim Versuch, auf die Android-SD-Karte zu schreiben

Ich versuche, eine Bilddatei aus der Fotogalerie auszuwählen und auf die SD-Karte zu schreiben. Unten ist der Code, der zu einer Ausnahme führt. Es scheint, diese Ausnahme auszulösen, wenn versucht wird, FileOutputStream zu erstellen. Ich habe die folgende Zeile zu der Manifestdatei hinzugefügt, die innerhalb des Anwendungselements verschachtelt ist. Ich kann keine Lösung für das Problem finden:

<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;

}
17
joefischer1

So sollte Ihre Manifestdatei aussehen

 

<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" />

24
Saurabh

Ich hatte dieses Problem und die Antworten hier konnten das Problem nicht beheben, da ich einen ziemlich dummen Fehler gemacht hatte. 

Vergewissern Sie sich, dass Sie Ihrem Android-Emulator eine SD-Karte geben. Ich hatte die Größe der SD-Karte leer gelassen, sodass sie nichts finden konnte. Darüber hinaus habe ich ein Verzeichnis auf der SD-Karte angegeben, das noch nicht erstellt wurde. Denken Sie also auch daran, diesen Fall zu berücksichtigen.

(Sie können die SD-Karteneinstellungen eines AVDs ändern, indem Sie den Android Virtual Device Manager aufrufen, den gewünschten Emulator bearbeiten und einen Wert für die SD-Kartengröße eingeben.)

9
deluxxxe

Sie müssen auch sicherstellen, dass sich das Subsystem für den externen Speicher im richtigen Zustand befindet. Verwenden Sie Environment.getExternalStorageState() und suchen Sie nach Environment.MEDIA_MOUNTED, das der einzige sichere Zustand ist.

Es ist auch eine gute Idee, die Ausnahmebehandlung in diesen Abschnitten auf IOException zu beschränken, damit nicht von E/A-spezifischen Problemen, z. Medien unmontiert.

Wenn Sie Ereignisse benötigen, gibt es Broadcast Intents (Intent.ACTION_MEDIA_xxx) mit den gleichen Informationen, für die Sie sich mit IntentListener registrieren können.

Beachten Sie auch, dass der externe Speicher disabled sein kann, wenn Sie USB zum Debuggen verwenden!

Es gibt auch einen längeren Zeitraum während des Gerätestarts, in dem kein externer Speicher verfügbar ist. Wenn Sie beim Start Dienste ausführen, ist dies ein Problem.

Im Allgemeinen muss Ihre Anwendung beim Zugriff auf den Status des externen Speichers informiert sein und Fälle behandeln, in denen er nicht verfügbar ist oder beim Zugriff nicht mehr verfügbar ist.

7
escape-llc

Wenn Sie im Manifest die richtigen Berechtigungen festgelegt haben, stellen Sie sicher, dass sich Ihr Gerät nicht im Festplattenmodus befindet, wenn Sie eine Verbindung zu einem PC herstellen. Ändern Sie den Modus "Nur Laden" und es sollte funktionieren.

3
Dave_S

Beachten Sie, dass zusätzlich zu Saurabh answer seit API 23 Berechtigungen zur Laufzeit angefordert werden müssen.

Siehe hier: https://developer.Android.com/training/permissions/requesting.html

Und Justin Fiedlers Antwort hier: https://stackoverflow.com/a/33288986/328059

Ich hatte auch mehrere Fälle, in denen die Berechtigungen nach dem Ändern der Berechtigung und dem erneuten Ausführen der App mit Instant Run nicht aktualisiert wurden. Nach einer Änderung des Manifests deinstalliere ich die App auf dem Zielgerät und baue sie neu auf.

2
Nitay

Sie können versuchen mit:

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

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

Verwenden Sie openFileOutput("filename"), um einen FileOutputStream zurückzugeben, anstatt den Speicherort selbst anzugeben. 

Überprüfen Sie das doc hier

0
Timothy Leung