J'ai une application publiée et l'une des fonctionnalités fondamentales est de permettre à l'utilisateur de prendre une photo, puis de l'enregistrer dans un dossier spécifique de son stockage externe.
Tout semble bien fonctionner, mais j'ai maintenant deux rapports qui prétendent qu'après avoir pris une photo et cliqué sur "Terminé" pour quitter l'appareil photo (et revenir à l'activité), l'application est fermée de force, ce qui amène l'utilisateur retour à l'écran d'accueil.
Cela se produit sur un Samsung Nexus S et le Galaxy Tab. Ci-dessous, j'ai posté mon code pour montrer que je définissais mon intention et comment je gérais l'enregistrement et l'affichage de la photo dans onActivityResult (). Toute indication sur ce qui pourrait provoquer son blocage après avoir cliqué sur "Terminé" pour quitter l'application pour appareil photo serait grandement appréciée!
Encore une fois, cela semble bien fonctionner sur la plupart des appareils, mais je me demandais si leur approche serait plus efficace et universelle. Je vous remercie
Comment je tire la caméra
case ACTION_BAR_CAMERA:
// numbered image name
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(direct + File.separator + fileName); // create
// output
while (output.exists()) { // while the file exists
numImages++; // increment number of images
fileName = "image_" + String.valueOf(numImages) + ".jpg";
output = new File(outputFolder, fileName);
}
camera = new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
uriSavedImage = Uri.fromFile(output); // get Uri of the output
camera.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); //pass in Uri to camera intent
startActivityForResult(camera, 1);
break;
default:
return super.onHandleActionBarItemClick(item, position);
}
return true;
}
Comment je configure onActivityResult ()
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) { // If data was passed successfully
Bundle extras = data.getExtras();
//Bundle extras = data.getBundleExtra(MediaStore.EXTRA_OUTPUT);
/*ad = new AlertDialog.Builder(this).create();
ad.setIcon(Android.R.drawable.ic_menu_camera);
ad.setTitle("Save Image");
ad.setMessage("Save This Image To Album?");
ad.setButton("Ok", this);
ad.show();*/
bmp = (Bitmap) extras.get("data"); // Set the bitmap to the bundle
// of data that was just
// received
image.setImageBitmap(bmp); // Set imageview to image that was
// captured
image.setScaleType(ScaleType.FIT_XY);
}
}
Tout d’abord, précisons: nous avons deux options pour prendre des données d’image dans onActivityResult from Camera:
1. Démarrez l'appareil photo en passant l'adresse Uri exacte de l'image où vous souhaitez enregistrer.
2. Il suffit de démarrer l'appareil photo pour ne laisser passer aucun Uri en loaction.
1 . EN PREMIER CAS:
Démarrez Caméra en passant l'image Uri où vous souhaitez enregistrer:
String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";
File imageFile = new File(imageFilePath);
Uri imageFileUri = Uri.fromFile(imageFile); // convert path to Uri
Intent it = new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
it.putExtra(Android.provider.MediaStore.EXTRA_OUTPUT, imageFileUri);
startActivityForResult(it, CAMERA_RESULT);
Dans onActivityResult, recevez l'image en tant que:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RESULT_OK == resultCode) {
iv = (ImageView) findViewById(R.id.ReturnedImageView);
// Decode it for real
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = false;
//imageFilePath image path which you pass with intent
Bitmap bmp = BitmapFactory.decodeFile(imageFilePath, bmpFactoryOptions);
// Display it
iv.setImageBitmap(bmp);
}
}
2. DANS UN SECOND CAS:
Démarrez Appareil photo sans passer d'image Uri, si vous souhaitez recevoir une image dans Intention (données):
Intent it = new Intent(Android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(it, CAMERA_RESULT);
Dans onActivityResult recive image en tant que:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (RESULT_OK == resultCode) {
// Get Extra from the intent
Bundle extras = data.getExtras();
// Get the returned image from extra
Bitmap bmp = (Bitmap) extras.get("data");
iv = (ImageView) findViewById(R.id.ReturnedImageView);
iv.setImageBitmap(bmp);
}
}
Sur l'événement de clic du bouton de la caméra, vous pouvez essayer ceci:
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(this)));
startActivityForResult(intent, TAKE_PHOTO_CODE);
declare TAKE_PHOTO_CODE globally as:
private static final int TAKE_PHOTO_CODE = 1;
Ajoutez la fonction getTempFile dans le code, ce qui vous aidera à enregistrer l'image nommée myImage.png sur laquelle vous avez cliqué dans la carte mémoire sous le dossier nommé en tant que nom de package de votre application.
private File getTempFile(Context context) {
final File path = new File(Environment.getExternalStorageDirectory(),
context.getPackageName());
if (!path.exists()) {
path.mkdir();
}
return new File(path, "myImage.png");
}
Maintenant sur la fonction OnActivityResult, ajoutez ceci:
if (requestCode == TAKE_PHOTO_CODE) {
final File file = getTempFile(this);
try {
Uri uri = Uri.fromFile(file);
Bitmap captureBmp = Media.getBitmap(getContentResolver(),
uri);
image.setImageBitmap(captureBmp);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
au cas où vous auriez des problèmes de mémoire, ajoutez le code ci-dessous:
@Override
protected void onPause() {
image.setImageURI(null);
super.onPause();
}
J'espère que cela t'aidera
Je suspecte que 3 problèmes possibles aient pu créer votre problème:
Certains périphériques renvoient null
lorsque vous appelez extras.get("data");
dans la méthode onActivityResult
afin que votre problème puisse être un NullPointerException
. Pour résoudre ce problème, vous devez indiquer l'emplacement exact URI
pour indiquer à l'application de caméra où vous souhaitez le stocker et l'utiliser dans onActivityResult
pour récupérer l'image en tant que Bitmap
.
Certains autres périphériques renvoient un Bitmap
de taille normale lorsque extras.get("data");
dans onActivityResult
. Si le bitmap est trop volumineux, OutOfMemmoryError
peut en résulter, vous devrez peut-être décoder votre image dans un format plus petit pour ne pas prendre autant de mémoire. Ces deux liens peuvent vous aider dans cette situation:
http://developer.Android.com/training/displaying-bitmaps/load-bitmap.html
Votre activité est peut-être détruite par GC
et vous devez donc utiliser onSavedInstanceState
et onRestoreInstanceState
pour enregistrer les données de votre Activity
. Voir la réponse de ce post précédent pour plus d'informations.
Je ne sais pas si vous avez déjà traité ces problèmes.
J'espère que cela pourra aider:)
Tout d’abord, assurez-vous de vérifier le code de la demande, vous pourriez peut-être y trouver le résultat de quelqu'un d’autre. Deuxièmement, n'utilisez pas le bitmap de données de l'intention - si tant est que ce soit, c'est petit, mais puisque vous fournissez le chemin pour stocker l'image capturée, il ne devrait même pas être là (voir ici ). Donc, stockez l'URL que vous avez fournie comme chemin du fichier de sortie et lisez Bitmap à partir de là lorsque vous aurez reçu RESULT_OK pour la requête :
...
// save your file uri, not necessarily static
mUriSavedImage = Uri.fromFile(output);
startActivityForResult(camera, MY_REQUEST_CODE);
/* Make a String like "com.myname.MY_REQUEST_CODE" and hash it into int to give it
a bit of uniqueness */
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Bitmap bmp = BitmapFactory.decodeFile(mUriSavedImage);
if (bmp != null) {
image.setImageBitmap(bmp); // Set imageview to image that was
// captured
image.setScaleType(ScaleType.FIT_XY);
} else {
Toast.makeText(this, "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
Bonjour tout ce que je sais réponse a été donnée mais comme c'est aussi l'une des solution la plus simple que j'ai jamais trouvée
Voici l'exemple qui se préoccupe de l'appareil!
AndroidCameraUtils - Téléchargez le projet et à partir du projet de la bibliothèque en l'incluant ci-dessous. L'extrait de code que vous pouvez utiliser!
privé void setupCameraIntentHelper () { mcameraIntentHelper = nouveau CameraIntentHelper (ceci, nouveau CameraIntentHelperCallback () { @Override .__ photoUri.toString ());
Bitmap photo = BitmapHelper.readBitmap(CameraIntentActivity.this, photoUri);
if (photo != null) {
photo = BitmapHelper.shrinkBitmap(photo, 300, rotateXDegrees);
ImageView imageView = (ImageView) findViewById(de.ecotastic.Android.camerautil.sample.R.id.activity_camera_intent_image_view);
imageView.setImageBitmap(photo);
}
}
@Override
public void deletePhotoWithUri(Uri photoUri) {
BitmapHelper.deleteImageWithUriIfExists(photoUri, CameraIntentActivity.this);
}
@Override
public void onSdCardNotMounted() {
Toast.makeText(getApplicationContext(), getString(R.string.error_sd_card_not_mounted), Toast.LENGTH_LONG).show();
}
@Override
public void onCanceled() {
Toast.makeText(getApplicationContext(), getString(R.string.warning_camera_intent_canceled), Toast.LENGTH_LONG).show();
}
@Override
public void onCouldNotTakePhoto() {
Toast.makeText(getApplicationContext(), getString(R.string.error_could_not_take_photo), Toast.LENGTH_LONG).show();
}
@Override
public void onPhotoUriNotFound() {
messageView.setText(getString(R.string.activity_camera_intent_photo_uri_not_found));
}
@Override
public void logException(Exception e) {
Toast.makeText(getApplicationContext(), getString(R.string.error_sth_went_wrong), Toast.LENGTH_LONG).show();
Log.d(getClass().getName(), e.getMessage());
}
});
}
@Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
mCameraIntentHelper.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCameraIntentHelper.onRestoreInstanceState(savedInstanceState);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
mCameraIntentHelper.onActivityResult(requestCode, resultCode, intent);
}
}
NOTE: - J'ai essayé de nombreux exemples pour les utilités de la caméra et bien sûr, il existe un autre moyen de le gérer, mais pour les débutants et les personnes qui ne sont pas très familières avec les concepts de base, ce projet serait plus confortable. Merci!
Suivez les étapes indiquées sur ce lien - link . J'espère que cela vous sera utile.
OR
Récupérer votre image sans planter
Ecrivez le code ci-dessous dans MainActivity
// Storage for camera image URI components
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";
private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI";
// Required for camera operations in order to save the image file on resume.
private String mCurrentPhotoPath = null;
private Uri mCapturedImageURI = null;
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
if (mCurrentPhotoPath != null) {
savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath);
}
if (mCapturedImageURI != null) {
savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString());
}
super.onSaveInstanceState(savedInstanceState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY);
}
if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) {
mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY));
}
super.onRestoreInstanceState(savedInstanceState);
}
J'ai fait face au même problème. Apparemment, la solution consiste à rendre uriSavedImage statique. Je ne sais pas si c'est le meilleur moyen. Mais cela fonctionne pour moi.