简体   繁体   English

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

[英]Android Camera not returning photo to main activity when I rotate the screen in the camera application and my main activity fails

This is my first post and while I am new to Android, this community has been great so far. 这是我的第一篇文章,虽然我是Android新手,但到目前为止,这个社区很棒。

Here is the trouble I am having with my relatively simple application. 这是我相对简单的应用程序遇到的麻烦。

I have a image view on my main activity. 我的主要活动有图像视图。 onClick, the image view will open up the Camera application. onClick时,图像视图将打开“相机”应用程序。 I can take a picture and the camera application will return that picture and set it as the picture in the image view. 我可以拍照,相机应用程序将返回该图片并将其设置为图像视图中的图片。

The main activity will crash when I start in one orientation and take a picture in another. 当我从一个方向开始并以另一方向拍照时,主要活动将崩溃。 Example: I open the main activity initially in a vertical orientation, open the camera application and switch to a horizontal view, and take a picture. 示例:首先,我以垂直方向打开主要活动,打开相机应用程序并切换到水平视图,然后拍照。 When the camera application tries to return the picture the main activity crashes. 当摄像头应用程序尝试返回图片时,主要活动崩溃。 The application does not crash when all activities are used in the same orientation. 以相同方向使用所有活动时,应用程序不会崩溃。

I'm lead to believe it's either the way that I am saving the picture or that on onResume, the main activity doesn't have enough time to switch to the new orientation and receive the picture before it crashes.... or maybe that it simply destroys the picture when the main activity is resumed. 我被认为是我保存图片的方式,或者是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;
}


}

Android restarts the main activity when the orientation changes so you'll need to disable or handle that. 方向更改时,Android将重新启动主要活动,因此您需要禁用或处理该活动。 You can find out more here: How do I disable orientation change on Android? 您可以在此处找到更多信息: 如何在Android上禁用方向更改?

The accepted answer is bad practice, see Why not use always android:configChanges="keyboardHidden|orientation"? 可接受的答案是不好的做法,请参阅为什么不始终使用android:configChanges =“ keyboardHidden | orientation”? .

It would be a better idea to save your mCurrentPhotoPath variable. 保存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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM