I'm developing a QR code scanner with Mobile Vision API (play-services-vision 11.0.1). I've run my application on two Android devices (Xperia SO-04E Android 4.2.2). My application works correctly on one device but does not detect QR code on the other. Camera started correctly, but detected no QR code. Does anyone know a solution? Might does a device's configuration cause this?
A part of source code(Activity written in Kotlin) is as below. I've configured the camera permission in AndroidManifest.xml.
// instantiate barcode detector in an Activity onCreate method
val barcodeDetector = BarcodeDetector.Builder(this).build()
cameraSource = CameraSource.Builder(this, barcodeDetector)
.setAutoFocusEnabled(true)
.setRequestedPreviewSize(1600, 1024)
// set callback
barcodeDetector.setProcessor(object: Detector.Processor<Barcode>?) {
override fun release() {}
override fun receiveDetections(detections: Detector.Detections<Barcode>?) {
・・・
// parse a detected QR code
・・・
}
}
Check internet connection on the second device; As Vision API requires Google play services and this needs internet connection; however need not to provide permission in Manifest file..
Related
I am writing a sample application which is scanning for available wifis and connects to them programmatically
For that propose, I'm using WiFiManager, but recently Google deprecated most of the methods that are allowing to scan for WiFis and Connect to them programmatically. And yes it seems logical from Google's side to not allow anyone to try to connect to any WiFi programmatically.
But my questions will be following
Is there still a way to Scan for available WiFi-s
Is there a way to connect to a Public WiFi
Is there a way to connect to a Private WiFi programmatically, or if no if there is a way to suggest user connect to a private WiFi, so user can enter a password
In the new API I found a way how I can suggest user connect to the WiFi
wifiManager.addNetworkSuggestions(listOf(WifiNetworkSuggestion
.Builder()
.setSsid("testWiFi")
.setWpa2Passphrase("test1234")
.build()))
but this is working really unpredictable, the first time when I run my all and call this method, on Android Q it's showing a notification and on Android R it's showing dialog asking the user if he allows connecting to the WiFi-s when app somehow connects to the WiFi but after that calling the same function for another WiFis does nothing and app is not showing any more ant notification or dialog (it this a bug? )
also I tried requestNetwoerk method
val specifier = WifiNetworkSpecifier
.Builder()
.setSsid("testWiFi")
.setBssid(MacAddress.fromString("testWiFiMac"))
.build()
val request = NetworkRequest
.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build()
connectivityManager.requestNetwork(request, networkCallback)
but in this case, it's not very clear if it is possible to connect to password-protected WiFi, and if yes how to do that.
So if there are some examples or explanations, please let me know.
even if start scan is deprecated Google still recommends to use it.
The three steps here are:
Register a broadcast receiver for SCAN_RESULTS_AVAILABLE_ACTION.
Request a scan using WifiManager.startScan()
Get the scan results with WifiManager.getScanResults(). Note that if you are using these scan results before receiving the results from the broadcast, these results might be a bit older from previous scans.
Sample code might be look like this:
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val wifiScanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
if (success) {
scanSuccess()
} else {
scanFailure()
}
}
}
val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)
val success = wifiManager.startScan()
if (!success) {
// scan failure handling
scanFailure()
}
....
private fun scanSuccess() {
val results = wifiManager.scanResults
... use new scan results ...
}
private fun scanFailure() {
// handle failure: new scan did NOT succeed
// consider using old scan results: these are the OLD results!
val results = wifiManager.scanResults
... potentially use older scan results ...
}
For devices running on Android Q or higher, the only method to properly to connect to a public or private wifi which is not intended as a peer to peer network is to use the NetworkSuggestionAPI as you already showed in your question.
The reason why you sometimes don't see the network suggestion is the following:
"If the user uses the Wi-Fi picker to explicitly disconnect from one of the network suggestions when connected to it, then that network is ignored for 24 hours. During this period, that network will not be considered for auto-connection, even if the app removes and re-adds the network suggestion corresponding to the network.", cited from the Google documentation website.
For more information about the wifi scanning look at the official documentation:
https://developer.android.com/guide/topics/connectivity/wifi-scan#kotlin
More information about the WifiNetworkSuggestion API can be found here:
https://developer.android.com/guide/topics/connectivity/wifi-suggest
Starting from Android 9 (API level 28) a new system app is available for scanning barcodes 1D/2D : its name is "QT code scanner".
Is there any intent to call this system app and have it handle barcode detection in live camera preview to just grab the decoded string in onActivityResult() when the app is done?
Thanks!
I am using Google Mobile Vision API in my Android Application to scan QR codes. The scanning is absolutely fine.
In some phones, the focus is not proper. In Galaxy S4, I have to move the phone back and forth to scan.
The below line is in build.gradle.
compile 'com.google.android.gms:play-services-vision:8.4.0'
This is how I create the CameraSource.
cameraSource = new CameraSource.Builder(this, barcodeDetector).setAutoFocusEnabled(true).build();
Though the auto focus is set to true, the QR code is not focused.
Try using Flag FOCUS_MODE_CONTINUOUS_PICTURE in function setFocusMode
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null)
.setAutoFocusEnabled(true).build();
I am fetching data from server with barcode reading using RS507 ring scanner trigger with Bluetooth pairing with TC55 Kitkat device. I found some problems when I tried to use onKeyDown and onKeyUp callback methods to read barcode. So I used onStatus callback method to read barcode i.e. scanner.read(). I am trying to stop scanner when my Async task operation is in progress, because it causes multiple request calls when I press scanner trigger button multiple times. I tried to use scanner.cancelRead(), but it doesn't helpful. The same case is working fine on TC55 Jellybean device, but only difference in Jellybean case is its not supporting Bluetooth pairing utility with RS507 ring scanner. Can anybody please suggest any solution on this.
You should be receiving barcode data through the DataListener interface (onData), not the status interface (onStatus): http://techdocs.zebra.com/emdk-for-android/6-3/api/reference/com/symbol/emdk/barcode/Scanner.DataListener.html. Also, please make sure your RS507 is in SSI mode (details are in the integration guide), you should not need to use onKeyDown or onKeyUp unless the device is operating in HID mode but EMDK requires SSI mode.
CancelRead() will only be useful if you have previously submitted a read, http://techdocs.zebra.com/emdk-for-android/6-3/api/reference/com/symbol/emdk/barcode/Scanner.html#read()
How to detect if my AndroidTV is currently an Google Cast receiver from mobile/desktop ?
How to detect who is currently an Google Cast sender from Google Cast Receiver perspective?
How to detect if my Android Phone is currently an Google Cast sender?
You could use the Android Media Router API to request all available routes to Cast devices. Then you would then have to connect to each Cast device and then you can determine the app ID or even if media is playing. If you only want to know if your own app is running, then simply filter the Media Router request by that.
Only the receiver would know which senders are connected to it. In your own custom receiver you could keep track of that for your own app.
You might be able to use the Media Router to determine if there is an active route. Not sure if you will be able to tell if it is a Cast route, since these routes could also go to other devices like bluetooth speakers.
To add to Leons answer, we have a callback on the MediaRouter like so to get callback on when our chromecast receiver app is selected
val mMediaRouterCallback = object : MediaRouter.Callback() {
override fun onRouteSelected(router: MediaRouter?, route: MediaRouter.RouteInfo?) {
routeInfo = route
}
override // override appropriate methods here!!
}
val mMediaRouteSelector = MediaRouteSelector.Builder()
.addControlCategory(
CastMediaControlIntent
.categoryForCast(BuildConfig.CHROMECAST_RECEIVER_APP_ID)
).build()
MediaRouter.getInstance(context).addCallback(
mMediaRouteSelector, mMediaRouterCallback,
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN
)
Build selector to work for more than one app. And it is possible to change MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN to broaden your scan.