nerdelicious
nerdelicious

Reputation: 53

Android: retaining camera preview on orientation change while other views can rotate

I'm trying to build a custom camera app. I have a class which extends SurfaceView for the camera preview. When the device changes orientation, this surface is destroyed and recreated, leading to a noticeable "glitch" which diminishes user experience.

What I'd like to do is to prevent this camera preview from having to be recreated on orientation change. In addition, I'd like to have some buttons overlaying this preview (e.g. flash, choice of front/back camera etc.) which WOULD rotate on orientation change. This is similar to what the stock camera app does:

Stock camera in landscape mode.

Stock camera in portrait mode. Note that buttons rotate on orientation change.

Best approach I found (described, for example, here) is to force the activity orientation to landscape using the manifest file and, once the picture is taken, rotate the resulting picture depending on the real device orientation. The drawback of this approach, as I understand it, is that this will prevent rotation of the overlaying buttons as well. Alternatively, as I've read a bit about using fragments and retaining fragment instances, I am wondering whether I could accomplish my goal by retaining the fragment containing the camera preview (yes, I'm a noob).

What would be the proper way to do this?

Upvotes: 5

Views: 4714

Answers (1)

Alex Cohn
Alex Cohn

Reputation: 57173

If your manifest does not declare that the activity handles orientation changes, and is not locked to a single orientation, then rotation of the device will cause the whole activity to get unloaded and reloaded again. Isn't this what you experience now?

If you specify android:configChanges="orientation|screenSize" for your activity, then the user experience will be much smoother. But still, you cannot keep the camera preview "intact" after such rotation; the layout will be rebuilt.

Finally, the approach of the stock camera app is to set fixed (usually landscape) activity orientation and fake the portrait orientation by changing the buttons and other UI elements. But if you look for the system notifications or navigation (soft) buttons on the bottom, you will understand that actually device is locked in landscape, only controls are redrawn. You will also notice that camera apps avoid standard text widgets, because such widgets cannot be easily rotated.

By the way, there is another misunderstanding in your question. If you want to store the picture as portrait, you will need (or not need) manual rotation of the JPEG regardless of your activity orientation. On most devices, camera can only produce landscape JPEG files. Camera API includes setRotation() method, but usually, this only sets an EXIF flag in the JPEG header. Not all image viewers respect this flag. You may need manual rotation of the image if you don't want to compromize.

Upvotes: 5

Related Questions