Closed davidhuang24 closed 6 years ago
代码比较老, 没用兼容android 7 解决 Android N 7.0 上 报错:android.os.FileUriExposedException https://blog.csdn.net/yy1300326388/article/details/52787853
拷贝源码的朋友 可以尝试替换一下:
public class ImageCropper extends FrameLayout implements GestureDetector.OnGestureListener, View.OnClickListener, BaseActivity.BackPressedObserver {
private final View iBack;
private final View iSubmit;
private final ImageView iSource;
private final OverlayView vOverlay;
private final TextView tTitle;
private float initMinScale;
private int mOutputWidth;
private int mOutputHeight;
private String mTag;
boolean isInAnimation;
boolean isOutputFixedSize;
private boolean isMultiTouch = false;
private float mLastScale;
private float mLastTranslateX;
private float mLastTranslateY;
private float mLastFingersDistance;
private float mLastFingersCenterX;
private float mLastFingersCenterY;
private final GestureDetector mGestureDetector;
private Callback mCallback;
private ViewPropertyAnimator animRestore;
private Bitmap bmpSource;
public ImageCropper(Context context) {
this(context, null);
}
public ImageCropper(Context context, AttributeSet attrs) {
super(context, attrs);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
mGestureDetector = new GestureDetector(context, this);
LayoutInflater.from(context).inflate(R.layout.image_cropper_layout, this);
(iBack = findViewById(R.id.vBack)).setOnClickListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
iBack.setBackgroundResource(R.drawable.b_white_ripple);
}
(iSubmit = findViewById(R.id.vSubmit)).setOnClickListener(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
iSubmit.setBackgroundResource(R.drawable.b_white_ripple);
}
tTitle = (TextView) findViewById(R.id.t_title);
iSource = (ImageView) findViewById(R.id.i_source);
vOverlay = (OverlayView) findViewById(R.id.v_overlay);
setBackgroundColor(Color.BLACK);
setVisibility(View.INVISIBLE);
}
/**
* @param outputFixedSize 是否按照vImageCropper.crop()方法入参outputWidth和outputHeight来输出,false表示仅只按其比例输出,true为绝对尺寸输出
*/
public void setOutputFixedSize(boolean outputFixedSize) {
isOutputFixedSize = outputFixedSize;
}
public void setTranslucentStatus(int statusBarHeight) {
findViewById(R.id.v_fit).setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, statusBarHeight));
}
private void cropInternal(Uri sourceUri, int outputWidth, int outputHeight, boolean isCircleOverlay, String tag) throws Throwable {
final int mWidth = getWidth();
final int mHeight = getWidth();
if (mWidth * mHeight == 0) return;
setVisibility(View.VISIBLE);
mTag = tag;
mOutputWidth = outputWidth;
mOutputHeight = outputHeight;
vOverlay.reset(mOutputWidth, mOutputHeight, isCircleOverlay);
bmpSource = obtainBmpSource(getContext(), sourceUri, mOutputWidth, mOutputHeight);
if (1f * bmpSource.getWidth() / bmpSource.getHeight() > 1f * iSource.getWidth() / iSource.getHeight()) {
int bitmapHeightAfterFitCenter = (int) (1f * bmpSource.getHeight() * iSource.getWidth() / bmpSource.getWidth());
bmpSource = Bitmap.createScaledBitmap(bmpSource, iSource.getWidth(), bitmapHeightAfterFitCenter, true);
float initMinScaleX = 1f * vOverlay.getOverlayWidth() / iSource.getWidth();
float initMinScaleY = 1f * vOverlay.getOverlayHeight() / bitmapHeightAfterFitCenter;
initMinScale = Math.max(initMinScaleX, initMinScaleY);
} else {
int bitmapWidthAfterFitCenter = (int) (1f * bmpSource.getWidth() * iSource.getHeight() / bmpSource.getHeight());
bmpSource = Bitmap.createScaledBitmap(bmpSource, bitmapWidthAfterFitCenter, iSource.getHeight(), true);
float initMinScaleX = 1f * vOverlay.getOverlayWidth() / bitmapWidthAfterFitCenter;
float initMinScaleY = 1f * vOverlay.getOverlayHeight() / iSource.getHeight();
initMinScale = Math.max(initMinScaleX, initMinScaleY);
}
final float defaultScale = initMinScale > 1 ? initMinScale : 1;
iSource.setTranslationX(0);
iSource.setTranslationY(0);
iSource.setScaleX(defaultScale);
iSource.setScaleY(defaultScale);
iSource.setImageBitmap(bmpSource);
}
/**
* 裁剪图片(输出的图片默认只有比例是按照入参outputWidth和outputHeight获得的,尺寸大小并没有按照指定的尺寸大小。<br>
* 如果要求大小也为入参请调用{@link ImageCropper#setOutputFixedSize(boolean)} 设置值为true) <br>
* 逻辑见{@link ImageCropper#onClick(View)} output = mOutputWidth * mOutputHeight != 0 ? Bitmap.createScaledBitmap(clip, mOutputWidth, mOutputHeight, true) : clip <br>
* ps: createScaledBitmap (小图变大图会造成内容的失真) 55555555<br>
*
* @param sourceUri 原图片路径
* @param outputWidth 输出宽度
* @param outputHeight 输出高度
* @param isCircleOverlay 遮罩蒙板是否为圆形,为圆形的条件时在isCircleOverlay为true的同时,outputWidth等于outputHeight才行
* @param tag 若同一界面有多处裁剪功能,对此传递一个tag标志避免混淆
*/
public void crop(final Uri sourceUri, final int outputWidth, final int outputHeight, final boolean isCircleOverlay, final String tag) {
Const.INSTANCE.setStatusBarDarkTheme(false, (Activity) getContext());
post(new Runnable() {
@Override
public void run() {
try {
cropInternal(sourceUri, outputWidth, outputHeight, isCircleOverlay, tag);
} catch (Throwable e) {
e.printStackTrace();
if (e instanceof OutOfMemoryError) {
Toast.makeText(getContext().getApplicationContext(), "裁剪图片-无法正确加载源数据[1099]", Toast.LENGTH_SHORT).show();
System.gc();
} else {
Toast.makeText(getContext().getApplicationContext(), "裁剪图片-无法正确加载源数据[1088]", Toast.LENGTH_SHORT).show();
}
animExit();
}
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
final int action = event.getAction() & MotionEvent.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_UP:
final float startScale = iSource.getScaleX();
final float endScale;
if (startScale < initMinScale) endScale = initMinScale;
else endScale = startScale;
final float edgeTranslateX = (bmpSource.getWidth() * endScale - vOverlay.getOverlayWidth()) / 2;
final float startTranslateX = iSource.getTranslationX();
final float endTranslateX;
if (startTranslateX > edgeTranslateX) endTranslateX = edgeTranslateX;
else if (startTranslateX < -edgeTranslateX) endTranslateX = -edgeTranslateX;
else endTranslateX = startTranslateX;
final float edgeTranslateY = (bmpSource.getHeight() * endScale - vOverlay.getOverlayHeight()) / 2;
final float startTranslateY = iSource.getTranslationY();
final float endTranslateY;
if (startTranslateY > edgeTranslateY) endTranslateY = edgeTranslateY;
else if (startTranslateY < -edgeTranslateY) endTranslateY = -edgeTranslateY;
else endTranslateY = startTranslateY;
if (endScale == startScale && endTranslateY == startTranslateY && endTranslateX == startTranslateX)
break;
if (animRestore != null) animRestore.cancel();
animRestore = iSource.animate().scaleX(endScale).scaleY(endScale).translationX(endTranslateX)
.translationY(endTranslateY);
animRestore.start();
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (!isMultiTouch) {
isMultiTouch = true;
mLastFingersDistance = 0;
mLastFingersCenterX = 0;
mLastFingersCenterY = 0;
mLastScale = iSource.getScaleX();
mLastTranslateX = iSource.getTranslationX();
mLastTranslateY = iSource.getTranslationY();
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerCount() - 1 < 1 + 1) {
isMultiTouch = false;
}
break;
}
return mGestureDetector.onTouchEvent(event);
}
@Override
public boolean onDown(MotionEvent e) {
mLastScale = iSource.getScaleX();
mLastTranslateX = iSource.getTranslationX();
mLastTranslateY = iSource.getTranslationY();
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
try {
if (!isMultiTouch) {
iSource.setTranslationX(iSource.getTranslationX() - distanceX);
iSource.setTranslationY(iSource.getTranslationY() - distanceY);
} else {
final float deltaX = e2.getX(1) - e2.getX(0);
final float deltaY = e2.getY(1) - e2.getY(0);
float distance = (float) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (mLastFingersDistance == 0) mLastFingersDistance = distance;
float changedScale = (distance - mLastFingersDistance) / (getWidth() * 0.8f);
float changedScaleValue = mLastScale + changedScale;
if (changedScaleValue < initMinScale / 2) changedScaleValue = initMinScale / 2;
iSource.setScaleX(changedScaleValue);
iSource.setScaleY(changedScaleValue);
float centerX = (e2.getX(1) + e2.getX(0)) / 2;
float centerY = (e2.getY(1) + e2.getY(0)) / 2;
if (mLastFingersCenterX == 0 && mLastFingersCenterY == 0) {
mLastFingersCenterX = centerX;
mLastFingersCenterY = centerY;
}
float changedCenterX = centerX - mLastFingersCenterX;
iSource.setTranslationX(mLastTranslateX + changedCenterX);
float changedCenterY = centerY - mLastFingersCenterY;
iSource.setTranslationY(mLastTranslateY + changedCenterY);
}
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
}
return false;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
@Override
public void onClick(View v) {
if (animRestore != null) animRestore.cancel();
if (isInAnimation) return;
if (v == iSubmit) {
if (mCallback != null) {
final float x = ((bmpSource.getWidth() * iSource.getScaleX() - vOverlay.getOverlayWidth()) / 2 - iSource.getTranslationX()) / iSource.getScaleX();
final float width = vOverlay.getOverlayWidth() / iSource.getScaleX();
final float y = ((bmpSource.getHeight() * iSource.getScaleY() - vOverlay.getOverlayHeight()) / 2 - iSource.getTranslationY()) / iSource.getScaleY();
final float height = vOverlay.getOverlayHeight() / iSource.getScaleY();
Bitmap clip = Bitmap.createBitmap(bmpSource, (int) x, (int) y, (int) width, (int) (height));
Bitmap output = (isOutputFixedSize && mOutputWidth * mOutputHeight != 0) ? Bitmap.createScaledBitmap(clip, mOutputWidth, mOutputHeight, true) : clip;
mCallback.onPictureCropOut(output, mTag);
animExit();
}
} else if (v == iBack) {
animExit();
}
}
private void animExit() {
animate().alpha(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
isInAnimation = true;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
isInAnimation = false;
setVisibility(View.GONE);
setAlpha(1f);
final String currentActivity = ((Activity) getContext()).getClass().getSimpleName();
EventBus.getDefault().post(new BusEvent(Bus.INSTANCE.getREFRESH_STATUS_BAR_THEME(), currentActivity));
}
}).start();
}
@Override
public boolean handleBackPressed() {
if (View.GONE != getVisibility()) {
iBack.performClick();
return true;
}
return false;
}
interface Callback {
void onPictureCropOut(Bitmap bitmap, String tag);
}
public void setCallback(Callback cb) {
mCallback = cb;
}
static class Helper {
private static final int VIEW_IMAGE_CROPPER_ID = R.id.view_image_cropper;
private final ViewGroup activityDecorView;
private final ImageCropper mImageCropper;
private Helper(Activity activity) {
mImageCropper = new ImageCropper(activity);
mImageCropper.setId(VIEW_IMAGE_CROPPER_ID);
activityDecorView = (ViewGroup) activity.getWindow().getDecorView();
}
public static Helper with(Activity activity) {
return new Helper(activity);
}
public Helper setCallback(Callback cb) {
mImageCropper.setCallback(cb);
return this;
}
public Helper setOutputFixedSize(boolean isOutputFixedSize) {
mImageCropper.setOutputFixedSize(isOutputFixedSize);
return this;
}
public Helper setTitle(String title) {
mImageCropper.tTitle.setText(title);
return this;
}
Helper setTranslucentStatusHeight(int translucentStatusHeight) {
mImageCropper.setTranslucentStatus(translucentStatusHeight);
return this;
}
public ImageCropper create() {
removeExistingOverlayInView(activityDecorView);
activityDecorView.addView(mImageCropper);
Activity act = Const.INSTANCE.extractActivity(activityDecorView.getContext());
if (act != null) {
final String currentActivity = act.getClass().getSimpleName();
EventBus.getDefault().post(new BusEvent(Bus.INSTANCE.getBACK_PRESSED_SUBSCRIBE(), currentActivity, mImageCropper));
}
return mImageCropper;
}
void removeExistingOverlayInView(ViewGroup parent) {
for (int i = 0; i < parent.getChildCount(); i++) {
View child = parent.getChildAt(i);
if (child.getId() == VIEW_IMAGE_CROPPER_ID) {
parent.removeView(child);
}
if (child instanceof ViewGroup) {
removeExistingOverlayInView((ViewGroup) child);
}
}
}
}
private static Bitmap obtainBmpSource(@NonNull Context context, @NonNull Uri uri, int requiredWidth, int requiredHeight) throws Exception {
final ParcelFileDescriptor parcelFileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
final FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
// options.inSampleSize = calculateInSampleSize(options, Const.INSTANCE.getScreenWidth(), Const.INSTANCE.getScreenWidth());
options.inJustDecodeBounds = false;
Bitmap decodeSampledBitmap = null;
boolean success = false;
while (!success) {
try {
decodeSampledBitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
success = true;
} catch (OutOfMemoryError error) {
error.printStackTrace();
// Log.e("ImageCropper", "decodeSampledBitmap: BitmapFactory.decodeFileDescriptor: ", error);
options.inSampleSize++;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
close(parcelFileDescriptor);
}
int exifOrientation = getExifOrientation(context, uri);
int exifDegrees = exifToDegrees(exifOrientation);
int exifTranslation = exifToTranslation(exifOrientation);
Matrix matrix = new Matrix();
if (exifDegrees != 0) {
matrix.preRotate(exifDegrees);
}
if (exifTranslation != 1) {
matrix.postScale(exifTranslation, 1);
}
if (!matrix.isIdentity()) {
decodeSampledBitmap = transformBitmap(decodeSampledBitmap, matrix);
}
return decodeSampledBitmap;
}
private static Bitmap transformBitmap(@NonNull Bitmap bitmap, @NonNull Matrix transformMatrix) {
try {
Bitmap converted = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), transformMatrix, true);
if (bitmap != converted) {
bitmap.recycle();
bitmap = converted;
}
} catch (OutOfMemoryError error) {
error.printStackTrace();
// Log.e("ImageCropper", "transformBitmap: ", error);
}
return bitmap;
}
private static int calculateInSampleSize(@NonNull BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width lower or equal to the requested height and width.
while ((height / inSampleSize) > reqHeight || (width / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
private static int getExifOrientation(@NonNull Context context, @NonNull Uri imageUri) {
int orientation = ExifInterface.ORIENTATION_UNDEFINED;
try {
InputStream stream = context.getContentResolver().openInputStream(imageUri);
if (stream == null) {
return orientation;
}
orientation = new ImageHeaderParser(stream).getOrientation();
close(stream);
} catch (IOException e) {
e.printStackTrace();
// Log.e("ImageCropper", "getExifOrientation: " + imageUri.toString(), e);
}
return orientation;
}
private static int exifToDegrees(int exifOrientation) {
int rotation;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
case ExifInterface.ORIENTATION_TRANSPOSE:
rotation = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
rotation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
case ExifInterface.ORIENTATION_TRANSVERSE:
rotation = 270;
break;
default:
rotation = 0;
}
return rotation;
}
private static int exifToTranslation(int exifOrientation) {
int translation;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
case ExifInterface.ORIENTATION_TRANSPOSE:
case ExifInterface.ORIENTATION_TRANSVERSE:
translation = -1;
break;
default:
translation = 1;
}
return translation;
}
@SuppressWarnings("ConstantConditions")
private static void close(@Nullable Closeable c) {
if (c != null && c instanceof Closeable) { // java.lang.IncompatibleClassChangeError: interface not implemented
try {
c.close();
} catch (IOException e) {
// silence
}
}
}
}
项目移除了这个工程代码
您的debug-apk运行崩溃,重新编译也崩溃。 1.单选图片确定后崩溃 java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference at ch.ielse.view.imagecropper.ImageCropper.cropInternal(ImageCropper.java:101) at ch.ielse.view.imagecropper.ImageCropper.access$000(ImageCropper.java:25) at ch.ielse.view.imagecropper.ImageCropper$1.run(ImageCropper.java:139) 2.选择拍照后崩溃 io.reactivex.exceptions.OnErrorNotImplementedException: file:///storage/emulated/0/Android/data/ch.ielse.demo.p01/cache/rxPicker/TEMP1595091369.jpg exposed beyond app through ClipData.Item.getUri() at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704) at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701) at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:74) at io.reactivex.observers.SerializedObserver.onError(SerializedObserver.java:155) at io.reactivex.internal.operators.observable.ObservableTakeUntil$TakeUntilObserver.onError(ObservableTakeUntil.java:73) at io.reactivex.subjects.PublishSubject.subscribeActual(PublishSubject.java:95) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableTakeUntil.subscribeActual(ObservableTakeUntil.java:41) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.Observable.subscribe(Observable.java:10828) at io.reactivex.Observable.subscribe(Observable.java:10731) at ch.ielse.demo.p01.MainActivity.takeCamera(MainActivity.java:107) at ch.ielse.demo.p01.MainActivity.access$000(MainActivity.java:26) at ch.ielse.demo.p01.MainActivity$1$1.accept(MainActivity.java:78) at ch.ielse.demo.p01.MainActivity$1$1.accept(MainActivity.java:75) at io.reactivex.internal.observers.ConsumerSingleObserver.onSuccess(ConsumerSingleObserver.java:61) at io.reactivex.internal.operators.single.SingleTakeUntil$TakeUntilMainObserver.onSuccess(SingleTakeUntil.java:92) at io.reactivex.internal.operators.observable.ObservableAllSingle$AllObserver.onComplete(ObservableAllSingle.java:99) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drainLoop(ObservableFlatMap.java:367) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.drain(ObservableFlatMap.java:323) at io.reactivex.internal.operators.observable.ObservableFlatMap$MergeObserver.onComplete(ObservableFlatMap.java:300) at io.reactivex.internal.operators.observable.ObservableFromArray$FromArrayDisposable.run(ObservableFromArray.java:110) at io.reactivex.internal.operators.observable.ObservableFromArray.subscribeActual(ObservableFromArray.java:36) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableFlatMap.subscribeActual(ObservableFlatMap.java:55) at io.reactivex.Observable.subscribe(Observable.java:10842) at io.reactivex.internal.operators.observable.ObservableAllSingle.subscribeActual(ObservableAllSingle.java:34) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.internal.operators.single.SingleTakeUntil.subscribeActual(SingleTakeUntil.java:51) at io.reactivex.Single.subscribe(Single.java:2703) at io.reactivex.Single.subscribe(Single.java:2689) at io.reactivex.Single.subscribe(Single.java:2660) at ch.ielse.demo.p01.MainActivity.requestPermissions(MainActivity.java:155) at ch.ielse.demo.p01.MainActivity$1.onClick(MainActivity.java:74) at ch.ielse.demo.p01.SheetDialog$Builder$1.onClick(SheetDialog.java:142) at android.view.View.performClick(View.java:5730) at android.view.View$PerformClick.run(View.java:22806) at android.os.Handler.handleCallback(Handler.java:836) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:203) at android.app.ActivityThread.main(ActivityThread.java:6519) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1113) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:974) Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/ch.ielse.demo.p01/cache/rxPicker/TEMP1595091369.jpg exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1847) at android.net.Uri.checkFileUriExposed(Uri.java:2346) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:833) at android.content.Intent.prepareToLeaveProcess(Intent.java:8976) at android.content.Intent.prepareToLeaveProcess(Intent.java:8961) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1647) at android.app.Activity.startActivityForResult(Activity.java:4888) at android.app.Activity.startActivityFromFragment(Activity.java:4874) at android.app.Activity$HostCallbacks.onStartActivityFromFragment(Activity.java:7176) at android.app.Fragment.startActivityForResult(Fragment.java:1150) at android.app.Fragment.startActivityForResult(Fragment.java:1139) at ch.ielse.view.imagecropper.RxImagePickerFragment.takeCamera(RxImagePickerFragment.java:170) at ch.ielse.view.imagecropper.RxImagePicker.takeCamera(RxImagePicker.java:59) at ch.ielse.demo.p01.MainActivity.takeCamera(MainActivity.java:104) ... 37 more