0

I am trying to use android:configChanges="keyboardHidden|orientation|screenSize" in my Manifest so that I cannot lose state of my VideoView when configuration changes happen. This means I need to choose the layouts myself on the configuration. The problem I am having is that when I first initialize which view to use in onCreate, here:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.activity_make_photo_video_land);

        } else if (getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_PORTRAIT) {
            setContentView(R.layout.activity_make_photo_video);
        }
}

It chooses the right layout. But when I need to adjust the layout on the configuration change like here:

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        if (getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.activity_make_photo_video_land);
        } else if (getResources().getConfiguration().orientation ==
                Configuration.ORIENTATION_PORTRAIT) {
            setContentView(R.layout.activity_make_photo_video);
        }


    }

It does not use the same instance of the layout, but rather reloads it, which makes my VideoView go black. Then I am unable to press any buttons after that.

Is there a way to reuse the initial layouts? I have tried to set the views like this one setContentView(R.layout.activity_make_photo_video_land); to an Activity activity object, but IDE won't let me, it says Activity is incompatible with void. Because if I could get a reference to that view, then I could reuse it. Or is there a simpler way of doing this that I am not seeing?

Thanks.

enter image description here

Azurespot
  • 3,066
  • 3
  • 45
  • 73

2 Answers2

1

I am suggesting alternative and simple solution for your problem :

1. Move layout activity_make_photo_video_land to /res/layout-land/ folder and rename it as activity_make_photo_video.xml

This way your activity_make_photo_video_land view (rename as activity_make_photo_video) will be inflated when orientation changes to LANDSCAPE

So, you are not required to handle these facility manually from java code.

Change the onCreate() to :

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_make_photo_video_land);

}

Your application will have single layout activity_make_photo_video in /res/layout/ and /res/layout-land/ both folder

UPDATE :

Unless you specify otherwise, a configuration change (such as a change in screen orientation, language, input devices, etc) will cause your current activity to be destroyed, going through the normal activity lifecycle process of onPause(), onStop(), and onDestroy() as appropriate. If the activity had been in the foreground or visible to the user, once onDestroy() is called in that instance then a new instance of the activity will be created, with whatever savedInstanceState the previous instance had generated from onSaveInstanceState(Bundle).

Override onSaveInstanceState(Bundle) and save your state here

You can check more Here

I hope this will work

Kushal
  • 8,100
  • 9
  • 63
  • 82
  • Thanks, that won't work though. The whole reason I need to do it manually is to try to save the state of my `VideoView`. Letting Android choose my layouts when I go back and forth to/from landscape/portrait means the `Activity` gets restarted, and hence I lose my loaded video. Plus, any layout I put in `layout` folder forces portrait. And any layout I put in `layout-land` forces landscape, no matter what they're named. – Azurespot Apr 01 '15 at 04:31
  • I don't entirely understand, but you can't put an object in a Bundle: "... you can't put plain object in a Bundle. And the reason for this is that the point of that saved state is for it to be copied out of your process, so if your process needs to be killed, it can later be copied back in to a new process for you to re-initialize your activity/fragment from. A raw object is only meaningful in the context of the process it is running in, so it isn't possible to correctly copy the reference to such an object out of your current process and in to another." – Azurespot Apr 01 '15 at 04:43
  • 1
    From [here](http://stackoverflow.com/questions/6446961/when-to-use-fragmentmanagerputfragment-and-getfragment/6542596#6542596). – Azurespot Apr 01 '15 at 04:43
  • If you know of a working example that's simple, let me know. I don't see how it would look in the code. Thanks. – Azurespot Apr 01 '15 at 05:33
  • Thanks @Kushal, I was able to find some code out there, very lucky. I managed to override those 2 methods. I can't mark your answer correctly, since there were a lot of different things I changed, but your answer pointed me in the write direction, so thank you! I wrote details in another answer, to keep a log for others. – Azurespot Apr 01 '15 at 05:59
1

Thanks to @Kushal suggestion, I looked into the 2 methods of onSaveInstanceState(Bundle savedInstanceState) and onRestoreInstanceState(Bundle savedInstanceState) to save my VideoView state on configuration change (since this was the root of my problem, and using setContentView was just a hack idea). Turns out I found some code out there. Here is what I did:

  1. Make sure I had a landscape xml and a regular xml. In my layout-land and layout folder respectively with the same name.

  2. Overrode those 2 methods like this:

    private int position = 0;
    
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        super.onSaveInstanceState(savedInstanceState);
        // use onSaveInstanceState in order to store the video
        // playback position for orientation change
        savedInstanceState.putInt("Position",  videoView.getCurrentPosition());
        videoView.pause();
    }
    
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // use onRestoreInstanceState in order to play the video playback
        // from the stored position
        position = savedInstanceState.getInt("Position");
        videoView.seekTo(position);
    }
    
  3. Took the android:configChanges="keyboardHidden|orientation|screenSize" out of my Manifest.

  4. Deleted the onConfigurationChanged(Configuration newConfig) method (didn't need it anymore with #3 gone).

This did it! I was able to change orientation at anytime, and record my video at anytime. Upon returning from recoding the video, it would easily display in either landscape or portrait, without losing the video (screen never went black).

The only problem I have now is my OnTouchListener is disabled, but that's another issue.

Azurespot
  • 3,066
  • 3
  • 45
  • 73