Dans ma Fragment
, j'essaie de prendre une photo de mon appareil photo, mais la onActivityResult
de ma Fragment
n'est pas appelée. Après avoir pris une photo, cette Fragment
n'est pas affichée et passe à ma première Fragment
. Y at-il un autre moyen de capturer des photos dans une Fragment
ou que fais-je de travers?
Voici mon code actuel:
public void takePhoto() {
Intent intent = new Intent("Android.media.action.IMAGE_CAPTURE");
File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
PhotosListFragment.this.startActivityForResult(intent, 100);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 100:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = imageUri;
getActivity().getContentResolver().notifyChange(selectedImage, null);
ContentResolver cr = getActivity().getContentResolver();
Bitmap bitmap;
try {
bitmap = Android.provider.MediaStore.Images.Media
.getBitmap(cr, selectedImage);
viewHolder.imageView.setImageBitmap(bitmap);
Toast.makeText(getActivity(), selectedImage.toString(),
Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(getActivity(), "Failed to load", Toast.LENGTH_SHORT)
.show();
Log.e("Camera", e.toString());
}
}
}
}
J'ai essayé votre code son travail bien mec. j'ai changé
PhotosListFragment.this.startActivityForResult(intent, 100);
à
getActivity().startActivityForResult(intent, 100);
qui après avoir pris la photo, retournant à la même activité.
Je pense que vos deux fragments sont sur la même activité.
si tel est le cas, je vous suggère de créer une nouvelle activité et d'y insérer le nouveau fragment.
J'espère que ceci vous aidera:
public class CameraImage extends Fragment {
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1888;
Button button;
ImageView imageView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.camera_image,
container, false);
button = (Button) rootView.findViewById(R.id.button);
imageView = (ImageView) rootView.findViewById(R.id.imageview);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,
CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
return rootView;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length);
imageView.setImageBitmap(bitmap);
}
}
}
}
C'est l'un des problèmes les plus populaires. Nous pouvons trouver beaucoup de discussions sur ce problème. Mais aucun d'entre eux n'est utile pour moi.
J'ai donc résolu ce problème en utilisant cette solution.
Voyons d'abord pourquoi cela se produit.
Nous pouvons appeler startActivityForResult
directement à partir de Fragment mais, en réalité, le mécanicien derrière est géré par activité.
Une fois que vous appelezstartActivityForResult
depuis un fragment, requestCode sera modifié pour attacher l'identité du fragment au code. Cela permettra à Activity de retracer ceux qui envoient cette demande une fois le résultat reçu.
Une fois l'activité retrouvée, le résultat sera envoyé à onActivityResult d'Activity avec le requestCode modifié qui sera décodé en identifiant le requestCode + identité d'origine. Après cela, Activity enverra le résultat de l'activité à ce fragment via onActivityResult. Et tout est fait.
Le problème est:
Activity pourrait envoyer le résultat uniquement au fragment qui a été attaché directement à Activity mais pas au fragment imbriqué. C'est la raison pour laquelle onActivityResult de fragment imbriqué n'a jamais été appelé quoi qu'il arrive.
Solution:
1) Lancez l'objectif de l'appareil photo dans votre fragment à l'aide du code ci-dessous:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Fragment frag = this;
/** Pass your fragment reference **/
frag.startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); // REQUEST_IMAGE_CAPTURE = 12345
2) Maintenant, dans votre activité parent, remplacez ** onActivityResult()
: **
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Vous devez appeler cela dans l'activité parent pour que cela fonctionne.
3) Dans votre fragment appel:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
// Do something with imagePath
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageview.setImageBitmap(photo);
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
Uri selectedImage = getImageUri(getActivity(), photo);
String realPath=getRealPathFromURI(selectedImage);
selectedImage = Uri.parse(realPath);
}
}
}
4) Méthodes de référence pour obtenir l'URI:
-> Méthode d'obtention d'Uri à partir du bitmap
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
-> Méthode d'obtention du chemin du fichier depuis l'Uri
public String getRealPathFromURI(Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
C'est ça… .. Avec cette solution, elle pourrait être appliquée à n'importe quel fragment, qu'il soit imbriqué ou non. Et oui, cela couvre aussi tous les cas! De plus, les codes sont aussi gentils et propres.
Pour Fragment c'est la solution la plus simple:
cameraIamgeView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
getActivity().startActivityFromFragment(PlaceOrderFragment.this, cameraIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
// super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK && data != null) {
Bitmap bmp = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
/*
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
// convert byte array to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0,
byteArray.length);
*/
cameraIamgeView.setImageBitmap(bmp);
}
}
}catch(Exception e){
Toast.makeText(this.getActivity(), e+"Something went wrong", Toast.LENGTH_LONG).show();
}
}