国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

炫酷!讓Android同時掃多個二維碼的魔法揭秘

移動開發 Android
超市里別人還在一個一個掃商品二維碼,你的APP卻能"唰"一下瞬間識別整排商品!今天教大家用Google的黑科技MLKit+CameraX,輕松實現這個超酷功能。別擔心,跟著做絕對能搞定!

想象一下:超市里別人還在一個一個掃商品二維碼,你的APP卻能"唰"一下瞬間識別整排商品!今天教大家用Google的黑科技MLKit+CameraX,輕松實現這個超酷功能。別擔心,跟著做絕對能搞定~

準備工作:裝備你的"魔法棒"

// build.gradle 添加這些"魔法材料"
dependencies {
    implementation 'androidx.camera:camera-camera2:1.3.1'       // 相機核心
    implementation 'androidx.camera:camera-lifecycle:1.3.1'      // 生命周期管家
    implementation 'androidx.camera:camera-view:1.3.1'  // 取景器
    implementation 'com.google.mlkit:barcode-scanning:17.1.0'   // 二維碼識別引擎
}
<!-- AndroidManifest.xml 申請相機權限 -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />

?? 就像哈利波特需要魔杖,這些就是我們的"魔法裝備"!記得先在手機設置里開啟相機權限哦~

搭建舞臺:創建掃描界面

<!-- activity_main.xml 布置舞臺 -->
<androidx.camera.view.PreviewView
    android:id="@+id/viewFinder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

?? 這個全屏"魔法鏡"就是我們的掃描窗口,用戶看到的實時畫面都在這里顯示

核心魔法:二維碼識別器

class QRCodeAnalyzer(privateval onDetect: (List<Barcode>) -> Unit) : ImageAnalysis.Analyzer {

    // 設置只識別二維碼(避免誤認條形碼)
    privateval options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
        .build()

    privateval scanner = BarcodeScanning.getClient(options)  // 創建識別器實例

    @SuppressLint("UnsafeExperimentalUsageError")
    overridefun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        mediaImage?.let { 
            // 將相機畫面轉為可識別格式
            val image = InputImage.fromMediaImage(it, imageProxy.imageInfo.rotationDegrees)
            scanImage(image, imageProxy)  // 開始掃描!
        }
    }

    privatefun scanImage(image: InputImage, imageProxy: ImageProxy) {
        scanner.process(image)
            .addOnSuccessListener { codes -> 
                onDetect(codes)  // 成功抓到所有二維碼!
            }
            .addOnCompleteListener { 
                imageProxy.close()  // 關閉當前幀,準備下一幀
            }
    }
}

?? 這段代碼就像訓練了一只"二維碼獵犬":

analyze()負責轉換相機畫面格式

scanImage()釋放獵犬識別二維碼

? 識別完成后自動重置準備下次狩獵

啟動魔法:把一切組裝起來

class MainActivity : AppCompatActivity() {
    private val cameraExecutor = Executors.newSingleThreadExecutor()  // 專用工作線程
    private val viewFinder by lazy { findViewById<PreviewView>(R.id.viewFinder) }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()
            
            // 創建預覽畫面
            val preview = Preview.Builder().build().apply {
                setSurfaceProvider(viewFinder.surfaceProvider)
            }

            // 創建二維碼識別管道
            val qrAnalyzer = ImageAnalysis.Builder().build().apply {
                setAnalyzer(cameraExecutor, QRCodeAnalyzer { codes ->
                    // 識別結果回調區 ▼
                    codes.forEachIndexed { index, code ->
                        Log.d("QR_DEBUG", "抓到二維碼 ${index + 1}: ${code.rawValue}")
                    }
                })
            }

            try {
                // 組裝所有部件!啟動!
                cameraProvider.unbindAll()
                cameraProvider.bindToLifecycle(
                    this, 
                    CameraSelector.DEFAULT_BACK_CAMERA,  // 使用后置攝像頭
                    preview,
                    qrAnalyzer
                )
            } catch (e: Exception) {
                Log.e("CAMERA", "啟動失敗", e)
            }
        }, ContextCompat.getMainExecutor(this))
    }
}

啟動流程四步走:

? 獲取相機控制權

? 設置預覽窗口

? 連接二維碼識別器

? 啟動整個系統!

圖片圖片

圖片圖片


讓掃描結果躍然屏上

想要把掃描到的二維碼信息實時展示出來?小菜一碟!

<!-- 結果展示層 -->
<LinearLayout
    android:id="@+id/resultsContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="vertical"
    android:background="#80000000"
    android:padding="16dp">
        
    <TextView
        android:id="@+id/tvHeader"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="掃描結果"
        android:textColor="#4CAF50"
        android:textSize="18sp"
        android:textStyle="bold"/>
        
    <LinearLayout
        android:id="@+id/resultsLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginTop="8dp"/>
</LinearLayout>

設計思路:動態添加識別到的每個二維碼信息

在MainActivity中添加處理邏輯:

// 獲取布局元素引用
private val resultsLayout by lazy { findViewById<LinearLayout>(R.id.resultsLayout) }
private val resultsContainer by lazy { findViewById<LinearLayout>(R.id.resultsContainer) }
    
