I am writing an app using Camera2 API, which should show preview from camera and take a picture. Currently my code works as follows:
TextureView.SurfaceTextureListener.onSurfaceTextureAvailable
to be calledsetDefaultBufferSize
with new size for its TextureView
's SurfaceTexture
TextureView
starts to show image from cameraonPause
and steps 1-4 are followed again after onResume
Surface
instance is shared between Fragment and camera logic classes: the shared variable is initialized with it in TextureView.SurfaceTextureListener.onSurfaceTextureAvailable
and is set to null when TextureView.SurfaceTextureListener.onSurfaceTextureDestroyed
is calledThis works fine for some devices of popular brands with modern Android versions, but the app should work on the particular generic Chinese tablet with Android 6 ("CameraManager: Using legacy camera HAL
"), and there I face a problem.
setDefaultBufferSize
is 1280x720Surface::setBuffersUserDimensions(this=0x7f55fb5200,w=640,h=480)
messagessetDefaultBufferSize
too early on first Camera Fragment setup, and only when the view is recreated when after the app was minimized, the needed resolution is "picked up"setDefaultBufferSize
in lambda passed to TextureView.post
, and it solved the problem except for the case when I should ask for user's permissions on Camera Fragment (ie when user opens the camera for the first time), so the Fragment is paused a few times to show permissions pop-ups. However, without TextureView.post
setDefaultBufferSize
is also called in main thread, so I guess that delay caused by TextureView.post
was the game changer heresetDefaultBufferSize
docs I see: The new default buffer size will take effect the next time the image producer requests a buffer to fill. For Canvas this will be the next time Surface.lockCanvas is called. For OpenGL ES, the EGLSurface should be destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated (via eglCreateWindowSurface) to ensure that the new default size has taken effect. It seems to me that it may be about the caseSolved this by overriding onSurfaceTextureSizeChanged
of SurfaceTextureListener
and calling surfaceTexture.setDefaultBufferSize
there with the desired preview size. When default buffer size is overridden with incorrect size (during initialization), this method is called, and I override it again.