1 /* <lambda>null2 * Copyright 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.camera.integration.view 18 19 import android.graphics.RectF 20 import android.os.Bundle 21 import android.view.LayoutInflater 22 import android.view.View 23 import android.view.ViewGroup 24 import android.widget.Button 25 import android.widget.ToggleButton 26 import androidx.camera.core.CameraSelector.DEFAULT_BACK_CAMERA 27 import androidx.camera.core.CameraSelector.DEFAULT_FRONT_CAMERA 28 import androidx.camera.core.ImageAnalysis.COORDINATE_SYSTEM_VIEW_REFERENCED 29 import androidx.camera.core.impl.utils.executor.CameraXExecutors.mainThreadExecutor 30 import androidx.camera.mlkit.vision.MlKitAnalyzer 31 import androidx.camera.view.LifecycleCameraController 32 import androidx.camera.view.PreviewView 33 import androidx.fragment.app.Fragment 34 import com.google.mlkit.vision.barcode.BarcodeScanner 35 import com.google.mlkit.vision.barcode.BarcodeScanning 36 37 /** Fragment for testing MLKit integration. */ 38 class MlKitFragment : Fragment() { 39 40 private lateinit var cameraController: LifecycleCameraController 41 private lateinit var previewView: PreviewView 42 private lateinit var overlayView: OverlayView 43 private lateinit var toggle: ToggleButton 44 private var barcodeScanner: BarcodeScanner? = null 45 46 override fun onCreateView( 47 inflater: LayoutInflater, 48 container: ViewGroup?, 49 savedInstanceState: Bundle? 50 ): View? { 51 // Set up UI. 52 val view = inflater.inflate(R.layout.mlkit_view, container, false) 53 previewView = view.findViewById(R.id.preview_view) 54 overlayView = view.findViewById(R.id.overlay_view) 55 toggle = view.findViewById(R.id.toggle_camera) 56 toggle.setOnCheckedChangeListener { _, _ -> updateCameraOrientation() } 57 previewView.implementationMode = PreviewView.ImplementationMode.COMPATIBLE 58 // This button resets the pipeline. This is for testing when the detector is closed, 59 // MlKitAnalyzer handles it correctly. 60 view.findViewById<Button>(R.id.restart).setOnClickListener { clearAndSetAnalyzer() } 61 62 // Set up CameraX. 63 cameraController = LifecycleCameraController(requireContext()) 64 cameraController.bindToLifecycle(viewLifecycleOwner) 65 previewView.controller = cameraController 66 clearAndSetAnalyzer() 67 68 // Update states to match UI. 69 updateCameraOrientation() 70 return view 71 } 72 73 override fun onDestroyView() { 74 super.onDestroyView() 75 barcodeScanner?.close() 76 } 77 78 private fun updateCameraOrientation() { 79 cameraController.cameraSelector = 80 if (toggle.isChecked) DEFAULT_BACK_CAMERA else DEFAULT_FRONT_CAMERA 81 } 82 83 private fun clearAndSetAnalyzer() { 84 barcodeScanner?.close() 85 barcodeScanner = BarcodeScanning.getClient() 86 87 cameraController.clearImageAnalysisAnalyzer() 88 val scanner = barcodeScanner!! 89 cameraController.setImageAnalysisAnalyzer( 90 mainThreadExecutor(), 91 MlKitAnalyzer( 92 listOf(scanner), 93 COORDINATE_SYSTEM_VIEW_REFERENCED, 94 mainThreadExecutor() 95 ) { result -> 96 val barcodes = result.getValue(scanner) 97 if (barcodes != null && barcodes.size > 0) { 98 overlayView.setTileRect(RectF(barcodes[0].boundingBox)) 99 overlayView.invalidate() 100 } 101 } 102 ) 103 } 104 } 105