Search code examples
javaandroidgalaxy-tab

Samsung Galaxy Tab 7.0 restarts app on return from camera intent


My code works as expected on smaller and bigger devices (Motorola Xoom, Samsung Galaxy Player 4.0, Kyocera Digno), but for the Samsung Galaxy Tab 7.0, after launching an ACTION_IMAGE_CAPTURE intent and taking a picture, when the app returns onDestroy() is called, followed by onCreate(), then onActivityResult() is called, and finally, onDestroy() and onCreate() are called again, which is of course undesireable - only onActivityResult() should be called.

Possibles clues:

  • The Galaxy Tab 7.0 has a screen size that is explicity not supported in the manifest file (and this is the only device I have tested with an unsupported screen size), so the user may choose scretch-to-fit or zoom-to-fit. Both UIs have the same (bad) behavior.
  • The camera activity seems to switch orientation when previewing a picture. My app only supports portrait mode (edit: on smaller screens - on non-xlarge screens, it supports orientation changes). Maybe the orientation change is destroying my activity, somehow.
  • I have tried launching and returning from a different intent (email intent), and my app is not destroyed and re-created in that case.

Let me know if more information or a code sample is needed.

Edit: the issue has been narrowed down to the orientation change. As per Karthik's answer, setting android:configChanges="orientation" fixes the issue. The only problem is, my app supports orientation changes on xlarge screens. This setting breaks this functionality on those devices. I've tried using android:configChanges="@string/config_changes" and providing a different string depending on the screen size, but now I'm getting an "Installation error: INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION". According to this, Android Activity, how to override manifest's android:configChanges with Java code?, there is no way to set it programmatically. Is my only option left to handle all orientation changes in my app manually?


Solution

  • I discovered that the reason my app restarts is because the device runs out of memory when starting the camera app and the OS recycled my main Activity. That wouldn't be a problem, except I had a Fragment-based layout and some Fragment initialization was being done in onCreate(), regardless of the savedInstanceState. This caused the automatic Fragment restoration to be discarded and made the app look like it was restarting from the beginning when in fact it was just trying to be restored.

    Ex:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // add main menu -- WRONG!
        MainMenuFragment mainMenu = new MainMenuFragment();
        FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
        ft.add(R.id.contents, mainMenu);
        ft.commit();
    
        if (savedInstanceState != null) {
            // <restore state>
        }
        else {
            // <initialize stuff>
        }
    }
    

    To fix it, I skipped the Fragment initialization when savedInstanceState was not null and made sure that the state was being saved correctly in onSaveInstanceState() and restored in onCreate(), and implemented the normal handling for onActivityResult().

    Ex:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        if (savedInstanceState != null) {
            // <restore state>
        }
        else {
            // <initialize stuff>
    
            // add main menu -- CORRECT!
            MainMenuFragment mainMenu = new MainMenuFragment();
            FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
            ft.add(R.id.contents, mainMenu);
            ft.commit();
        }
    }