我正在开发图像捕获应用程序,其中如果您不想保存图像捕获图像后,按后退按钮[onBackPress我发起新活动,即BottomNavigationActivity]它应该切换到家庭活动(就像正常的相机应用程序一样)。
@Override
public void onBackPressed()
{
startActivity(new Intent(getApplicationContext(), BottomNavigationActivity.class));
}
但是当我按下后退按钮时发生TransactionTooLargeException然后应用程序崩溃。我不知道为什么会发生这种情况,即使我没有传输任何大量的数据,如arrayList等,这有助于我解决这个问题 提前谢谢。
CameraFragment.java [这里我捕捉图片]
public class CameraFragment extends Fragment implements SurfaceHolder.Callback, Camera.PictureCallback
{
public static final String TAG = CameraFragment.class.getSimpleName();
public static final String CAMERA_ID_KEY = "camera_id";
public static final String CAMERA_FLASH_KEY = "flash_mode";
public static final String IMAGE_INFO = "image_info";
private static final int PICTURE_SIZE_MAX_WIDTH = 1280;
private static final int PREVIEW_SIZE_MAX_WIDTH = 640;
private int mCameraID;
private String mFlashMode;
private Camera mCamera;
private SquareCameraPreview mPreviewView;
private SurfaceHolder mSurfaceHolder;
private boolean mIsSafeToTakePhoto = false;
private ImageParameters mImageParameters;
private CameraOrientationListener mOrientationListener;
ImageView iv_camera_close;
public static Fragment newInstance() {
return new CameraFragment();
}
public CameraFragment() {}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mOrientationListener = new CameraOrientationListener(context);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Restore your state here because a double rotation with this fragment
// in the backstack will cause improper state restoration
// onCreate() -> onSavedInstanceState() instead of going through onCreateView()
if (savedInstanceState == null) {
mCameraID = getBackCameraID();
mFlashMode = CameraSettingPreferences.getCameraFlashMode(getActivity());
mImageParameters = new ImageParameters();
}
else
{
mCameraID = savedInstanceState.getInt(CAMERA_ID_KEY);
mFlashMode = savedInstanceState.getString(CAMERA_FLASH_KEY);
mImageParameters = savedInstanceState.getParcelable(IMAGE_INFO);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.squarecamera__fragment_camera, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mOrientationListener.enable();
mPreviewView = (SquareCameraPreview) view.findViewById(R.id.camera_preview_view);
mPreviewView.getHolder().addCallback(CameraFragment.this);
final View topCoverView = view.findViewById(R.id.cover_top_view);
final View btnCoverView = view.findViewById(R.id.cover_bottom_view);
iv_camera_close = view.findViewById(R.id.iv_camera_close);
iv_camera_close.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
startActivity(new Intent(getContext(), BottomNavigationActivity.class));
}
});
mImageParameters.mIsPortrait =
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
if (savedInstanceState == null) {
ViewTreeObserver observer = mPreviewView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mImageParameters.mPreviewWidth = mPreviewView.getWidth();
mImageParameters.mPreviewHeight = mPreviewView.getHeight();
mImageParameters.mCoverWidth = mImageParameters.mCoverHeight
= mImageParameters.calculateCoverWidthHeight();
// Log.d(TAG, "parameters: " + mImageParameters.getStringValues());
// Log.d(TAG, "cover height " + topCoverView.getHeight());
resizeTopAndBtmCover(topCoverView, btnCoverView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mPreviewView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
mPreviewView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});
} else {
if (mImageParameters.isPortrait()) {
topCoverView.getLayoutParams().height = mImageParameters.mCoverHeight;
btnCoverView.getLayoutParams().height = mImageParameters.mCoverHeight;
} else {
topCoverView.getLayoutParams().width = mImageParameters.mCoverWidth;
btnCoverView.getLayoutParams().width = mImageParameters.mCoverWidth;
}
}
final ImageView swapCameraBtn = (ImageView) view.findViewById(R.id.change_camera);
swapCameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCameraID == CameraInfo.CAMERA_FACING_FRONT) {
mCameraID = getBackCameraID();
} else {
mCameraID = getFrontCameraID();
}
restartPreview();
}
});
final View changeCameraFlashModeBtn = view.findViewById(R.id.flash);
changeCameraFlashModeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_AUTO)) {
mFlashMode = Camera.Parameters.FLASH_MODE_ON;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_ON)) {
mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
} else if (mFlashMode.equalsIgnoreCase(Camera.Parameters.FLASH_MODE_OFF)) {
mFlashMode = Camera.Parameters.FLASH_MODE_AUTO;
}
setupFlashMode();
setupCamera();
}
});
setupFlashMode();
final ImageView takePhotoBtn = (ImageView) view.findViewById(R.id.capture_image_button);
takePhotoBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePicture();
}
});
}
private void setupFlashMode() {
View view = getView();
if (view == null) return;
final TextView autoFlashIcon = (TextView) view.findViewById(R.id.auto_flash_icon);
if (Camera.Parameters.FLASH_MODE_AUTO.equalsIgnoreCase(mFlashMode)) {
autoFlashIcon.setText("Auto");
} else if (Camera.Parameters.FLASH_MODE_ON.equalsIgnoreCase(mFlashMode)) {
autoFlashIcon.setText("On");
} else if (Camera.Parameters.FLASH_MODE_OFF.equalsIgnoreCase(mFlashMode)) {
autoFlashIcon.setText("Off");
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
// Log.d(TAG, "onSaveInstanceState");
outState.putInt(CAMERA_ID_KEY, mCameraID);
outState.putString(CAMERA_FLASH_KEY, mFlashMode);
outState.putParcelable(IMAGE_INFO, mImageParameters);
super.onSaveInstanceState(outState);
}
private void resizeTopAndBtmCover( final View topCover, final View bottomCover) {
ResizeAnimation resizeTopAnimation
= new ResizeAnimation(topCover, mImageParameters);
resizeTopAnimation.setDuration(800);
resizeTopAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
topCover.startAnimation(resizeTopAnimation);
ResizeAnimation resizeBtmAnimation
= new ResizeAnimation(bottomCover, mImageParameters);
resizeBtmAnimation.setDuration(800);
resizeBtmAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
bottomCover.startAnimation(resizeBtmAnimation);
}
private void getCamera(int cameraID) {
try {
mCamera = Camera.open(cameraID);
mPreviewView.setCamera(mCamera);
} catch (Exception e) {
Log.d(TAG, "Can't open camera with id " + cameraID);
e.printStackTrace();
}
}
/**
* Restart the camera preview
*/
private void restartPreview() {
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
getCamera(mCameraID);
startCameraPreview();
}
/**
* Start the camera preview
*/
private void startCameraPreview() {
determineDisplayOrientation();
setupCamera();
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
setSafeToTakePhoto(true);
setCameraFocusReady(true);
} catch (IOException e) {
Log.d(TAG, "Can't start camera preview due to IOException " + e);
e.printStackTrace();
}
}
/**
* Stop the camera preview
*/
private void stopCameraPreview() {
setSafeToTakePhoto(false);
setCameraFocusReady(false);
// Nulls out callbacks, stops face detection
mCamera.stopPreview();
mPreviewView.setCamera(null);
}
private void setSafeToTakePhoto(final boolean isSafeToTakePhoto) {
mIsSafeToTakePhoto = isSafeToTakePhoto;
}
private void setCameraFocusReady(final boolean isFocusReady) {
if (this.mPreviewView != null) {
mPreviewView.setIsFocusReady(isFocusReady);
}
}
private void determineDisplayOrientation() {
CameraInfo cameraInfo = new CameraInfo();
Camera.getCameraInfo(mCameraID, cameraInfo);
// Clockwise rotation needed to align the window display to the natural position
int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: {
degrees = 0;
break;
}
case Surface.ROTATION_90: {
degrees = 90;
break;
}
case Surface.ROTATION_180: {
degrees = 180;
break;
}
case Surface.ROTATION_270: {
degrees = 270;
break;
}
}
int displayOrientation;
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_FRONT) {
// Orientation is angle of rotation when facing the camera for
// the camera image to match the natural orientation of the device
displayOrientation = (cameraInfo.orientation + degrees) % 360;
displayOrientation = (360 - displayOrientation) % 360;
} else {
displayOrientation = (cameraInfo.orientation - degrees + 360) % 360;
}
mImageParameters.mDisplayOrientation = displayOrientation;
mImageParameters.mLayoutOrientation = degrees;
mCamera.setDisplayOrientation(mImageParameters.mDisplayOrientation);
}
private void setupCamera() {
// Never keep a global parameters
Camera.Parameters parameters = mCamera.getParameters();
Size bestPreviewSize = determineBestPreviewSize(parameters);
Size bestPictureSize = determineBestPictureSize(parameters);
parameters.setPreviewSize(bestPreviewSize.width, bestPreviewSize.height);
parameters.setPictureSize(bestPictureSize.width, bestPictureSize.height);
// Set continuous picture focus, if it's supported
if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
final View changeCameraFlashModeBtn = getView().findViewById(R.id.flash);
List<String> flashModes = parameters.getSupportedFlashModes();
if (flashModes != null && flashModes.contains(mFlashMode)) {
parameters.setFlashMode(mFlashMode);
changeCameraFlashModeBtn.setVisibility(View.VISIBLE);
} else {
changeCameraFlashModeBtn.setVisibility(View.INVISIBLE);
}
mCamera.setParameters(parameters);
}
private Size determineBestPreviewSize(Camera.Parameters parameters) {
return determineBestSize(parameters.getSupportedPreviewSizes(), PREVIEW_SIZE_MAX_WIDTH);
}
private Size determineBestPictureSize(Camera.Parameters parameters) {
return determineBestSize(parameters.getSupportedPictureSizes(), PICTURE_SIZE_MAX_WIDTH);
}
private Size determineBestSize(List<Size> sizes, int widthThreshold) {
Size bestSize = null;
Size size;
int numOfSizes = sizes.size();
for (int i = 0; i < numOfSizes; i++) {
size = sizes.get(i);
boolean isDesireRatio = (size.width / 4) == (size.height / 3);
boolean isBetterSize = (bestSize == null) || size.width > bestSize.width;
if (isDesireRatio && isBetterSize) {
bestSize = size;
}
}
if (bestSize == null) {
Log.d(TAG, "cannot find the best camera size");
return sizes.get(sizes.size() - 1);
}
return bestSize;
}
private int getFrontCameraID() {
PackageManager pm = getActivity().getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
return CameraInfo.CAMERA_FACING_FRONT;
}
return getBackCameraID();
}
private int getBackCameraID() {
return CameraInfo.CAMERA_FACING_BACK;
}
private void takePicture() {
if (mIsSafeToTakePhoto) {
setSafeToTakePhoto(false);
mOrientationListener.rememberOrientation();
Camera.ShutterCallback shutterCallback = null;
Camera.PictureCallback raw = null;
// postView callback occurs when a scaled, fully processed
// postView image is available.
Camera.PictureCallback postView = null;
mCamera.takePicture(shutterCallback, raw, postView, this);
}
}
@Override
public void onResume() {
super.onResume();
if (mCamera == null) {
restartPreview();
}
}
@Override
public void onStop() {
mOrientationListener.disable();
// stop the preview
if (mCamera != null) {
stopCameraPreview();
mCamera.release();
mCamera = null;
}
CameraSettingPreferences.saveCameraFlashMode(getActivity(), mFlashMode);
super.onStop();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
getCamera(mCameraID);
startCameraPreview();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// The surface is destroyed with the visibility of the SurfaceView is set to View.Invisible
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK) return;
switch (requestCode) {
case 1:
Uri imageUri = data.getData();
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
/**
* A picture has been taken
* @param data
* @param camera
*/
@Override
public void onPictureTaken(byte[] data, Camera camera) {
int rotation = getPhotoRotation();
getFragmentManager()
.beginTransaction()
.replace(
R.id.fragment_container,
EditSavePhotoFragment.newInstance(data, rotation, mImageParameters.createCopy()),
EditSavePhotoFragment.TAG)
.addToBackStack(null)
.commit();
setSafeToTakePhoto(true);
}
private int getPhotoRotation() {
int rotation;
int orientation = mOrientationListener.getRememberedNormalOrientation();
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(mCameraID, info);
if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
rotation = (info.orientation - orientation + 360) % 360;
} else {
rotation = (info.orientation + orientation) % 360;
}
return rotation;
}
/**
* When orientation changes, onOrientationChanged(int) of the listener will be called
*/
private static class CameraOrientationListener extends OrientationEventListener {
private int mCurrentNormalizedOrientation;
private int mRememberedNormalOrientation;
public CameraOrientationListener(Context context) {
super(context, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onOrientationChanged(int orientation) {
if (orientation != ORIENTATION_UNKNOWN) {
mCurrentNormalizedOrientation = normalize(orientation);
}
}
/**
* @param degrees Amount of clockwise rotation from the device's natural position
* @return Normalized degrees to just 0, 90, 180, 270
*/
private int normalize(int degrees) {
if (degrees > 315 || degrees <= 45) {
return 0;
}
if (degrees > 45 && degrees <= 135) {
return 90;
}
if (degrees > 135 && degrees <= 225) {
return 180;
}
if (degrees > 225 && degrees <= 315) {
return 270;
}
throw new RuntimeException("The physics as we know them are no more. Watch out for anomalies.");
}
public void rememberOrientation() {
mRememberedNormalOrientation = mCurrentNormalizedOrientation;
}
public int getRememberedNormalOrientation() {
rememberOrientation();
return mRememberedNormalOrientation;
}
}
}
EditSavePhotoFragment.java [此处显示图片预览]
这是切换活动的代码,当我调用此应用程序时崩溃
view.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//getActivity().onBackPressed();
getActivity().startActivity(new Intent(getContext(), BottomNavigationActivity.class));
}
});
下面是完整的源代码
public class EditSavePhotoFragment extends Fragment {
public static final String TAG = EditSavePhotoFragment.class.getSimpleName();
public static String BITMAP_KEY = "bitmap_byte_array";
public static String ROTATION_KEY = "rotation";
public static String IMAGE_INFO = "image_info";
private static final int REQUEST_STORAGE = 1;
SharedPreferences pref;
SharedPreferences.Editor editor;
private static final String PHOTO_PREF = "PHOTO_PREF";
private static final String CAPTURE_IMAGE_PATH = "CAPTURE_IMAGE_PATH";
public static Fragment newInstance(byte[] bitmapByteArray, int rotation,
@NonNull ImageParameters parameters) {
Fragment fragment = new EditSavePhotoFragment();
Bundle args = new Bundle();
args.putByteArray(BITMAP_KEY, bitmapByteArray);
args.putInt(ROTATION_KEY, rotation);
args.putParcelable(IMAGE_INFO, parameters);
fragment.setArguments(args);
return fragment;
}
public EditSavePhotoFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.squarecamera__fragment_edit_save_photo, container, false);
pref = getContext().getSharedPreferences(PHOTO_PREF, 0);
editor = pref.edit();
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
int rotation = getArguments().getInt(ROTATION_KEY);
byte[] data = getArguments().getByteArray(BITMAP_KEY);
ImageParameters imageParameters = getArguments().getParcelable(IMAGE_INFO);
if (imageParameters == null) {
return;
}
final ImageView photoImageView = (ImageView) view.findViewById(R.id.photo);
imageParameters.mIsPortrait =
getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
final View topView = view.findViewById(R.id.topView);
if (imageParameters.mIsPortrait) {
topView.getLayoutParams().height = imageParameters.mCoverHeight;
} else {
topView.getLayoutParams().width = imageParameters.mCoverWidth;
}
rotatePicture(rotation, data, photoImageView);
view.findViewById(R.id.save_photo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
savePicture(photoImageView);
}
});
view.findViewById(R.id.cancel).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//getActivity().onBackPressed();
getActivity().startActivity(new Intent(getContext(), BottomNavigationActivity.class));
}
});
}
private void rotatePicture(int rotation, byte[] data, ImageView photoImageView) {
Bitmap bitmap = ImageUtility.decodeSampledBitmapFromByte(getActivity(), data);
// Log.d(TAG, "original bitmap width " + bitmap.getWidth() + " height " + bitmap.getHeight());
if (rotation != 0) {
Bitmap oldBitmap = bitmap;
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(
oldBitmap, 0, 0, oldBitmap.getWidth(), oldBitmap.getHeight(), matrix, false
);
oldBitmap.recycle();
}
photoImageView.setImageBitmap(bitmap);
}
private void savePicture(ImageView imageView)
{
/*
try
{
SaveImageMethod(imageView);
}
catch (IOException e)
{
e.printStackTrace();
}
*/
requestForPermission();
}
private void SaveImageMethod(ImageView iv) throws IOException
{
BitmapDrawable draw = (BitmapDrawable) iv.getDrawable();
Bitmap bitmap = draw.getBitmap();
FileOutputStream outStream = null;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() + "/SelfiLife");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
Log.d("MainActivity","new IMAGE PATH = "+outFile);
editor.putString(CAPTURE_IMAGE_PATH, String.valueOf(outFile));
editor.commit();
outStream = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
}
private void requestForPermission() {
RuntimePermissionActivity.startActivity(EditSavePhotoFragment.this,
REQUEST_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Activity.RESULT_OK != resultCode) return;
if (REQUEST_STORAGE == requestCode && data != null) {
final boolean isGranted = data.getBooleanExtra(RuntimePermissionActivity.REQUESTED_PERMISSION, false);
final View view = getView();
if (isGranted && view != null) {
ImageView photoImageView = (ImageView) view.findViewById(R.id.photo);
Bitmap bitmap = ((BitmapDrawable) photoImageView.getDrawable()).getBitmap();
Uri photoUri = ImageUtility.savePicture(getActivity(), bitmap);
((CameraActivity) getActivity()).returnPhotoUri(photoUri);
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}