Фотосъемка с камеры в фрагменте
В моем Fragment
я пытаюсь сделать снимок с моей камеры, но onActivityResult
моего Fragment
не вызывается. После фотосъемки этот Fragment
не отображается и переключается на мой первый Fragment
. Есть ли другой способ для захвата фотографий в Fragment
, или что я делаю неправильно?
Вот мой текущий код:
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());
}
}
}
}
Ответы
Ответ 1
Я пробовал свой код, работая прекрасным чуваком. Я изменил
PhotosListFragment.this.startActivityForResult(intent, 100);
к
getActivity().startActivityForResult(intent, 100);
который после съемки, возвращаясь к той же активности.
Я думаю, что оба ваших фрагмента находятся в одной и той же активности.
если это так, я предлагаю вам создать новую активность и разместить там новый фрагмент.
Ответ 2
Надеюсь, это поможет вам:
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);
}
}
}
}
Ответ 3
Это одна из самых популярных проблем. Мы можем найти много сообщений об этой проблеме. Но ни один из них не полезен для меня.
Итак, я решил эту проблему, используя это решение.
Позвольте сначала понять, почему это происходит.
Мы можем вызвать startActivityForResult
непосредственно из Fragment, но на самом деле механика позади обрабатываются Activity.
Как только вы вызываете startActivityForResult
из фрагмента, requestCode будет изменен, чтобы привязать идентификатор фрагмента к коду. Это позволит Activity отслеживать, кто отправляет этот запрос после получения результата.
После того, как операция была перенесена обратно, результат будет отправлен в Activity onActivityResult с измененным кодом запроса, который будет декодирован до исходного идентификатора requestCode + Fragment. После этого Activity отправит результат активности на этот фрагмент через onActivityResult. И все это сделано.
Проблема заключается в следующем:
Активность может отправить результат только фрагменту, который был прикреплен непосредственно к Activity, но не к вложенному. Причина, по которой onActivityResult вложенного фрагмента никогда не вызывалась, что бы ни случилось.
Решение:
1) Запустите настройку камеры в фрагменте ниже:
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) Теперь в переопределении родительской активности ** onActivityResult()
: **
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Вы должны вызвать это в родительской активности, чтобы заставить его работать.
3) В вызове фрагмента
@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) Справочные методы для получения URI:
- > Способ получения Uri из растрового изображения
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);
}
- > Способ получения пути к файлу из 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();
}
}
}
Что это.
С помощью этого решения он может применяться для любого отдельного фрагмента, независимо от того, является он вложенным или нет. И да, это также охватывает весь случай! Кроме того, коды также приятны и чисты.
Ответ 4
Для фрагмента это простейшее решение:
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();
}
}