// 顯示掃描結果的核心方法
private fun showScanResults(codes: List<Barcode>) {
    // 清空之前的結果
    resultsLayout.removeAllViews()
        
    if (codes.isEmpty()) {
        // 沒有掃描到結果時顯示提示
        val emptyView = TextView(this).apply {
            text = "???♀? 正在尋找二維碼..."
            setTextColor(Color.WHITE)
        }
        resultsLayout.addView(emptyView)
        return
    }

    // 動態添加每個二維碼結果
    codes.forEachIndexed { index, barcode ->
        val resultView = createResultView(barcode, index)
        resultsLayout.addView(resultView)
    }
}

// 創建單個結果視圖
private fun createResultView(barcode: Barcode, index: Int): TextView {
    return TextView(this).apply {
        // 解析二維碼內容
        val content = barcode.rawValue ?: "未知內容"
            
        // 格式化顯示文本
        text = "? 二維碼 ${index + 1}:\n${content.take(50)}${if (content.length > 50) "..." else ""}"
        setTextColor(Color.WHITE)
        setTypeface(null, Typeface.BOLD)
        textSize = 14f
            
        // 添加點擊事件查看完整內容
        setOnClickListener {
            AlertDialog.Builder(this@MainActivity)
                .setTitle("二維碼詳情")
                .setMessage(content)
                .setPositiveButton("復制") { _, _ ->
                    copyToClipboard(content)
                    Toast.makeText(this@MainActivity, "已復制到剪貼板", Toast.LENGTH_SHORT).show()
                }
                .setNegativeButton("關閉", null)
                .show()
        }
    }
}
    
// 復制到剪貼板工具方法
private fun copyToClipboard(text: String) {
    val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    val clip = ClipData.newPlainText("二維碼內容", text)
    clipboard.setPrimaryClip(clip)
}

圖片圖片

超實用小技巧

性能優化:在ImageAnalysis.Builder()后加上.setBackpressureStrategy(STRATEGY_KEEP_ONLY_LATEST)避免卡頓

多類型支持:修改.setBarcodeFormats()可同時識別條形碼/二維碼

聚焦區域:添加viewFinder.setOnTouchListener實現點擊聚焦

// 添加點擊聚焦功能
viewFinder.setOnTouchListener { _, event ->
    if (event.action == MotionEvent.ACTION_DOWN) {
        val factory = viewFinder.meteringPointFactory
        val point = factory.createPoint(event.x, event.y)
        CameraControl?.startFocusAndMetering(FocusMeteringAction.Builder(point).build())
    }
    true
}

CameraX搭舞臺,ML Kit來識別,異步處理不卡頓,多碼掃描So Easy!

現在你的APP已經擁有"火眼金睛"啦!快去試試同時掃描一排二維碼的爽快感吧~

源碼https://github.com/Reathin/Sample-Android/tree/master/module_mlkit_barcode_scanning

責任編輯:武曉燕 來源: 沐雨花飛碟
相關推薦

2023-12-25 14:53:36

2022-03-24 09:43:29

二維碼二維碼修改器github

2023-08-08 14:16:07

二維碼開發鴻蒙

2024-06-26 08:46:45

2013-12-03 10:32:52

2013-01-30 12:16:49

二維碼NFC近場通訊

2013-11-26 09:54:02

2024-03-07 07:59:37

2013-03-27 16:13:17

Android開發Android二維碼生QR生成

2018-03-05 18:39:25

2023-11-17 15:44:06

C++庫生成二維碼

2021-09-08 10:02:56

面試二維碼前端

2023-05-09 20:41:00

網絡詐騙網絡安全

2023-11-17 09:07:51

.NET生成二維碼識別二維碼

2012-04-01 09:53:13

二維碼

2017-02-21 09:17:46

二維碼漏洞

2011-12-06 16:40:45

二維碼快拍二維碼靈動快拍

2013-11-19 16:06:39

2011-11-24 16:00:23

信息圖QR碼二維碼

2013-01-30 12:12:20

微信二維碼智能手機
點贊
收藏

51CTO技術棧公眾號

