当我在相机应用程序中旋转屏幕并且我的主要活动失败时,Android相机没有将照片返回到主要活动

时间:2014-12-04 02:55:40

标签: java android camera rotation

这是我的第一篇文章,虽然我是Android新手,但到目前为止,这个社区一直很棒。

这是我用相对简单的应用程序遇到的麻烦。

我的主要活动有图像视图。 onClick,图像视图将打开Camera应用程序。我可以拍照并且相机应用程序将返回该图片并将其设置为图像视图中的图片。

当我从一个方向开始并在另一个方向拍照时,主要活动将崩溃。示例:我最初以垂直方向打开主要活动,打开相机应用程序并切换到水平视图,然后拍照。当相机应用程序尝试返回图片时,主要活动崩溃。当所有活动以相同方向使用时,应用程序不会崩溃。

我认为这是我保存图片的方式或onResume的方式,主要活动没有足够的时间切换到新的方向并在崩溃之前收到图片....或者它可能只是在主要活动恢复时破坏图片。

public class mainActivity extends Activity {

static final int REQUEST_IMAGE_CAPTURE = 1;

//Declares variable of mImageView
ImageView mImageView;
String mCurrentPhotoPath;
//String activityOrientation;

File photoFile = null;

Uri uriFile;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //Setting mImageView to the UI ID of
    mImageView = (ImageView) findViewById(R.id.imageViewLicense); // making mImageView = the        license image view right now just to make sure the code works, I can add to later when adding the medical card 

}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState.containsKey("cameraImageUri")) {
        uriFile = Uri.parse(savedInstanceState.getString("cameraImageUri"));
    }
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    if (uriFile != null) {
        outState.putString("cameraImageUri", uriFile.toString());
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}


//Initialized the camera to take a picture then return the result of the picture


public void dispatchTakePictureIntent(View view)
{
    //Create new intent
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // Create the File where the photo should go

        try {
            photoFile = createImageFile();
        } catch (IOException ex) {

        }
        // Continue only if the File was successfully created
        if (photoFile != null) {

            uriFile = Uri.fromFile(photoFile);

            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                    uriFile);
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}

//Method for rotating the image of the bitmap to the corrected orientation
private Bitmap adjustImageOrientation(Bitmap image) {
    ExifInterface exif;
    try {
        exif = new ExifInterface(mCurrentPhotoPath);
        int exifOrientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        int rotate = 0;
        switch (exifOrientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                rotate = 90;
                break;

            case ExifInterface.ORIENTATION_ROTATE_180:
                rotate = 180;
                break;

            case ExifInterface.ORIENTATION_ROTATE_270:
                rotate = 270;
                break;
        }

        if (rotate != 0) {
            int w = image.getWidth();
            int h = image.getHeight();

            // Setting pre rotate
            Matrix mtx = new Matrix();
            mtx.preRotate(rotate);

            // Rotating Bitmap & convert to ARGB_8888, required by tess
            image = Bitmap.createBitmap(image, 0, 0, w, h, mtx, false);

        }
    } catch (IOException e) {
        return null;
    }
    return image.copy(Bitmap.Config.ARGB_8888, true);
}
//The photo taken in the takePicture method is returned here
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

            // Get the dimensions of the View
            int targetW = mImageView.getWidth();
            int targetH = mImageView.getHeight();

            // Get the dimensions of the bitmap
            BitmapFactory.Options bmOptions = new BitmapFactory.Options();
            bmOptions.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
            int photoW = bmOptions.outWidth;
            int photoH = bmOptions.outHeight;

            // Determine how much to scale down the image
            int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

            // Decode the image file into a Bitmap sized to fill the View
            bmOptions.inJustDecodeBounds = false;
            bmOptions.inSampleSize = scaleFactor;



            bmOptions.inPurgeable = true;

            Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);


            //Rotates the image to the proper orientation
            Bitmap adjustedBitmap = adjustImageOrientation(bitmap);

            //Sets the original imageview as picture taken.
            mImageView.setImageBitmap(adjustedBitmap);


}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}


}

2 个答案:

答案 0 :(得分:1)

当方向发生变化时,Android会重新启动主要活动,因此您需要禁用或处理该方案。您可以在此处找到更多信息:How do I disable orientation change on Android?

答案 1 :(得分:1)

接受的答案是不好的做法,请参阅Why not use always android:configChanges="keyboardHidden|orientation"?

保存mCurrentPhotoPath变量会更好。

@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putString("filepath", mCurrentPhotoPath);
    super.onSaveInstanceState(outState);
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    mCurrentPhotoPath = state.getString("filepath");
    super.onRestoreInstanceState(state);
}