Android CameraX ничего не показывает
Я реализовал новый пример, вот ссылка, которая описывает новый API CameraX из кодов Google, но TextureView ничего не показывает и выдает следующее исключение:
OpenGLRenderer: [SurfaceTexture-0-7609-1] dequeueImage: SurfaceTexture не прикреплен к представлению
Другие образцы камер, такие как Camera2 и приложение родной камеры, работают нормально. Я использовал эмулятор с уровнем API Q beta 3
класс CameraXFragment: Fragment(), TextureView.SurfaceTextureListener {сопутствующий объект { fun newInstance(): Fragment = CameraXFragment() } частное val REQUEST_CODE_PERMISSIONS = 10 частное val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMER__exmission_Rife_RIFERFIFERGE) onCreateView(inflater: LayoutInflater, контейнер: ViewGroup?, saveInstanceState: Bundle?): Просмотреть? = inflater.inflate(R.layout.fragment_camera, container, false) переопределить веселье onViewCreated(view: View, saveInstanceState: Bundle?) { super.onViewCreated(view, saveInstanceState) viewFinder.surfaceTextureListener = this } личное веселье startCamera() { CameraX.unbindAll() val previewConfig = PreviewConfig.Builder().apply { setTargetAspectRatio(Rational(1, 1)) setTargetResolution(Size(320, 320)) }.build() val preview = Preview(previewConfig) preview.setOnPreviewOutputUpdateListener { view, captureButton.setOnClickListener { val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "${System.currentTimeMillis()}.jpg") imageCapture.takePicture(file, object: ImageCapture.OnImageSavedListener {переопределить fun onError (ошибка: ImageCapture.UseCaseError, message: String, t: Throwable?) { t?.printStackTrace() } переопределить fun onImageSaved(file: File) { val msg = "Снимок успешно завершен: ${file.absolutePath}" Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show() } }) } CameraX.bindToLifecycle(this, preview, imageCapture) } личное увлечение updateTransform() { val matrix = Matrix() val centerXX = viewFinder.width / 2f val centerY = viewFinder.height / 2f val вращение Degrees = when (viewFinder.display.rotation) { Surface.ROTATION_0 -> 0 Surface.ROTATION_90 -> 90 Surface.ROTATION_180 -> 180 Surface.ROTATION_270 -> 270 else -> return } matrix.postRotate(-rotationDegrees.toFloat(), centerX, centerY) viewFinder.setTransform(matrix) } переопределить fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) { } переопределить fun onSurfaceTextureUpdated(surface: SurfaceTexture) { } переопределить fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean {вернуть true } override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int) { if (allPermissionsGranted()) { viewFinder.post { startCamera() } } else { requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS) }geLay_Clayer_Выглядеть, _, _, _, _, _, _, _ -> updateTransform() } } переопределить забаву onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { if (requestCode == REQUEST_CODE_PERMISSIONS) { if (allPermissionsGranted()) { viewFinder.post { startCamera() } } else { Toast.makeText(requireContext(), "Права не предоставлены", Toast.LENGTH_SHORT).show() } } } личное веселье allPermissionsGranted(): Boolean { for (разрешение в REQUIRED_PERMISSIONS) { if (ContextCompat.checkSelfPermission(requireContext(), разрешение)!= PackageManager.PERMISSION_GRANTED) { return false } } вернуть true } }
5 ответов
TextureView необходимо удалить и повторно добавить из родительского представления для прикрепления SurfaceTexture. Это связано с тем, что TextureView внутренне создает свою собственную SurfaceTexture, как только она присоединена к иерархии представления, и эта внутренняя SurfaceTexture корректно отсоединяется только после удаления родительского TextureView из иерархии представления. Вы должны изменить preview.setOnPreviewOutputUpdateListener
чтобы:
preview.setOnPreviewOutputUpdateListener {
val parent = viewFinder.parent as ViewGroup
parent.removeView(viewFinder)
viewFinder.surfaceTexture = it.surfaceTexture
parent.addView(viewFinder, 0)
updateTransform()
}
Похоже, что вы, возможно, скопировали код из кодовой метки, которая теперь была обновлена, чтобы включить повторное вложение представления. Официальный образец также реализует этот вид повторного вложения.
Я столкнулся с той же проблемой, когда следовал codeLabs. Я заблокировал экран, затем снова включил его, и вдруг он заработал нормально, функция захвата тоже сработала. Я понятия не имею об этой ситуации, но вы можете попробовать этот способ в качестве обходного пути. Я использую Q beta 3 в Pixel 3.
PS: Вы можете просто вызвать события onStop и onStart для Activity (например, нажмите home и снова откройте приложение), предварительный просмотр будет работать. На мой взгляд, я думаю, что эта проблема связана с CameraX.bindToLifecycle
,
Если кто -то хочет, чтобы этот код на omtinez в Java, то здесь:
ViewGroup parent = (ViewGroup) textureView.getParent();
parent.removeView(textureView);
parent.addView(textureView, 0);
SurfaceTexture surfaceTexture = previewOutput.getSurfaceTexture();
textureView.setSurfaceTexture(surfaceTexture);
В дополнение к этому ответу. Я решил свою проблему, удалив уровень приложения
hardwareAccelerated="false"
строка из файла AndroidManifest.xml.
Этот код работает у меня
val parent = viewFinder.parent as ViewGroup
parent.removeView(viewFinder)
parent.addView(viewFinder, 0)
val surfaceTexture: SurfaceTexture = it.surfaceTexture
viewFinder.setSurfaceTexture(surfaceTexture)