Android StartActivityForResult奇怪的行为

时间:2016-01-29 17:34:33

标签: android startactivityforresult

所以,我有一个Activity(比方说,OneActivity)调用另一个活动来获得像这样的结果

public class OneActivity extends Activity {

    private static final int REQUEST_OTHER = 1;

    private ImageView btnStartAction;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstaceState);
        setContentView(R.layout.homeView);

        // UI Component Initialization.
    }

    // some code.
    public void btnActionHandleClick(View v) {
        Intent intent = new Intent(getApplicationContext(), OtherActivity.class);
        intent.putExtra("parameter", "someValue");
        startActivityForResult(intent, REQUEST_OTHER);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_OTHER) {
            // do something.
        }
    }
}

另一方面,我有这个具有Camera功能处理功能的OtherActivity,并且我已经添加了Map处理因为它被请求了。在Map特色请求之前,OtherActivity与Camera功能完美配合。

public class OtherActivity : FragmentActivity {
    private static final int REQUEST_CAMERA = 1;

    private ImageView btnTakePicture;
    private ImageView btnClose;
    private ImageView mImageView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.galeryView);

        // UI Component Initialization.
        mImageView = (ImageView) findViewById(R.id.mImageView);
    }

    public void btnTakePictureHandleClick(View v) {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(takePictureIntent, REQUEST_CAMERA);
        }
    }

    public void btnCloseHandleClick(View v) {
        Intent intent = new Intent();
        intent.putExtra("returnVale", "returnValue");
        if (getParent() == null) {
            setResult(Activity.RESULT_OK, intent);
        } else {
            getParent().setResult(Activity.RESULT_OK, intent);
        }
        finish();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_CAMERA && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            mImageView.setImageBitmap(imageBitmap);
        }
    }
}

就像我之前说过的,这段代码工作得很好但是因为我在应用程序中添加了Map交互,所以当我拍照时我开始注意到一些奇怪的行为:它启动了ACTION_IMAGE_CAPTURE意图,但在我拍摄照片后它返回到来自OneActivity类的onActivityResult,resultCode = RESULT_CANCELED。 顺便说一下,Map工作得很好并且有正确的互动:P 有没有其他人之前注意过这样的行为?可能是导致这种情况的地图?

任何意见都将不胜感激。 提前谢谢!

2 个答案:

答案 0 :(得分:1)

我建议做自己的相机活动。这样您就不必担心制造商的不同实现。当三星用相机改变了他们的onActivityResult实现时,我就被烧了。

这是我创建的相机活动:

public class DTechCameraActivity extends Activity implements OnClickListener {

    //declare needed layout variables
    private FrameLayout mCameraPreviewLayout;
    private ImageView mCaputeredBitmapImageView;
    private Button mCaptureImageButton, mRetakeImageButton, mSaveImageButton, mCancelImageButton;

