求助:零基础开发Android条码扫描并即时存入SQL数据库的APP
嘿,完全理解你的处境——从零碰Android开发,还找不到精准的教程,确实头大。不过你的需求其实很典型,我把整个流程拆成超级易懂的步骤,跟着走就能搞定!
第一步:搞定开发环境
首先下载安装最新版的Android Studio,安装过程中默认选Android SDK就行(不用纠结太多选项,新手默认配置足够)。打开后创建一个Empty Activity项目,语言选Kotlin(比Java简洁,入门更快),项目名随便取,比如BarcodeScannerDB。
第二步:集成扫码功能(不用自己写!)
咱们直接用成熟的扫码库zxing-android-embedded,省得自己造轮子。
打开模块级的
build.gradle(注意是Module: app那个文件),在dependencies里加一行:implementation 'com.journeyapps:zxing-android-embedded:4.3.0' implementation 'com.google.zxing:core:3.4.1'然后点击Sync Now同步依赖。
给你的主Activity加一个扫码按钮和显示结果的文本框,布局文件
activity_main.xml大概这样:<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/scanBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="扫描条码"/> <TextView android:id="@+id/resultTv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:textSize="18sp"/> </LinearLayout>处理扫码逻辑:在
MainActivity.kt里,先申请相机权限(Android 6.0以上必须动态申请),然后点击按钮启动扫码界面:import android.Manifest import android.content.Intent import android.content.pm.PackageManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextView import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions class MainActivity : AppCompatActivity() { private lateinit var resultTv: TextView // 扫码契约(新版ZXing推荐用这个,替代旧的onActivityResult) private val barcodeLauncher = registerForActivityResult(ScanContract()) { result -> if (result.contents != null) { val barcodeContent = result.contents resultTv.text = "扫描结果:$barcodeContent" // 这里后面会加存数据库的代码 } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) resultTv = findViewById(R.id.resultTv) val scanBtn = findViewById<Button>(R.id.scanBtn) scanBtn.setOnClickListener { // 先检查相机权限 if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED ) { // 申请权限 ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.CAMERA), 100 ) } else { // 权限已通过,启动扫码 startScan() } } } // 处理权限申请结果 override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode == 100 && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { startScan() } } // 启动扫码界面的方法 private fun startScan() { val options = ScanOptions() options.setPrompt("对准条码进行扫描") options.setBeepEnabled(true) // 扫码成功响铃 barcodeLauncher.launch(options) } }现在运行APP,点击按钮就能扫码并显示结果了!
第三步:集成本地SQL数据库(用Room,比原生SQLite简单10倍)
Android官方推荐用Room Persistence Library,封装了SQLite,不用写复杂的SQL语句。
先加Room的依赖,还是在模块级
build.gradle的dependencies里:// Room implementation "androidx.room:room-runtime:2.5.2" kapt "androidx.room:room-compiler:2.5.2" // 如果用Kotlin协程的话,再加这个(推荐,避免主线程操作数据库) implementation "androidx.room:room-ktx:2.5.2"注意顶部要加kapt插件:在
plugins块里加id 'kotlin-kapt',然后Sync Now。定义数据库实体(对应数据库的表):新建一个
BarcodeData.kt文件:import androidx.room.Entity import androidx.room.PrimaryKey @Entity(tableName = "barcode_table") data class BarcodeData( @PrimaryKey(autoGenerate = true) val id: Int = 0, val content: String, // 条码内容 val timestamp: Long // 扫描时间戳 )定义Dao(数据访问对象,用来操作数据库):新建
BarcodeDao.kt:import androidx.room.Dao import androidx.room.Insert import androidx.room.Query @Dao interface BarcodeDao { // 插入一条条码数据 @Insert suspend fun insertBarcode(barcode: BarcodeData) // 可选:查询所有条码数据,方便测试 @Query("SELECT * FROM barcode_table ORDER BY timestamp DESC") suspend fun getAllBarcodes(): List<BarcodeData> }创建数据库类:新建
AppDatabase.kt:import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import android.content.Context @Database(entities = [BarcodeData::class], version = 1) abstract class AppDatabase : RoomDatabase() { abstract fun barcodeDao(): BarcodeDao // 单例模式,避免重复创建数据库实例 companion object { @Volatile private var INSTANCE: AppDatabase? = null fun getInstance(context: Context): AppDatabase { return INSTANCE ?: synchronized(this) { val instance = Room.databaseBuilder( context.applicationContext, AppDatabase::class.java, "barcode_database" ).build() INSTANCE = instance instance } } } }把扫码结果存入数据库:回到
MainActivity.kt,修改扫码成功后的逻辑,用协程操作数据库(避免主线程阻塞):
首先加协程依赖(如果之前没加的话):implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"然后修改
barcodeLauncher的代码:private val barcodeLauncher = registerForActivityResult(ScanContract()) { result -> if (result.contents != null) { val barcodeContent = result.contents resultTv.text = "扫描结果:$barcodeContent" // 存数据库 val barcodeData = BarcodeData(content = barcodeContent, timestamp = System.currentTimeMillis()) // 用协程在后台执行 lifecycleScope.launch { val dao = AppDatabase.getInstance(this@MainActivity).barcodeDao() dao.insertBarcode(barcodeData) // 可选:提示用户已保存 runOnUiThread { resultTv.text = "扫描结果:$barcodeContent\n已保存到数据库" } } } }
第四步:测试验证
现在运行APP,扫描几个条码,然后可以加个按钮来查询所有数据(可选),比如在布局里加个按钮:
<Button android:id="@+id/viewBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:text="查看已存条码"/>
然后在MainActivity.kt里加点击事件:
val viewBtn = findViewById<Button>(R.id.viewBtn) viewBtn.setOnClickListener { lifecycleScope.launch { val dao = AppDatabase.getInstance(this@MainActivity).barcodeDao() val allBarcodes = dao.getAllBarcodes() // 在UI线程显示结果 runOnUiThread { val sb = StringBuilder() allBarcodes.forEach { sb.append("ID: ${it.id}, 内容: ${it.content}, 时间: ${it.timestamp}\n") } resultTv.text = sb.toString() } } }
新手必看提示
- 一定要用真机测试,模拟器的相机可能不好用,甚至没有相机;
- 遇到报错先看Android Studio底部的Logcat,红色的错误信息里会告诉你哪里出问题了;
- 不用追求完美,先让扫码和存数据跑通,再慢慢优化界面和功能;
- Room的版本如果有更新,可以换成最新的,只要保持runtime和compiler版本一致就行。
内容的提问来源于stack exchange,提问作者Tolga20

