Camera freezes after scanning QR code with Zxing library - android

I implemented QR code scanner with result handler. It is scanning well. But, after first scanning is complete I show a popup. When I close the popup, camera gets stuck.
I tried using resume camera but it doesn't work.
Here is some of my code
private fun startCamera() {
binding.scanner.setResultHandler(this)
binding.scanner.setAspectTolerance(0.5f)
binding.scanner.startCamera()
binding.scanner.resumeCameraPreview(this)
}
override fun onResume() {
super.onResume()
mScannerView?.setResultHandler(this)
}
override fun onStart() {
super.onStart()
startCamera()
}
override fun handleResult(rawResult: Result?) {
val result = rawResult?.text ?: return
liveMasterclass?.id?.let {
viewModel.getAttendance(it, result)
mScannerView?.resumeCameraPreview(this)
}
}

Related

Is there a way to continously record audio in background with a service on Android with Kotlin?

Im building an app that translate audio in background on live. I display a overlay over apps and i want to record the audio to translate in real time. But in android 13 the audio recording stops after a few secods recording.
I guess that the problem is for the security of the user, but im looking for a second opinion
Im using the SpeechRecognizer library. But I receive recommendations
Added a piece of code
AndroidManifiest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<service
android:name=".feature.overlay.OverlayService"
android:exported="false"
android:foregroundServiceType="microphone"/>
OverlayService
override fun onCreate() {
super.onCreate()
windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
configureSpeechToText()
windowManager.addView(layoutText,params)
}
fun configureSpeechToText() {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this)
speechRecognizerIntent.putExtra(
RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM
)
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault())
speechRecognizer?.setRecognitionListener(object : RecognitionListener {
override fun onReadyForSpeech(bundle: Bundle) {}
override fun onBeginningOfSpeech() {}
override fun onRmsChanged(v: Float) {}
override fun onBufferReceived(bytes: ByteArray) {}
override fun onEndOfSpeech() {}
override fun onError(i: Int) {
val errorMessage = getErrorText(i)
Log.d("Error", "FAILED: $errorMessage")
}
override fun onResults(bundle: Bundle) {
val data = bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
dataVoiceText = data!![0]
run(dataVoiceText)//The function that translate the text
}
override fun onPartialResults(bundle: Bundle) {}
override fun onEvent(i: Int, bundle: Bundle) {}
})
handler.postDelayed(Runnable {//Run this code every few seconds to translate every few seconds
handler.postDelayed(runnable!!, delay.toLong())
speechRecognizer?.stopListening()
speechRecognizer?.startListening(speechRecognizerIntent)
}.also { runnable = it }, delay.toLong())
}
Im trying to record audio in background with a service, im expecting to it continously record the audio. but right now it is stoping

How to launch implicit intent from a QR Code result?

I have built a QR scanning application (written in Kotlin, for Android). It scans for a QR code and then returns the URL after its scanned like so.
However, I wish to take it a step further and actually launch the return value of the QR code into a search engine of an internet application and have it display the results of what the QR code had intended. How would I get the application to get the returned URL and redirect the user to the intended place?
Here is my MainActivity.kt for reference:
class MainActivity : AppCompatActivity() {
private lateinit var codeScanner: CodeScanner
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val scannerView = findViewById<CodeScannerView>(R.id.scanner_view)
codeScanner = CodeScanner(this, scannerView)
codeScanner.camera = CodeScanner.CAMERA_BACK
codeScanner.formats = CodeScanner.ALL_FORMATS
codeScanner.autoFocusMode = AutoFocusMode.SAFE
codeScanner.scanMode = ScanMode.SINGLE
codeScanner.isAutoFocusEnabled = true
codeScanner.isFlashEnabled = false
codeScanner.decodeCallback = DecodeCallback {
runOnUiThread {
Toast.makeText(this, "Scan result: ${it.text}", Toast.LENGTH_LONG).show()}
}
scannerView.setOnClickListener {
codeScanner.startPreview()
}
}
override fun onResume() {
super.onResume()
codeScanner.startPreview()
}
override fun onPause() {
codeScanner.releaseResources()
super.onPause()
}
}
I used this answer to build a searchWeb function within my MainActivity.kt class like so;
fun searchWeb(query: String) {
val url = "http://www.google.com"
val intent = Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url))
startActivity(intent)
}
I then called the function within my codeScanner.decodeCallback like so;
codeScanner.decodeCallback = DecodeCallback {
runOnUiThread {
Toast.makeText(this, "Scan result: ${it.text}", Toast.LENGTH_LONG).show()
}
searchWeb(it.text)
}
After doing this, the implicit intent was launched and the QR application launched the internet browser.

How to detect fragment is idle for some time in android

I want to check that no one has interacted with fragment UI for some time and on the bases of that I want to call a Function/Method inside fragment. Android Studio
You could use a Handler for this and call resetTimeout() when the user does something:
val timeoutHandler = Handler(Looper.getMainLooper()) {
onTimeout()
true
}
fun clearTimeout() = timeoutHandler.removeMessages(0)
fun resetTimeout() =
clearTimeout().also {
timeoutHandler.sendEmptyMessageDelayed(0, TIMEOUT_IN_MILLIS)
}
override fun onResume() {
super.onResume()
resetTimeout()
}
override fun onPause() {
super.onPause()
clearTimeout()
}
private fun onTimeout() {
//we have timed out
}

