diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index bf2e855..3ee1c8e 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -129,8 +129,6 @@ dependencies {
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)
-
-
//lifecycle
implementation(libs.lifecycle.runtime.compose)
@@ -145,5 +143,6 @@ dependencies {
generalImplementation(libs.google.firebase.analytics.ktx)
//barcode scanning
- implementation(libs.play.services.code.scanner)
+ implementation(libs.zxing.android.embedded)
+ implementation(libs.zxing.core)
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d762f13..3d9332b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -58,6 +58,12 @@
+
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/barcode/QRScanner.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/barcode/QRScanner.kt
deleted file mode 100644
index dd502c7..0000000
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/barcode/QRScanner.kt
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.zaneschepke.wireguardautotunnel.service.barcode
-
-import com.google.mlkit.vision.codescanner.GmsBarcodeScanner
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.callbackFlow
-import timber.log.Timber
-import javax.inject.Inject
-
-class QRScanner @Inject constructor(private val gmsBarcodeScanner: GmsBarcodeScanner) : CodeScanner {
- override fun scan(): Flow {
- return callbackFlow {
- gmsBarcodeScanner.startScan().addOnSuccessListener {
- trySend(it.rawValue)
- }.addOnFailureListener {
- trySend(it.message)
- Timber.e(it.message)
- }
- awaitClose {
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/CaptureActivityPortrait.java b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/CaptureActivityPortrait.java
new file mode 100644
index 0000000..f9770eb
--- /dev/null
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/CaptureActivityPortrait.java
@@ -0,0 +1,6 @@
+package com.zaneschepke.wireguardautotunnel.ui;
+
+import com.journeyapps.barcodescanner.CaptureActivity;
+
+public class CaptureActivityPortrait extends CaptureActivity {
+}
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
index cbca1db..58a8ae4 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt
@@ -70,7 +70,10 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
+import com.journeyapps.barcodescanner.ScanContract
+import com.journeyapps.barcodescanner.ScanOptions
import com.wireguard.android.backend.Tunnel
+import com.zaneschepke.wireguardautotunnel.ui.CaptureActivityPortrait
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
@@ -141,6 +144,11 @@ fun MainScreen(
result.data?.data?.let { viewModel.onTunnelFileSelected(it) }
}
+ val scanLauncher = rememberLauncherForActivityResult(
+ contract = ScanContract(),
+ onResult = { result -> viewModel.onTunnelQrResult(result.contents) }
+ )
+
Scaffold(
modifier = Modifier.pointerInput(Unit) {
detectTapGestures(onTap = {
@@ -219,7 +227,13 @@ fun MainScreen(
.clickable {
scope.launch {
showBottomSheet = false
- viewModel.onTunnelQRSelected()
+ val scanOptions = ScanOptions()
+ scanOptions.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
+ scanOptions.setOrientationLocked(true)
+ scanOptions.setPrompt(context.getString(R.string.scanning_qr))
+ scanOptions.setBeepEnabled(false)
+ scanOptions.captureActivity = CaptureActivityPortrait().javaClass
+ scanLauncher.launch(scanOptions)
}
}
.padding(10.dp)
diff --git a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
index e82eba2..fa28c47 100644
--- a/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
+++ b/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt
@@ -13,14 +13,13 @@ import com.zaneschepke.wireguardautotunnel.Constants
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.repository.SettingsDoa
import com.zaneschepke.wireguardautotunnel.repository.TunnelConfigDao
-import com.zaneschepke.wireguardautotunnel.service.barcode.CodeScanner
-import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceState
+import com.zaneschepke.wireguardautotunnel.repository.model.Settings
+import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
+import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceState
import com.zaneschepke.wireguardautotunnel.service.foreground.WireGuardConnectivityWatcherService
import com.zaneschepke.wireguardautotunnel.service.shortcut.ShortcutsManager
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
-import com.zaneschepke.wireguardautotunnel.repository.model.Settings
-import com.zaneschepke.wireguardautotunnel.repository.model.TunnelConfig
import com.zaneschepke.wireguardautotunnel.ui.ViewState
import com.zaneschepke.wireguardautotunnel.util.NumberUtils
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -38,8 +37,7 @@ import javax.inject.Inject
class MainViewModel @Inject constructor(private val application : Application,
private val tunnelRepo : TunnelConfigDao,
private val settingsRepo : SettingsDoa,
- private val vpnService: VpnService,
- private val codeScanner: CodeScanner
+ private val vpnService: VpnService
) : ViewModel() {
private val _viewState = MutableStateFlow(ViewState())
@@ -96,13 +94,12 @@ class MainViewModel @Inject constructor(private val application : Application,
ServiceManager.stopVpnService(application.applicationContext)
}
- suspend fun onTunnelQRSelected() {
- codeScanner.scan().collect {
- if(!it.isNullOrEmpty() && it.contains(application.resources.getString(R.string.config_validation))) {
- val tunnelConfig = TunnelConfig(name = NumberUtils.generateRandomTunnelName(), wgQuick = it)
+ fun onTunnelQrResult(result : String) {
+ viewModelScope.launch(Dispatchers.IO) {
+ if(result.contains(application.resources.getString(R.string.config_validation))) {
+ val tunnelConfig =
+ TunnelConfig(name = NumberUtils.generateRandomTunnelName(), wgQuick = result)
saveTunnel(tunnelConfig)
- } else if(!it.isNullOrEmpty() && it.contains(application.resources.getString(R.string.barcode_downloading))) {
- showSnackBarMessage(application.resources.getString(R.string.barcode_downloading_message))
} else {
showSnackBarMessage(application.resources.getString(R.string.barcode_error))
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 8297e67..da5c9e0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -92,4 +92,5 @@
Attempting connection..
VPN Starting
wg-tunnel-db
+ Reading QR code
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 487e750..3d485f8 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -15,7 +15,6 @@ lifecycle-runtime-compose = "2.6.2"
material-icons-extended = "1.5.1"
material3 = "1.1.1"
navigationCompose = "2.7.2"
-playServicesCodeScanner = "16.1.0"
roomVersion = "2.6.0-beta01"
timber = "5.0.1"
tunnel = "1.0.20230706"
@@ -28,6 +27,8 @@ compose="1.5.1"
crashlytics="18.4.1"
analytics="21.3.0"
composeCompiler="1.5.3"
+zxingAndroidEmbedded = "4.3.0"
+zxingCore = "3.4.1"
[libraries]
@@ -69,7 +70,6 @@ junit = { module = "junit:junit", version.ref = "junit" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" }
lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle-runtime-compose" }
material-icons-extended = { module = "androidx.compose.material:material-icons-extended", version.ref = "material-icons-extended" }
-play-services-code-scanner = { module = "com.google.android.gms:play-services-code-scanner", version.ref = "playServicesCodeScanner" }
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
@@ -82,6 +82,9 @@ firebase-crashlytics-gradle = { module = "com.google.firebase:firebase-crashlyti
firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom"}
google-services = { module = "com.google.gms:google-services", version.ref = "google-services" }
+zxing-core = { module = "com.google.zxing:core", version.ref = "zxingCore" }
+zxing-android-embedded = { module = "com.journeyapps:zxing-android-embedded", version.ref = "zxingAndroidEmbedded" }
+
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }