Properly handling rotation of camera (in TextureView) - android

I try to use a Camera inside my app and I have a problem with proper handling of configuration changes. I know the proper way of handling configuration changes in a typical Activity (onSaveInstanceState etc...), but it's not the case here.
Think of my Activity as a fullscreen camera preview with an overlay shutter button and a frame which will be used to crop the image
What I'm trying to achieve (preview of a stock HTC Sense camera): http://youtu.be/uzfUJUNHY68
That is: the camera preview which is on TextureView should not be recreated on rotation, but the Activity should be orientation-aware, to position elements.
I'm pretty sure I don't want the Activity to be recreated on rotation. So I tried the android:configChanges approach. The problem is that onSurfaceTextureSizeChanged() is still called and the camera preview is rotated and the whole experience is not smooth (the preview lags for a moment and gets "recreated" or something).
I tried locking my Activity to landscape via android:screenOrientation="landscape", but this way onConfigurationChanged() is not called and I don't know how to position other views like in the video above. I guess I could listen to some accelerator events, but I'm pretty sure there is a better way. Is there?

Android camera source.
Lock activity rotation. On method onOrientationChanged of MyOrientationEventListener you can rotate, change positions of views etc. I think it's a best way.

Try with this option.
android:configChanges="keyboardHidden|orientation|screenSize"

Related

stage orientation in flash

I want to implement device rotation in my flash game running on AIR and Android. I use Starling, and when i rotate my device, Starling reinitializes the OpenGL device/context, this will destroy all textures and load them again after reinitialization, and time in which stage is rotated is too big, at least this is what i think it do.
The question is: how can i improve the time in which my stage is rotated ?
I think i can listen to StageOrientationEvent.ORIENTATION_CHANGING to prevent it from default behaviour, and rotate manually my game (rotate main sprite). But if i do this, and for example rotate my device from default orientation to left, then i can't rotate them back to default because the orientation state remains on default and event isn't dispatched. Can i somehow set the orientation state without actually orient the stage?
Did you tried to use:
Starling.handleLostContext = true
to handle lost Context?
This option should be enabled before you launch your Starling instance and it is the easiest way to automatically handle lost context.

Listen for orientation change when screenOrientation="sensorLandscape"

I am wanting to listen for an orientation change in an activity. I've attempted some of the usual things,
onConfigurationChange with orientation in the android:configChanges element
in the manifest,
There's no restart of the activity, (proved with breakpoints), so I can't check getWindowManager().getDefaultDisplay().getRotation() after a rotation unless I check it constantly in my draw thread, which is wasteful.
I could use OrientationEventListener but this gets called for every degree change of the phone, which (imo) is also wasteful.
I am trying to detect the difference from LandscapeLeft and LandscapeRight. I'm unsure how else to approach it at this point.
I don't believe the OrientationEventListener will necessarily tell you whether or not the screen's orientation has changed since it only returns the degrees.
Using getWindowManager().getDefaultDisplay().getRotation() is probably the way to go, but you would have to know the device's default orientation since this will only tell you the rotation based on the default.
There's a decent blog about using the various sensors with orientation changes and the coordinate system here.

Android: onPreviewFrame never called without SurfaceView

On some devices, onPreviewFrame is not called if no SurfaceView was set to display the camera preview.
However, I handle the camera in a service, so I can't set a SurfaceView but I don't want to have visible preview anyway.
How can this be done? Can I programmatically create a SurfaceView and set it with Camera::setPreviewDisplay?
This must be possible or not?
It works on almost every phone without a SurfaceView but not on HTC One X and Google Nexus One...
According to this question, creating a SurfaceView in code works fine. Though I don't think you can create it through a service.
Another approach is to create a 1px-1px SurfaceView inside a RelativeLayout and hiding it with some other view on top of it. (visibility should still be VISIBLE). We use this trick for Path camera UI where we render preview buffers through OpenGL and it works fine.
According to documentation readily configured, visible and displayed surface view is necessary to activate camera preview. It may be overlayued though
From API 11 on, you can use a SurfaceTexture instead of a SurfaceView to get frames from the camera. Then, instead of using Camera.setPreviewDisplay, simply use Camera.setPreviewTexture.
This answer as well as this one discuss this point.

media player screen rotation issue

i have made a media player and have called setDataSource(), setDisplay() and prepare() methods in onSurfaceCreated() method. Everything works fine when the view is rendered for the first time, if i rotate the screen, display disappears and only audio is availaible.How would I get it working? I have used video view for displaying video. Please help me with this issue.
From your question I can see that you are using a surface view which will re initiate when you rotate your screen. so you must set your screen mode to either landscape or portrait based on your requirement.
Else you must figure out some other way other than using surface view.
When you rotate the screen, Activity gets destroyed and a new one is created with a different configuration. If something doesn't work, it means that you should test your application in the landscape mode.

How do I detect screen rotation

I have an activity that is showing a compass, and I need to know the orientation of the screen to properly rotate the needle. I need to distinguish between 90° and 270° degree rotation to properly handle this.
When I rotate the screen (on my Nexus S at least) the activity's onCreate gets called, e.g. when I rotate from portrait to landscape mode. When I rotate from one landscape mode to the other with the top edge raised, onCreate() gets called twice (once for portrait orientation and once for the target landscape mode).
However, when I rotate with the bottom edge up, the screen rotates 180° and onCreate is not getting called. Is there an event that gets fired in this case?
You are correct that at a 180 degree rotation you will not get restarted or get a configuration change, because the configuration has not actually changed. (It is still in landscape or portrait, and everything else is the same.)
However if you are showing a compass, that must mean you are updating it from sensor events. Thus you can just call Display.getRotation() each time you get a sensor update to get the current rotation of the screen. In fact that you need is rotation of interpreting sensor events (or actually how your drawing of them will be modified when it gets to the screen), not just the orientation.
I found a relevant blog post that is well worth reading.
Be sure to read the SDK documentation.
Also check out the discussion about using Display.getRotation() to correctly remap sensor coordinates.
The helper class OrientationEventListener makes it very easy to get call backs on rotation. I would suggest you give it a try.
Just take a look at the SensorManager Documentation, there you can get the best examples and explanations of how to use the accelerometer to get the most precise informations. Instead of making the things just by detecting the phone orientation, with that API you can get the exactly rotation, just like used by racing games like Asphalt and Need For Speed.
As Monchote said, in order to make your needle rotate as expected on the compass, it's better to lock your UI to portrait or landscape, and change your needle angle according to the device rotation angle, which can be gained easily from OrientationListener.
In this way, no matter the auto rotation feature is opened or not by user, you can always get rotation angle change notification. Here's a good example for your reference.
Have a look at the OnConfigurationChanged method to track down the orientation change and re-arrange your UI as needed.
See some sample code

Categories

Resources