    //declare needed variables
    private Camera mCamera;
    private CameraPreview mPreview;
    private String mBitmapSaveFileLocation;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dtech_camera);

        //Create an instance of Camera
        mCamera = CameraHelper.getCameraInstance();

        //Get file location to save
        mBitmapSaveFileLocation = getIntent().getExtras().getString(DCGroupActivity.CAMERA_DATA);

        //Create and all click listeners for camera buttons
        mCaptureImageButton = (Button) findViewById(R.id.camera_button_capture);
        mCaptureImageButton.setOnClickListener(this);

        mCaputeredBitmapImageView = (ImageView) findViewById(R.id.camera_image_holder);

        mRetakeImageButton = (Button) findViewById(R.id.camera_button_retake);
        mRetakeImageButton.setOnClickListener(this);

        mSaveImageButton = (Button) findViewById(R.id.camera_button_save);
        mSaveImageButton.setOnClickListener(this);

        mCancelImageButton  = (Button) findViewById(R.id.camera_button_cancel);
        mCancelImageButton.setOnClickListener(this);

        //Create our camera preview view and set as main activity view
        mPreview = new CameraPreview(this, mCamera);
        mCameraPreviewLayout = (FrameLayout) findViewById(R.id.camera_preview);
        mCameraPreviewLayout.addView(mPreview);

        showImageCaptureControls();
    }

    @Override
    public void onBackPressed() {
        closeDownCameraAndReturnResult(false);
    }

    @Override
    public void onClick(View view) {
        switch(view.getId()) {
            case R.id.camera_button_capture:
                mCamera.autoFocus(mAutoFocusCallback);
                break;
            case R.id.camera_button_retake:
                showImageCaptureControls();
                break;
            case R.id.camera_button_save:
                closeDownCameraAndReturnResult(true);
                break;
            case R.id.camera_button_cancel:
                closeDownCameraAndReturnResult(false);
                break;
        }
    }

    private PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showCapturedImageControls(data);
        };
    };

    private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            mCamera.takePicture(null, null, mPicture);
        }
    };

    private void showCapturedImageControls(byte[] imageBitmapData) {
        mCamera.stopPreview();

        mCameraPreviewLayout.setVisibility(View.GONE);
        mCaptureImageButton.setVisibility(View.GONE);

        mCaputeredBitmapImageView.setVisibility(View.VISIBLE);
        mRetakeImageButton.setVisibility(View.VISIBLE);
        mSaveImageButton.setVisibility(View.VISIBLE);
        mCancelImageButton.setVisibility(View.VISIBLE);

        saveImageToFile(imageBitmapData);

        mCaputeredBitmapImageView.setImageBitmap(ImageManipulator.convertFileToBitmap(mBitmapSaveFileLocation));

    }

    private void saveImageToFile(byte[] imageBitmapData) {
        ImageManipulator.saveInitialBitmap(imageBitmapData, mBitmapSaveFileLocation);
        int angle = 90;//ImageManipulator.getTakenImageAngle(mBitmapSaveFileLocation);
        if (angle > 0)
            ImageManipulator.rotateAndSaveImage(mBitmapSaveFileLocation, angle);
        else
            ImageManipulator.saveReducedImage(mBitmapSaveFileLocation, BitmapFactory.decodeFile(mBitmapSaveFileLocation), true);
    }

    private void showImageCaptureControls() {
        mCaputeredBitmapImageView.setVisibility(View.GONE);
        mRetakeImageButton.setVisibility(View.GONE);
        mSaveImageButton.setVisibility(View.GONE);
        mCancelImageButton.setVisibility(View.GONE);

        mCameraPreviewLayout.setVisibility(View.VISIBLE);
        mCaptureImageButton.setVisibility(View.VISIBLE);

        mCamera.startPreview();
    }

    private void closeDownCameraAndReturnResult(boolean actionSaveImage) {
        mCamera.release();

        if(!actionSaveImage)
            setResult(RESULT_CANCELED);
        else 
            setResult(RESULT_OK, new Intent());

        this.finish();
    }

}

这就是我所说的:

mDTech.getSelectedEquipment().setImageDesc(
                        mEquipmentDescription.getText().toString());

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, getImageUri());

startActivityForResult(cameraIntent, DTechMobileApplication.CAMERA_REQUEST);

这是我的activityResult代码:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK
            && requestCode == DTechMobileApplication.CAMERA_REQUEST) {
        String imageLocation = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + getImageLocation();

        int angle = ImageManipulator.getTakenImageAngle(imageLocation);
        if (angle > 0)
            ImageManipulator.rotateAndSaveImage(imageLocation, angle);
        else
            ImageManipulator.saveReducedImage(imageLocation, 
                    BitmapFactory.decodeFile(imageLocation), true);

        saveEquipmentImageToPhone(mDTech.getSelectedEquipment()
                .getImageID(), mDTech.getSelectedEquipment()
                .getEquipmentID(), imageLocation, mDTech
                .getSelectedJob().getJobID(), mDTech
                .getAccessingEmployee().getTechID(), mDTech
                .getAccessingEmployee().getName(), mDTech
                .getSelectedEquipment().getEquipmentNum(), mDTech
                .getSelectedEquipment().getDescription());

        mTestImageUpload = SHOULD_UPLOAD_IMAGE;
    }
}

这是CameraHelper:

package com.Utilities;

import android.hardware.Camera;

public class CameraHelper {

    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

}

这是CameraPreview:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    //declare needed constants
    private final String CLASS_NAME = getClass().getName();

    //declare needed variables
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.setDisplayOrientation(90);
        } catch (IOException e) {
            Log.d(CLASS_NAME, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e){
            Log.d(CLASS_NAME, "Error starting camera preview: " + e.getMessage());
        }
    }
}

答案 1 :(得分:0)

嗯,事实证明其中一个视图(布局)应该设置@android:noHistory=true标志,但是我将该配置放入错误的布局而不是正确的布局。由于布局将noHistory标志设置为true,因此它永远不会返回onActivityResult,但会返回到上一个活动。 所以,它不是Google Map Api和相机功能......这是我的错误:(