【问题标题】:Take photo from camera in fragment从片段中的相机拍照
【发布时间】:2013-03-02 17:47:12
【问题描述】:

在我的Fragment 中,我尝试从我的相机拍照,但我的FragmentonActivityResult 没有被调用。拍照后,这个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());
                }
            }
        }
    }

【问题讨论】:

    标签: android android-fragments android-camera


    【解决方案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();
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多