Reputation: 16120
In my app, there is an option to take pictures from camera. My FragmentActivity
runs in portrait mode only. In my Fragment
, when user taps on button, I launches camera app using:
private void pickFromCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try {
File file = new File(createImageFile());
if(!file.exists()) {
file.createNewFile();
}
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
} catch (Exception e) {
e.printStackTrace();
}
startActivityForResult( intent , ACTION_REQUEST_CAMERA );
}
and in onActivityResult
of fragment, I am doing this:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
super.onActivityResult(requestCode, resultCode, data);
if ( resultCode == Activity.RESULT_OK ) {
switch ( requestCode ) {
case ACTION_REQUEST_GALLERY:
.....
case ACTION_REQUEST_CAMERA:
if(cameraImageFilePath == null) {
// show error message and return
}
addImage(cameraImageFilePath);
break;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
but I am facing strange issue here. On phones, it works normally. On tablet it works when picture is taken in landscape mode and save button is tapped from camera app. But If I take picture in portrait and presses save button, my app crashed. Here is logcat output:
09-18 17:00:09.960: E/AndroidRuntime(13701): FATAL EXCEPTION: main
09-18 17:00:09.960: E/AndroidRuntime(13701): java.lang.RuntimeException: Unable to resume activity {com.dstudios.napa/com.dstudios.napa.HomeActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196708, result=-1, data=null} to activity {com.dstudios.napa/com.dstudios.napa.HomeActivity}: java.lang.NullPointerException
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2291)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2319)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1839)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3191)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.access$600(ActivityThread.java:122)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1031)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.os.Handler.dispatchMessage(Handler.java:99)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.os.Looper.loop(Looper.java:132)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.main(ActivityThread.java:4126)
09-18 17:00:09.960: E/AndroidRuntime(13701): at java.lang.reflect.Method.invokeNative(Native Method)
09-18 17:00:09.960: E/AndroidRuntime(13701): at java.lang.reflect.Method.invoke(Method.java:491)
09-18 17:00:09.960: E/AndroidRuntime(13701): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:844)
09-18 17:00:09.960: E/AndroidRuntime(13701): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:602)
09-18 17:00:09.960: E/AndroidRuntime(13701): at dalvik.system.NativeStart.main(Native Method)
09-18 17:00:09.960: E/AndroidRuntime(13701): Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=196708, result=-1, data=null} to activity {com.dstudios.napa/com.dstudios.napa.HomeActivity}: java.lang.NullPointerException
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.deliverResults(ActivityThread.java:2821)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2278)
09-18 17:00:09.960: E/AndroidRuntime(13701): ... 13 more
09-18 17:00:09.960: E/AndroidRuntime(13701): Caused by: java.lang.NullPointerException
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:152)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.Activity.dispatchActivityResult(Activity.java:4581)
09-18 17:00:09.960: E/AndroidRuntime(13701): at android.app.ActivityThread.deliverResults(ActivityThread.java:2817)
Then I added onActivityResult method in FragmentActivity and surrounded the super call with try catch block as:
@Override
protected void onActivityResult(int arg0, int arg1, Intent arg2) {
// TODO Auto-generated method stub
try {
super.onActivityResult(arg0, arg1, arg2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Now what is happening is exception is catched and no crash but my activity is being restarted. I know there is a way to save the state of the activity using onSavedInstanceState and then... but my activity is very complex , it cannot be restored to its previous state bcz it is the main activity and a lot fragments get loaded and etc... Is there any workaround for this?
I am using Samsung's 10" tablet having Android HoneyComb 3.2.
Edit:
Also, I have added android:configChanges="orientation"
in manifest.
Upvotes: 2
Views: 2222
Reputation: 57203
No, there is no way you can guarantee that your activity will not be destroyed as soon as it lost the screen. It does happen more often when the orientation is switched due to the Camera app requesting Landscape, but you have no command of the situation. The user can choose to run one more background service, or use a custom IMAGE_CAPTURE provider, which will burn all your cards. See also https://stackoverflow.com/a/20783313/192373.
If you cannot go for the onSaveInstanceState(Bundle)
(or even if you can), it may be a much better experience for your users, if you provide an in-app camera, especially on a tablet with fragments.
Upvotes: 1