日韩久久一区二区| 日韩精品在线播放| 日韩欧美黄色大片| 日本韩国欧美国产| 毛片在线导航| 97视频免费看| 免费在线看一区| 国产天堂在线观看| 国产午夜精品全部视频播放| 日韩美女国产精品| 亚洲一区二区三区免费看| 一区二区三区四区视频精品免费| a天堂中文在线| 久久久这里只有精品视频| 国产九九精品| 成人午夜影院| 一本一本久久a久久精品综合小说 一本一本久久a久久精品牛牛影视 | 免费黄色福利视频| 91精品久久久久久蜜臀| 在线一级成人| 九色自拍视频在线观看| 亚洲福利影片在线| 你懂的视频一区二区| metart日本精品嫩模| 在线看日韩欧美| 性欧美长视频| 国产三区视频在线观看| 国产精品一区二区三区不卡 | 九色91在线视频| 成人免费小视频| 日本欧美在线| 国产高清av在线播放| 亚洲激情视频在线播放| 久久99国产精品成人| 中文在线手机av| 日本亚洲欧洲精品| 欧美一区二区黄色| 国产精品亚洲午夜一区二区三区| xxxx成人| 人人妻人人添人人爽欧美一区| 国产亚洲欧美另类中文| 国产麻豆精品视频| 亚洲欧洲专区| 天天爽夜夜爽一区二区三区| 欧美激情国产高清| 中文字幕制服丝袜成人av| 天美av一区二区三区久久| av在线无限看| 91美女片黄在线观看游戏| 欧美午夜精品一区二区三区| 久久国产精品第一页| 亚洲色图图片| 婷婷六月激情| 日韩高清dvd| 日韩视频一区在线| 亚洲一区欧美一区| 日本欧美一区二区三区乱码| 78精品国产综合久久香蕉| 国产在线黄色片| 欧美资源一区| 5566日本婷婷色中文字幕97| 欧美在线一区二区三区| 国产69精品久久久久777| 亚洲都市激情| 成年人黄视频在线观看| 亚洲人成电影| 一级片在线观看| 亚洲成人影院少妇| 福利视频网站| wwww.国产| 一区二区三区 日韩| 欧美激情精品久久久久久小说| 丰满少妇大力进入| 久久国产精品免费观看| 水蜜桃一区二区| 亚洲人一区二区| 国产人妻人伦精品| 天堂8在线天堂资源bt| 国产精品自拍合集| 中文字幕一区二区三区精彩视频| 日本国产一区二区三区| 亚洲另类激情图| 欧美一区二区视频在线观看 | 亚洲欧美久久久久一区二区三区| 97国产精品视频| 亚洲第一av在线| 91福利社在线观看| 亚洲精品一二三区| 国产偷国产偷亚洲高清人白洁| 精品一区二区免费视频| 亚洲美女毛片| 欧美视频亚洲视频| 四虎成人精品永久免费av九九| 成人黄色理论片| 国产精品久久亚洲不卡| av免费在线观看网址| av在线免费观看网| 五月天亚洲视频| 成人网址大全| 在线观看视频网站你懂得| 日韩欧美小视频| 日韩电影av| 国产精品视频一区视频二区| 88xx成人网| 国产成人精品福利| 日韩成人精品一区二区| 欧美一区二区三区久久精品| 国产精品久久777777毛茸茸| 久久亚洲美女| av电影一区二区| 欧美日韩国产精品专区 | 伊人精品一区| 午夜日韩激情| 国产精品综合av一区二区国产馆| 久久久美女毛片| 欧美午夜精品一区二区三区| 亚洲精品中文字幕有码专区| 欧美日韩国产成人| 成人动漫网站在线观看| 欧美在线一区二区三区四区| 视色,视色影院,视色影库,视色网| 伊人影院综合在线| 成人福利在线| 日韩啪啪网站| 日本一区影院| 九九视频免费观看视频精品| 欧美精品一区二区三区精品| 视频一区日韩| 婷婷久久综合九色综合99蜜桃| 日韩国产在线不卡视频| 欧美经典一区| 快播电影网址老女人久久| gogo在线高清视频| av香蕉成人| 麻豆视频在线免费观看| 免费在线国产| 成人免费在线观看视频网站| 欧美日韩亚洲第一| 黄色网址视频在线观看| 给我免费播放片在线观看| 成人免费观看cn| 香蕉视频在线免费看| 狠狠操综合网| 国产三级精品三级| 日韩精品在线免费观看| 欧美一区二区视频17c| 免费观看在线黄色网| 日韩1区2区| 91九色最新地址| 午夜精品一区二区在线观看 | 羞羞视频在线观看| 在线中文字幕第一页| 亚洲一区二区三区在线免费| 老司机精品福利视频| 狠狠躁天天躁日日躁欧美| 国产亚洲欧美aaaa| 91最新在线免费观看| 怡红院av亚洲一区二区三区h| 色多多视频在线观看| 色综合.com| 免费欧美在线视频| 色偷偷综合社区| 99在线欧洲视频| 国产精品巨作av| 国产精品羞羞答答xxdd| 久久se精品一区精品二区| 99久久99精品久久久久久| 国产一区二区日韩精品| 国产亚洲综合av| 日韩精品中文字幕一区二区三区| 国产一区二区三区奇米久涩| 亚洲色欲久久久综合网东京热| av免费看大片| 深夜视频在线免费| 国产福利电影在线| 国产精品久久麻豆| 成人在线免费av| 国产日产一区| 在线成人www免费观看视频| 免费成人美女在线观看.| 欧美日韩精品二区第二页| 中文字幕色一区二区| 147欧美人体大胆444| 青青青青草视频| 国产成人tv| 亚洲狼人国产精品| 国产一区二区不卡视频| 黄视频网站在线观看| 亚洲激情图片一区| 久久伊人资源站| 日本亚州欧洲精品不卡| 一区二区三区久久| 欧美日韩一区综合| 午夜激情电影在线播放| 成人动漫在线一区| www.欧美三级电影.com| 日本久久久精品视频| 欧美aaaaa级| 欧美日韩一卡二卡三卡| 国产精品久久久久久久天堂第1集|