il s'agit d'un bogue bien documenté dans certaines versions d'Android. Autrement dit, sur les versions Google Experience d'Android, la capture d'image ne fonctionne pas comme documenté. ce que j'ai généralement utilisé est quelque chose comme ça dans une classe d'utilitaires.
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);
}
puis lorsque je lance la capture d'image, je crée une intention qui vérifie le bogue.
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);
puis dans l'activité à laquelle je retourne, je fais différentes choses en fonction de l'appareil.
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();
}
}
cela vous évite d'avoir à écrire une nouvelle application pour appareil photo, mais ce code n'est pas non plus génial. les gros problèmes sont
vous n'obtenez jamais d'images en taille réelle des appareils avec le bogue. vous obtenez des images de 512 pixels de large qui sont insérées dans le fournisseur de contenu d'image. sur les appareils sans bogue, tout fonctionne comme un document, vous obtenez une grande image normale.
vous devez maintenir la liste. comme écrit, il est possible que les périphériques soient flashés avec une version d'Android (disons les versions de cyanogenmod ) qui a corrigé le bogue. si cela se produit, votre code plantera. le correctif consiste à utiliser toute l'empreinte digitale de l'appareil.
Je sais que cela a déjà été répondu, mais je sais que beaucoup de gens ont trébuché à ce sujet, alors je vais ajouter un commentaire.
J'ai eu exactement le même problème sur mon Nexus One. Cela provenait du fichier qui n'existait pas sur le disque avant le démarrage de l'application appareil photo. Par conséquent, je me suis assuré que le fichier existait avant de démarrer l'application appareil photo. Voici un exemple de code que j'ai utilisé:
Je crée d'abord un nom de fichier unique (un peu) en utilisant un hachage MD5 et je le mets dans le dossier approprié. Je vérifie ensuite s'il existe (ne devrait pas, mais c'est une bonne pratique de vérifier quand même). S'il n'existe pas, j'obtiens le répertoire parent (un dossier) et crée la hiérarchie des dossiers jusqu'à celui-ci (donc si les dossiers menant à l'emplacement du fichier n'existent pas, ils le seront après cette ligne. Ensuite, après cela Je crée le fichier Une fois le fichier créé, j'obtiens l'Uri et le passe à l'intention, puis le bouton OK fonctionne comme prévu et tout est doré.
Maintenant, lorsque le bouton OK est enfoncé sur l'application appareil photo, le fichier sera présent à l'emplacement donné. Dans cet exemple, ce serait /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
Il n'est pas nécessaire de copier le fichier dans le "onActivityResult" comme indiqué ci-dessus.
la source
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
dans votre manifeste si vous utilisez une version plus récente qu'Android 1.5 - passé quelques heures à déboguer le matériel de la caméra et cela n'était pas inclus, donc mes sauvegardes échoueraient toujours.J'ai suivi un certain nombre de stratégies de capture de photos et il semble toujours y avoir un cas, une plate-forme ou certains appareils, où certaines ou toutes les stratégies ci-dessus échoueront de manière inattendue. J'ai pu trouver une stratégie qui utilise le code de génération d'URI ci-dessous qui semble fonctionner dans la plupart sinon tous les cas.
Pour contribuer davantage à la discussion et aider les nouveaux arrivants, j'ai créé un exemple / test d'application qui montre plusieurs stratégies différentes pour la mise en œuvre de la capture de photos. Les contributions d'autres implémentations sont définitivement encouragées à ajouter à la discussion.
https://github.com/deepwinter/AndroidCameraTester
la source
onActivityResult
ou dois-je vraiment m'en souvenir moi-même? Je devrais l'enregistrer de manière persistante pour que mon application s'en souvienne même si elle est détruite pendant qu'une photo est prise ...J'ai eu le même problème où le bouton OK de l'application appareil photo ne faisait rien, à la fois sur l'émulateur et sur le nexus one.
Le problème a disparu après avoir spécifié un nom de fichier sûr qui est sans espaces, sans caractères spéciaux, dans
MediaStore.EXTRA_OUTPUT
De plus, si vous spécifiez un fichier qui réside dans un répertoire qui n'a pas encore été créé, vous devez d'abord le créer. L'application Appareil photo ne fait pas mkdir pour vous.la source
mkdirs()
plutôt quemkdir()
si votre chemin a plus d'un niveau de répertoire et que vous voulez qu'ils soient tous créés (mkdir
ne crée que le dernier, le répertoire «feuille»). J'ai eu quelques problèmes avec ça, et cette réponse m'a aidé.Le flux de travail que vous décrivez doit fonctionner comme vous l'avez décrit. Cela pourrait aider si vous pouviez nous montrer le code autour de la création de l'intention. En général, le modèle suivant devrait vous permettre de faire ce que vous essayez.
Notez que c'est l' activité de l' appareil photo qui créera et enregistrera le fichier, et qu'elle ne fait pas réellement partie de votre application, elle n'aura donc pas l'autorisation d'écriture sur votre dossier d'application. Pour enregistrer un fichier dans votre dossier d'application, créez un fichier temporaire sur la carte SD et déplacez-le vers votre dossier d'application dans le
onActivityResult
gestionnaire.la source
Pour faire suite au commentaire de Yenchi ci-dessus, le bouton OK ne fera rien non plus si l'application appareil photo ne peut pas écrire dans le répertoire en question.
Cela signifie que vous ne pouvez pas créer le fichier dans un endroit uniquement accessible en écriture par votre application (par exemple, quelque chose sous
getCacheDir())
Quelque chose sousgetExternalFilesDir()
devrait fonctionner, cependant.Ce serait bien si l'application de la caméra imprimait un message d'erreur dans les journaux si elle ne pouvait pas écrire dans le
EXTRA_OUTPUT
chemin spécifié , mais je n'en ai pas trouvé.la source
pour que la caméra écrive sur sdcard mais garde dans un nouvel album sur l'application de la galerie, j'utilise ceci:
Veuillez noter que vous devrez générer un nom de fichier unique à chaque fois et remplacer le 1111.jpg que j'ai écrit. Cela a été testé avec nexus one. l'URI est déclaré dans la classe privée, donc sur le résultat de l'activité, je suis capable de charger l'image de l'URI vers imageView pour un aperçu si nécessaire.
la source
J'ai eu le même problème et je l'ai résolu avec ce qui suit:
Le problème est que lorsque vous spécifiez un fichier auquel seule votre application a accès (par exemple en appelant
getFileStreamPath("file");
)C'est pourquoi je me suis juste assuré que le fichier donné existe vraiment et que TOUT LE MONDE y a accès en écriture.
De cette façon, l'application appareil photo a un accès en écriture à l'Uri donné et le bouton OK fonctionne bien :)
la source
Je vous recommande de suivre le post de formation Android pour capturer une photo. Ils montrent dans un exemple comment prendre de petites et de grandes photos. Vous pouvez également télécharger le code source ici
la source
J'ai créé une bibliothèque simple qui gérera le choix des images à partir de différentes sources (Galerie, Appareil photo), peut-être l'enregistrer dans un emplacement (carte SD ou mémoire interne) et renvoyer l'image, alors n'hésitez pas à l'utiliser et à l'améliorer - Android-ImageChooser .
la source
Le fichier doit être accessible en écriture par la caméra, comme l'a souligné Praveen .
Dans mon utilisation, je voulais stocker le fichier dans la mémoire interne. J'ai fait ça avec:
Voici
cacheFile
un fichier global utilisé pour désigner le fichier qui est écrit. Ensuite, dans la méthode de résultat, l'intention renvoyée est nulle. Ensuite, la méthode de traitement de l'intention ressemble à:Voici
getImageFile()
une méthode utilitaire pour nommer et créer le fichier dans lequel l'image doit être stockée, etcopyFile()
une méthode pour copier un fichier.la source
Vous pouvez utiliser ce code
la source
Il est très simple de résoudre ce problème avec le code de résultat d'activité Simple essayez cette méthode
la source
la source