从片段中的相机拍照
Posted
技术标签:
【中文标题】从片段中的相机拍照【英文标题】:Take photo from camera in fragment 【发布时间】:2013-03-02 17:47:12 【问题描述】:在我的Fragment
中,我尝试从我的相机拍照,但我的Fragment
的onActivityResult
没有被调用。拍照后,这个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】:希望对您有所帮助:
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);
【讨论】:
这对我有用,正是我想要的!但这只会返回缩略图。 @user2630955 我已经使用了你的代码,但它没有完全工作。我无法查看从相机拍摄的图像。你能帮帮我吗,我在这件事上坚持了两天。【参考方案2】:这是最受欢迎的问题之一。我们可以找到很多关于这个问题的线程。但它们都对我没有用。
所以我已经使用这个解决方案解决了这个问题。
让我们首先了解为什么会发生这种情况。
我们可以直接从 Fragment 调用startActivityForResult
但实际上背后的机制都是由 Activity 处理的。
一旦您从 Fragment 调用 startActivityForResult
,requestCode 将被更改以将 Fragment 的身份附加到代码中。这将使 Activity 能够在收到结果后追踪发送此请求的人。
一旦 Activity 被导航回来,结果将被发送到 Activity 的 onActivityResult 中,修改后的 requestCode 将被解码为原始 requestCode + Fragment 的标识。之后,Activity 会通过 onActivityResult 将 Activity Result 发送到该 Fragment。一切都完成了。
问题是:
Activity 只能将结果发送到直接附加到 Activity 的 Fragment,但不能发送到嵌套的 Fragment。这就是为什么嵌套片段的onActivityResult无论如何都不会被调用的原因。
解决方案:
1) 通过以下代码在 Fragment 中启动 Camera Intent:
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) 现在在您的 Parent Activity 中覆盖 **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的参考方法:
->从Bitmap中获取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();
就是这样。 使用此解决方案,它可以应用于任何单个片段,无论它是否嵌套。是的,它也涵盖了所有情况!此外,代码也很干净。
【讨论】:
嘿伙计,我知道这有点晚了,但它对我有用。非常感谢! 这个答案让我意识到实际上已经覆盖了活动的 onActivityResult 并且没有调用超级......很棒的酱汁。【参考方案3】:我试过你的代码,它工作得很好,伙计。我变了
PhotosListFragment.this.startActivityForResult(intent, 100);
到
getActivity().startActivityForResult(intent, 100);
拍照后,返回相同的活动。
我认为你的两个片段都在同一个活动中。
如果是这种情况,我建议您创建一个新活动并将新片段放入其中。
【讨论】:
是片段或活动上的 onActivityResult 吗? 我的 onActivityResult 没有被触发。我将这两种方法都放在我的片段中。还有什么我应该做的吗? 调用fragment的activity触发onActivityResult【参考方案4】:对于 Fragment,这是最简单的解决方案:
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();
【讨论】:
以上是关于从片段中的相机拍照的主要内容,如果未能解决你的问题,请参考以下文章