Stop mobile vision api after first detection

I'm trying to detect a QR code with the google mobile vision api.
The problem is that after detecting a QR code, the api calls continiously the "receiveDetections" function as long as the QR code is visible to the camera.
I need to stop after the first detection and send the result to my server to validate this code.
How can I stop the process after the first detection?
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.qrcode_scanner)
detector = BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build()
detector.setProcessor(object: Detector.Processor<Barcode> {
override fun release() {
override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
val barcodes = detections?.detectedItems
if(barcodes!!.size()>0) {
Log.e("qrcode",barcodes.valueAt(0).displayValue)
sendQRCodeToServer(url,barcodes.valueAt(0).displayValue)
}
}
})
cameraSource = CameraSource.Builder(this,detector).setRequestedPreviewSize(1920,1080).setRequestedFps(25f).setAutoFocusEnabled(true).build()
svBarcode.holder.addCallback(object: SurfaceHolder.Callback2 {
override fun surfaceRedrawNeeded(holder: SurfaceHolder?) {
}
override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
}
override fun surfaceDestroyed(holder: SurfaceHolder?) {
cameraSource.stop()
}
override fun surfaceCreated(holder: SurfaceHolder?) {
if(ContextCompat.checkSelfPermission(this#Scanner,
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
cameraSource.start(holder)
startAnimation()
} else ActivityCompat.requestPermissions(this#Scanner, arrayOf(Manifest.permission.CAMERA),123)
}
})
}
}
override fun onDestroy() {
super.onDestroy()
detector.release()
cameraSource.stop()
cameraSource.release()
}
you can create function to stop camera,ex
private fun stopCamera(){
cameraSource.stop()
}
detector = BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build()
detector.setProcessor(object: Detector.Processor<Barcode> {
override fun release() {
override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
val barcodes = detections?.detectedItems
if(barcodes!!.size()>0) {
Log.e("qrcode",barcodes.valueAt(0).displayValue)
sendQRCodeToServer(url,barcodes.valueAt(0).displayValue)
//add this to stop camera
stopCamera()
}
}
})
edit:
create variable for flag detection at first like
//to flag first detection
private var firstDetection=true
override fun onCreate(savedInstanceState: Bundle?) {
///.......
detector = BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS).build()
detector.setProcessor(object: Detector.Processor<Barcode> {
override fun release() {
}
override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
val barcodes = detections?.detectedItems
//check firstDetection
if(barcodes!!.size()>0 && firstDetection) {
sendQRCodeToServer(url,barcodes.valueAt(0).displayValue)
//set firstDetection
firstDetection=false
}
}
})
}
}
hope this help....

Android not opening camera using zxing

I'm trying to make the basic ZXing functionality to scan qr codes using their basic instructions, but my camera does not open it just goes to the blank ScanActivity.
I've already added the "implementation" on module app dependency
implementation 'me.dm7.barcodescanner:zxing:1.9'
and permission on AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>
I've also manually allowed its permission on the settings of the android phone i'm testing it on
My main activity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tvResult = tvresult
btn.setOnClickListener {
val intent = Intent(this#MainActivity, ScanActivity::class.java)
startActivity(intent)
}
}
companion object {
var tvResult: TextView? = null
}
}
ScanActivity Class
class ScanActivity : AppCompatActivity(), ZXingScannerView.ResultHandler {
private var mScannerView: ZXingScannerView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mScannerView = ZXingScannerView(this)
setContentView(R.layout.activity_scan)
mScannerView!!.setResultHandler(this) // Register ourselves as a handler for scan results.
}
public override fun onResume() {
super.onResume()
mScannerView!!.setResultHandler(this) // Register ourselves as a handler for scan results.
mScannerView!!.startCamera() // Start camera on resume
}
public override fun onPause() {
super.onPause()
mScannerView!!.stopCamera() // Stop camera on pause
}
override fun handleResult(rawResult: Result) {
// Do something with the result here
// Log.v("tag", rawResult.getText()); // Prints scan results
// Log.v("tag", rawResult.getBarcodeFormat().toString()); // Prints the scan format (qrcode, pdf417 etc.)
MainActivity.tvResult!!.setText(rawResult.text)
onBackPressed()
// If you would like to resume scanning, call this method below:
//mScannerView.resumeCameraPreview(this);
}}
after i click on the Scan barcode button it just goes to this
(im expecting the camera will open because of the startCamera()
I had a similar issue, it was permission related.
Try adding the following within the onCreate(..)
if (ContextCompat.checkSelfPermission(this#MainActivity, Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this#MainActivity, arrayOf(Manifest.permission.CAMERA), 123)
}
Late answer, by the way if someone else has this problem, you forgot to add mScannerView in your Layout

Categories

Resources