kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
commit
747ce82a7b
|
@ -173,9 +173,10 @@ dependencies {
|
|||
|
||||
// location services
|
||||
implementation 'com.google.android.gms:play-services-location:19.0.1'
|
||||
|
||||
// For Google Sign-In (owner name accesss)
|
||||
implementation 'com.google.android.gms:play-services-auth:20.1.0'
|
||||
// ML Kit barcode scanning
|
||||
implementation 'com.google.android.gms:play-services-code-scanner:16.0.0-beta1'
|
||||
|
||||
// Add the Firebase SDK for Crashlytics.
|
||||
implementation 'com.google.firebase:firebase-crashlytics:18.2.6'
|
||||
|
|
|
@ -97,6 +97,9 @@
|
|||
<meta-data
|
||||
android:name="firebase_analytics_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="com.google.mlkit.vision.DEPENDENCIES"
|
||||
android:value="barcode_ui"/>
|
||||
|
||||
<!-- we need bind job service for oreo -->
|
||||
<service
|
||||
|
|
|
@ -518,8 +518,7 @@ class MainActivity : BaseActivity(), Logging,
|
|||
requestedChannelUrl = appLinkData
|
||||
|
||||
// if the device is connected already, process it now
|
||||
if (model.isConnected())
|
||||
perhapsChangeChannel()
|
||||
perhapsChangeChannel()
|
||||
|
||||
// We now wait for the device to connect, once connected, we ask the user if they want to switch to the new channel
|
||||
}
|
||||
|
@ -721,16 +720,16 @@ class MainActivity : BaseActivity(), Logging,
|
|||
}
|
||||
}
|
||||
|
||||
fun perhapsChangeChannel(url: Uri? = requestedChannelUrl) {
|
||||
// If the is opening a channel URL, handle it now
|
||||
if (url != null) {
|
||||
private fun perhapsChangeChannel(url: Uri? = requestedChannelUrl) {
|
||||
// if the device is connected already, process it now
|
||||
if (url != null && model.isConnected()) {
|
||||
requestedChannelUrl = null
|
||||
try {
|
||||
val channels = ChannelSet(url)
|
||||
val primary = channels.primaryChannel
|
||||
if (primary == null)
|
||||
showSnackbar(R.string.channel_invalid)
|
||||
else {
|
||||
requestedChannelUrl = null
|
||||
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.new_channel_rcvd)
|
||||
|
@ -967,6 +966,15 @@ class MainActivity : BaseActivity(), Logging,
|
|||
}
|
||||
}
|
||||
|
||||
// Call perhapsChangeChannel() whenever [changeChannelUrl] updates with a non-null value
|
||||
model.requestChannelUrl.observe(this) { url ->
|
||||
url?.let {
|
||||
requestedChannelUrl = url
|
||||
model.clearRequestChannelUrl()
|
||||
perhapsChangeChannel()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
bindMeshService()
|
||||
} catch (ex: BindFailedException) {
|
||||
|
|
|
@ -107,6 +107,20 @@ class UIViewModel @Inject constructor(
|
|||
private val _channels = MutableLiveData<ChannelSet?>()
|
||||
val channels: LiveData<ChannelSet?> get() = _channels
|
||||
|
||||
private val _requestChannelUrl = MutableLiveData<Uri?>(null)
|
||||
val requestChannelUrl: LiveData<Uri?> get() = _requestChannelUrl
|
||||
|
||||
fun setRequestChannelUrl(channelUrl: Uri) {
|
||||
_requestChannelUrl.value = channelUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* Called immediately after activity observes requestChannelUrl
|
||||
*/
|
||||
fun clearRequestChannelUrl() {
|
||||
_requestChannelUrl.value = null
|
||||
}
|
||||
|
||||
var positionBroadcastSecs: Int?
|
||||
get() {
|
||||
_radioConfig.value?.preferences?.let {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.geeksville.mesh.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.graphics.ColorMatrix
|
||||
|
@ -13,15 +14,15 @@ import android.view.ViewGroup
|
|||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.geeksville.analytics.DataPair
|
||||
import com.geeksville.android.GeeksvilleApplication
|
||||
import com.geeksville.android.Logging
|
||||
import com.geeksville.android.hideKeyboard
|
||||
import com.geeksville.android.isGooglePlayAvailable
|
||||
import com.geeksville.mesh.AppOnlyProtos
|
||||
import com.geeksville.mesh.ChannelProtos
|
||||
import com.geeksville.mesh.MainActivity
|
||||
import com.geeksville.mesh.R
|
||||
import com.geeksville.mesh.android.hasCameraPermission
|
||||
import com.geeksville.mesh.databinding.ChannelFragmentBinding
|
||||
|
@ -31,9 +32,11 @@ import com.geeksville.mesh.model.ChannelSet
|
|||
import com.geeksville.mesh.model.UIViewModel
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.mlkit.vision.barcode.common.Barcode
|
||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScannerOptions
|
||||
import com.google.mlkit.vision.codescanner.GmsBarcodeScanning
|
||||
import com.google.protobuf.ByteString
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanIntentResult
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import java.security.SecureRandom
|
||||
|
@ -189,6 +192,52 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
}
|
||||
}
|
||||
|
||||
private fun zxingScan() {
|
||||
debug("Starting zxing QR code scanner")
|
||||
val zxingScan = ScanOptions()
|
||||
zxingScan.setCameraId(0)
|
||||
zxingScan.setPrompt("")
|
||||
zxingScan.setBeepEnabled(false)
|
||||
zxingScan.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
|
||||
barcodeLauncher.launch(zxingScan)
|
||||
}
|
||||
|
||||
private fun requestPermissionAndScan() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.camera_required)
|
||||
.setMessage(R.string.why_camera_required)
|
||||
.setNeutralButton(R.string.cancel) { _, _ ->
|
||||
debug("Camera permission denied")
|
||||
}
|
||||
.setPositiveButton(getString(R.string.accept)) { _, _ ->
|
||||
requestPermissionAndScanLauncher.launch(Manifest.permission.CAMERA)
|
||||
}
|
||||
.show()
|
||||
}
|
||||
|
||||
|
||||
private fun mlkitScan() {
|
||||
debug("Starting ML Kit QR code scanner")
|
||||
val options = GmsBarcodeScannerOptions.Builder()
|
||||
.setBarcodeFormats(
|
||||
Barcode.FORMAT_QR_CODE
|
||||
)
|
||||
.build()
|
||||
val scanner = GmsBarcodeScanning.getClient(requireContext(), options)
|
||||
scanner.startScan()
|
||||
.addOnSuccessListener { barcode ->
|
||||
if (barcode.rawValue != null)
|
||||
model.setRequestChannelUrl(Uri.parse(barcode.rawValue))
|
||||
}
|
||||
.addOnFailureListener {
|
||||
Snackbar.make(
|
||||
requireView(),
|
||||
R.string.channel_invalid,
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
@ -212,25 +261,14 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
}
|
||||
|
||||
binding.scanButton.setOnClickListener {
|
||||
if ((requireActivity() as MainActivity).hasCameraPermission()) {
|
||||
debug("Starting QR code scanner")
|
||||
val zxingScan = ScanOptions()
|
||||
zxingScan.setCameraId(0)
|
||||
zxingScan.setPrompt("")
|
||||
zxingScan.setBeepEnabled(false)
|
||||
zxingScan.setDesiredBarcodeFormats(ScanOptions.QR_CODE)
|
||||
barcodeLauncher.launch(zxingScan)
|
||||
if (isGooglePlayAvailable(requireContext())) {
|
||||
mlkitScan()
|
||||
} else {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.camera_required)
|
||||
.setMessage(R.string.why_camera_required)
|
||||
.setNeutralButton(R.string.cancel) { _, _ ->
|
||||
debug("Camera permission denied")
|
||||
}
|
||||
.setPositiveButton(getString(R.string.accept)) { _, _ ->
|
||||
(requireActivity() as MainActivity).requestCameraPermission()
|
||||
}
|
||||
.show()
|
||||
if (requireContext().hasCameraPermission()) {
|
||||
zxingScan()
|
||||
} else {
|
||||
requestPermissionAndScan()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,16 +353,18 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
|||
if (getString(item.configRes) == selectedChannelOptionString)
|
||||
return item.modemConfig
|
||||
}
|
||||
|
||||
return ChannelProtos.ChannelSettings.ModemConfig.UNRECOGNIZED
|
||||
}
|
||||
|
||||
// Register the launcher and result handler
|
||||
private val barcodeLauncher: ActivityResultLauncher<ScanOptions> = registerForActivityResult(
|
||||
ScanContract()
|
||||
) { result: ScanIntentResult ->
|
||||
private val requestPermissionAndScanLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.RequestPermission()) { allowed ->
|
||||
if (allowed) zxingScan()
|
||||
}
|
||||
|
||||
// Register zxing launcher and result handler
|
||||
private val barcodeLauncher = registerForActivityResult(ScanContract()) { result ->
|
||||
if (result.contents != null) {
|
||||
((requireActivity() as MainActivity).perhapsChangeChannel(Uri.parse(result.contents)))
|
||||
model.setRequestChannelUrl(Uri.parse(result.contents))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue