Android Kotlin - разрешение запуска запускается слишком быстро, когда еще нет вида поверхностиAndroid

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Android Kotlin - разрешение запуска запускается слишком быстро, когда еще нет вида поверхности

Сообщение Anonymous »

Я не могу запустить свой сканер с RegisterForctivityResult. Мне кажется, что запуск запускается слишком быстро, когда еще нет представления поверхности.

Код: Выделить всё

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

previewView = binding.scannerPreviewView
scannerProgressBar = binding.scannerProgressBar
scannerTextView = binding.scannerTextView

previewView.previewStreamState.observe(viewLifecycleOwner) { state ->
when (state) {
PreviewView.StreamState.IDLE -> {
scannerProgressBar.visibility = View.VISIBLE
scannerTextView.visibility = View.GONE
}

PreviewView.StreamState.STREAMING -> {
scannerProgressBar.visibility = View.GONE
scannerTextView.visibility = View.VISIBLE
}
}
}
startCamera()
}
< /code>
и навигация на сам сканер, и, к сожалению, он также просто отображает черный экран. < /p>
Только когда я перевел разрешения с MainActivty в фрагмент, что камера запускается, когда я ввожу его во второй раз. Сканер начинается только после второго вызова. < /P>
abstract class QrScannerGenericFragment : Fragment() {

// UI
private lateinit var previewView: PreviewView
private lateinit var scannerProgressBar: ProgressBar
private lateinit var scannerTextView: TextView

// CAMERA

private val requestCameraPermissionLauncher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
// Permission was granted – proceed to open camera
startCamera()
} else {
// Permission denied – show a message or disable camera functionality

}
}
private lateinit var cameraProvider: ProcessCameraProvider
private lateinit var analysisUseCase: ImageAnalysis

private var rgbaBitmap: Bitmap? = null
private val cameraExecutor by lazy { Executors.newSingleThreadExecutor() }
private val scanner by lazy {
val options = BarcodeScannerOptions.Builder()
.setBarcodeFormats(Barcode.FORMAT_QR_CODE)
.build()
BarcodeScanning.getClient(options)
}

// HELPERS
private var scanned = false

//    private var cameraPermissionHelper: CameraPermissionHelper? = null
private var infoListener: InfoListener? = null

// BINDING
private var _binding: FragmentQrScannerBinding? = null
private val binding get() = _binding!!

override fun onAttach(context: Context) {
super.onAttach(context)
if (context is InfoListener) {
infoListener = context
} else {
throw RuntimeException("$context must implement InfoListener")
}
}

override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentQrScannerBinding.inflate(inflater, parent, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

previewView = binding.scannerPreviewView
scannerProgressBar = binding.scannerProgressBar
scannerTextView = binding.scannerTextView

previewView.previewStreamState.observe(viewLifecycleOwner) { state ->
when (state) {
PreviewView.StreamState.IDLE -> {
scannerProgressBar.visibility = View.VISIBLE
scannerTextView.visibility = View.GONE
}

PreviewView.StreamState.STREAMING -> {
scannerProgressBar.visibility = View.GONE
scannerTextView.visibility = View.VISIBLE
}
}
}
view.post { checkAndRequestCameraPermission() }
}

private fun checkAndRequestCameraPermission() {
context?.let { ctx ->
when {
// 2a.  If permission is already granted, just open the camera
ContextCompat.checkSelfPermission(ctx, Manifest.permission.CAMERA) ==
PackageManager.PERMISSION_GRANTED -> {
startCamera()
}

// 2c. Otherwise, directly request the permission
else -> {
requestCameraPermissionLauncher.launch(Manifest.permission.CAMERA)
}
}
}
}

private fun startCamera() {
scannerProgressBar.visibility = View.VISIBLE
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())

cameraProviderFuture.addListener({
cameraProvider = cameraProviderFuture.get()

val previewUseCase = Preview.Builder()
.build()
.also { it.setSurfaceProvider(previewView.surfaceProvider) }

analysisUseCase = ImageAnalysis.Builder()
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.build()
.also { useCase ->
useCase.setAnalyzer(cameraExecutor) { imageProxy ->
processImageProxy(imageProxy)
}
}

val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
viewLifecycleOwner,
cameraSelector,
previewUseCase,
analysisUseCase
)
}, ContextCompat.getMainExecutor(requireContext()))

}

private fun processImageProxy(imageProxy: ImageProxy) {
try {
val width = imageProxy.width
val height = imageProxy.height

if (rgbaBitmap == null
|| rgbaBitmap?.width != width
|| rgbaBitmap?.height != height
) {
rgbaBitmap?.recycle()
rgbaBitmap = createBitmap(width, height)
}

val buffer = imageProxy.planes[0].buffer
buffer.rewind()
rgbaBitmap!!.copyPixelsFromBuffer(buffer)

val inputImage =
InputImage.fromBitmap(rgbaBitmap!!, imageProxy.imageInfo.rotationDegrees)
scanner.process(inputImage)
.addOnSuccessListener { barcodes ->
if (!scanned) {
barcodes.firstOrNull()?.rawValue?.let { value ->
scanned = true
requireActivity().runOnUiThread {
onQrcodeDetected(value)
}
}
}

}
.addOnFailureListener { e ->
Log.e(LOGCAT_TAG, "Błąd skanowania", e)
}
} catch (e: Exception) {
Log.e(LOGCAT_TAG, "Error processing imageProxy", e)
} finally {
imageProxy.close()
}
}

override fun onResume() {
super.onResume()
scanned = false
}

override fun onStop() {
if (::cameraProvider.isInitialized) {
cameraProvider.unbindAll()
}
super.onStop()
}

override fun onDestroyView() {
super.onDestroyView()

if (::cameraProvider.isInitialized) {
cameraProvider.unbindAll()
}

cameraExecutor.shutdown()
scanner.close()

rgbaBitmap?.run {
if (!isRecycled) recycle()
}
rgbaBitmap = null
_binding = null
}

protected abstract fun onQrcodeDetected(value: String)

companion object {
private const val LOGCAT_TAG = "TagDebug"
}
}
Все работает на Android 11, но не для API 34


Подробнее здесь: https://stackoverflow.com/questions/796 ... s-no-surfa
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»