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;
}
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" />
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.)
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.
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.
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.
Sie können versuchen mit:
String myPath=Environment.getExternalStorageDirectory()+"/Image"+ imageGroup + "_" + imageNumber + ".png";
File myFile = new File();
input = new FileInputStream(myFile);
Verwenden Sie openFileOutput("filename")
, um einen FileOutputStream zurückzugeben, anstatt den Speicherort selbst anzugeben.
Überprüfen Sie das doc hier