Dies ist ein gut dokumentierter Fehler in einigen Versionen von Android. Das heißt, bei Google Experience Builds von Android funktioniert die Bilderfassung nicht wie dokumentiert. Was ich allgemein verwendet habe, ist so etwas in einer Utilities-Klasse.
public boolean hasImageCaptureBug() {
// list of known devices that have the bug
ArrayList<String> devices = new ArrayList<String>();
devices.add("android-devphone1/dream_devphone/dream");
devices.add("generic/sdk/generic");
devices.add("vodafone/vfpioneer/sapphire");
devices.add("tmobile/kila/dream");
devices.add("verizon/voles/sholes");
devices.add("google_ion/google_ion/sapphire");
return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
+ android.os.Build.DEVICE);
}
Wenn ich dann die Bilderfassung starte, erstelle ich eine Absicht, die nach dem Fehler sucht.
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);
dann mache ich in der Aktivität, zu der ich zurückkehre, verschiedene Dinge basierend auf dem Gerät.
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case GlobalConstants.IMAGE_CAPTURE:
Uri u;
if (hasImageCaptureBug()) {
File fi = new File("/sdcard/tmp");
try {
u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
if (!fi.delete()) {
Log.i("logMarker", "Failed to delete " + fi);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
u = intent.getData();
}
}
Dies erspart Ihnen das Schreiben einer neuen Kamera-App, aber dieser Code ist auch nicht besonders gut. Die großen Probleme sind
Mit dem Fehler erhalten Sie niemals Bilder in voller Größe von den Geräten. Sie erhalten Bilder mit einer Breite von 512 Pixel, die in den Bildinhaltsanbieter eingefügt werden. Auf Geräten ohne Fehler funktioniert alles als Dokument, Sie erhalten ein großes normales Bild.
Sie müssen die Liste pflegen. Wie geschrieben, ist es möglich, dass Geräte mit einer Android-Version (z. B. den Builds von Cyanogenmod ) geflasht werden, bei der der Fehler behoben ist. In diesem Fall stürzt Ihr Code ab. Das Update besteht darin, den gesamten Gerätefingerabdruck zu verwenden.
Ich weiß, dass dies bereits beantwortet wurde, aber ich weiß, dass viele Leute darüber gestolpert sind, deshalb werde ich einen Kommentar hinzufügen.
Ich hatte genau das gleiche Problem auf meinem Nexus One. Dies war aus der Datei, die vor dem Start der Kamera-App nicht auf der Festplatte vorhanden war. Daher habe ich sichergestellt, dass die Datei, die vor dem Start der Kamera-App vorhanden war. Hier ist ein Beispielcode, den ich verwendet habe:
Ich erstelle zuerst einen eindeutigen (etwas) Dateinamen mit einem MD5-Hash und lege ihn in den entsprechenden Ordner. Ich überprüfe dann, ob es existiert (sollte nicht, aber es ist eine gute Praxis, es trotzdem zu überprüfen). Wenn es nicht existiert, erhalte ich das übergeordnete Verzeichnis (einen Ordner) und erstelle die Ordnerhierarchie bis dahin (wenn also die Ordner, die zum Speicherort der Datei führen, nicht existieren, werden sie nach dieser Zeile angezeigt. Danach Ich erstelle die Datei. Sobald die Datei erstellt ist, erhalte ich den Uri und übergebe ihn an die Absicht. Dann funktioniert die Schaltfläche OK wie erwartet und alles ist golden.
Wenn Sie nun in der Kamera-App auf die Schaltfläche OK klicken, befindet sich die Datei am angegebenen Speicherort. In diesem Beispiel wäre dies /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
Es ist nicht erforderlich, die Datei in das oben angegebene "onActivityResult" zu kopieren.
quelle
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in Ihrem Manifest haben, wenn Sie neuer als Android 1.5 verwenden - haben ein paar Stunden damit verbracht, das Kamera-Zeug zu debuggen, und dies war nicht enthalten, so dass meine Speicherungen immer fehlschlagen würden.Ich habe eine Reihe von Fotoerfassungsstrategien durchlaufen, und es scheint immer einen Fall zu geben, eine Plattform oder bestimmte Geräte, bei denen einige oder alle der oben genannten Strategien auf unerwartete Weise fehlschlagen. Ich konnte eine Strategie finden, die den folgenden URI-Generierungscode verwendet, der in den meisten, wenn nicht allen Fällen zu funktionieren scheint.
Um einen weiteren Beitrag zur Diskussion zu leisten und Neulingen zu helfen, habe ich eine Beispiel- / Test-App erstellt, die verschiedene Strategien für die Implementierung der Fotoaufnahme zeigt. Beiträge anderer Implementierungen werden definitiv empfohlen, um die Diskussion zu ergänzen.
https://github.com/deepwinter/AndroidCameraTester
quelle
onActivityResult
oder muss ich mich wirklich daran erinnern? Ich müsste es dauerhaft speichern, damit sich meine App sogar daran erinnert, wenn es zerstört wird, während ein Foto aufgenommen wird ...Ich hatte das gleiche Problem, bei dem die Schaltfläche OK in der Kamera-App nichts tat, sowohl auf dem Emulator als auch auf dem Nexus 1.
Das Problem wurde behoben, nachdem ein sicherer Dateiname ohne Leerzeichen und ohne Sonderzeichen in angegeben
MediaStore.EXTRA_OUTPUT
wurde. Wenn Sie außerdem eine Datei angeben, die sich in einem Verzeichnis befindet, das noch nicht erstellt wurde, müssen Sie sie zuerst erstellen. Die Kamera-App erledigt mkdir nicht für Sie.quelle
mkdirs()
anstelle von verwenden,mkdir()
wenn Ihr Pfad mehr als eine Verzeichnisebene hat und Sie möchten, dass alle erstellt werden (mkdir
erstellt nur die letzte, das 'Blatt'-Verzeichnis). Ich hatte einige Probleme damit und diese Antwort half mir.Der von Ihnen beschriebene Workflow sollte so funktionieren, wie Sie ihn beschrieben haben. Es könnte hilfreich sein, wenn Sie uns den Code zur Erstellung der Absicht zeigen könnten. Im Allgemeinen sollten Sie mit dem folgenden Muster das tun können, was Sie versuchen.
Beachten Sie, dass es ist die Kamera Aktivität, die die Datei wird das Erstellen und Speichern, und es ist nicht wirklich Teil Ihrer Anwendung, so dass es keine Schreibrechte für Ihren Anwendungsordner haben. Um eine Datei in Ihrem App-Ordner zu speichern, erstellen Sie eine temporäre Datei auf der SD-Karte und verschieben Sie sie in Ihren App-Ordner im
onActivityResult
Handler.quelle
Um den obigen Kommentar von Yenchi zu verfolgen, führt die Schaltfläche OK auch nichts aus, wenn die Kamera-App nicht in das betreffende Verzeichnis schreiben kann.
Das bedeutet, dass Sie die Datei nicht an einem Ort erstellen können, der nur von Ihrer Anwendung beschreibbar ist (z. B. etwas unter
getCacheDir())
Etwas untergetExternalFilesDir()
funktionieren.Es wäre schön, wenn die Kamera-App eine Fehlermeldung in die Protokolle drucken würde, wenn sie nicht in den angegebenen
EXTRA_OUTPUT
Pfad schreiben könnte , aber ich habe keine gefunden.quelle
Damit die Kamera auf SD-Karte schreibt, aber in der Galerie-App ein neues Album enthält, verwende ich Folgendes:
Bitte beachten Sie, dass Sie jedes Mal einen eindeutigen Dateinamen generieren und die von mir geschriebene 1111.jpg ersetzen müssen. Dies wurde mit Nexus 1 getestet. Die URL wird in der privaten Klasse deklariert, sodass ich das Bild nach dem Aktivitätsergebnis bei Bedarf aus der URL in imageView laden kann, um eine Vorschau anzuzeigen.
quelle
Ich hatte das gleiche Problem und habe es mit folgendem behoben:
Das Problem ist, dass wenn Sie eine Datei angeben, auf die nur Ihre App Zugriff hat (z. B. durch Aufrufen)
getFileStreamPath("file");
)Deshalb habe ich nur sichergestellt, dass die angegebene Datei wirklich existiert und dass JEDER Schreibzugriff darauf hat.
Auf diese Weise hat die Kamera-App Schreibzugriff auf den angegebenen Uri und die OK-Taste funktioniert einwandfrei :)
quelle
Ich empfehle Ihnen, dem Android-Trainning-Beitrag zu folgen, um ein Foto aufzunehmen. Sie zeigen in einem Beispiel, wie man kleine und große Bilder macht. Sie können auch den Quellcode herunterladen von hier
quelle
Ich habe eine einfache Bibliothek erstellt, die die Auswahl von Bildern aus verschiedenen Quellen (Galerie, Kamera) verwaltet, sie möglicherweise an einem Ort (SD-Karte oder interner Speicher) speichert und das Bild zurückgibt. Bitte verwenden Sie es kostenlos und verbessern Sie es - Android-ImageChooser .
quelle
Die Datei muss von der Kamera beschreibbar sein, wie Praveen betonte.
In meiner Verwendung wollte ich die Datei im internen Speicher speichern. Ich habe das gemacht mit:
Hier
cacheFile
ist eine globale Datei, die verwendet wird, um auf die geschriebene Datei zu verweisen. Dann ist in der Ergebnismethode die zurückgegebene Absicht null. Dann sieht die Methode zur Verarbeitung der Absicht folgendermaßen aus:Hier
getImageFile()
ist eine Dienstprogrammmethode zum Benennen und Erstellen der Datei, in der das Bild gespeichert werden soll, undcopyFile()
eine Methode zum Kopieren einer Datei.quelle
Sie können diesen Code verwenden
quelle
Es ist sehr einfach, dieses Problem mit dem Aktivitätsergebniscode zu lösen. Probieren Sie diese Methode einfach aus
quelle
quelle