Camera2 cameraManager.openCamera exception from time to time on some devices - android

I have an app which records videos, it has about 80K current installations (more than 100K downloads), Crashlytics statistics seems to be good - Crash-free users 99.66% and rating on Google Play is also OK - 4.5
But still for some of my users can happen the next errors (it may happened for such user once or a couple of times by now, so not often, but still happens from time to time):
android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): connectHelper:1578: Camera "0" disabled by policy
android.hardware.camera2.CameraAccessException: CAMERA_DISCONNECTED (2): Camera service is currently unavailable
java.lang.IllegalArgumentException: supportsCameraApi:2096: Unknown camera ID 0
android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1066: Caller "com.MY_APP_PACKAGE" (PID 10237, UID 21433) cannot open camera "1" when sensor privacy is enabled
on opening camera using camera2 API:
...
cameraManager.openCamera(cameraId, stateCallback, mainHandler)`
} catch (e: Exception) {
e.printStackTrace()
openReportErrorDialog(e) // so a user could report this issue
...
Reported devices:
Vivo 1906
Wheatek BV5500Plus
Samsung SM-N975F
Samsung SM-G988W
Samsung SM-A520F
Motorola REVVLRY
HUAWEI VOG-L09
HUAWEI STK-LX1
HUAWEI MRD-LX1
HUAWEI FIG-LX1
Coolpad CP3669AS
Infinix X655C
Android versions: from 8 to 11 (app min SDK is 6)
So basically it can work fine for a specific user for some time, no issues when opening camera, but from time to time this exception can occur for such user
I don't have any idea why it happens. I can't reproduce this issue on my own devices (two Samsung, one Lenovo, one Huawei and one Xiaomi devices), only users can report such issue from time to time...
The most nonsense exception here is Unknown camera ID 0, because before opening camera I get list of available cameras, so it's not hardcoded, it's not possible that such camera id doesn't exist, and a user said that before this error that camera was working ok
UPDATE
Found this
https://developer.android.com/guide/components/foreground-services#bg-access-restrictions
So it seems if a foreground service was started by system (on BOOT_COMPLETED broadcast, declared in manifest) and not by app (if a user launch app) then it can't access camera and microphone.
So basically after rebooting a device we can't automatically start camera anymore without user interaction.
Really bad for dashboard camera applications for car drivers...
They added ACCESS_BACKGROUND_LOCATION, but there is no ACCESS_BACKGROUND_CAMERA and ACCESS_BACKGROUND_RECORD_AUDIO...

android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): connectHelper:1578: Camera "0" disabled by policy
That either means the device has an enterprise policy installed that disables cameras for example (employers that don't want employees photographing stuff at work), or your app is trying to open the camera in the background, on more recent Android releases.
If it's the policy, there's nothing you can do besides to tell the user that there's a policy in place and to complain to their admins.
android.hardware.camera2.CameraAccessException: CAMERA_DISCONNECTED (2): Camera service is currently unavailable
java.lang.IllegalArgumentException: supportsCameraApi:2096: Unknown camera ID 0
These usually mean something has crashed in the camera stack - until things restart (takes a few seconds usually), all cameras will be reported as unknown.
Ideally that'll never happen, but bugs unfortunately exist even on the best devices. A retry a few seconds later will probably work, unless the camera hardware on the phone is failing in some way that leads to a persistent crash.
android.hardware.camera2.CameraAccessException: CAMERA_DISABLED (1): validateClientPermissionsLocked:1066: Caller "com.MY_APP_PACKAGE" (PID 10237, UID 21433) cannot open camera "1" when sensor privacy is enabled
This means the OEM has some kind of 'shut off all cameras' feature like airplane mode is for radios. Like the enterprise policy above, this is something out of your control - the user needs to re-enable camera access, so all you can do is put up a dialog saying "cameras are disabled, sorry".

If your app targets Android 10 (API level 29) or higher and accesses location information in a foreground service, declare the location foreground service type as an attribute of your component.
<manifest>
...
<service ... android:foregroundServiceType="location|camera" />
At runtime, if the foreground service only needs access to a subset of the types declared in the manifest, you can limit the service's access using the logic in the following code snippet:
Notification notification = ...;
Service.startForeground(notification, FOREGROUND_SERVICE_TYPE_LOCATION| FOREGROUND_SERVICE_TYPE_CAMERA);
This is how you will be able to use camera in the background.

Related

Unable to retrieve camera characteristics for unknown device

I'm receiving reports from some of my users with the following exception
java.lang.IllegalArgumentException: getCameraCharacteristics:1019:
Unable to retrieve camera characteristics for unknown device 0: No
such file or directory (-2) at
android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1591)
at
android.hardware.camera2.CameraManager.getCameraCharacteristics(CameraManager.java:693)
This is of course doesn't make any sense, because we all know that the camera at "0" id should be available. And I have the info about cameras of a device being included to the report anyway:
Camera ID: 0 (selected), all [0, 2, 1, 3]
Cameras level: FULL, LIMITED, LIMITED, LIMITED
So it seems from time to time system thinks that such camera is not available and triggers this annoying exception.
One thing I can say that this issue only happened for Android 12...
UPDATE the issue seems to be related to this one Android camera recording is not working in background mode for some newest smartphones on Android 12

Android: Experiencing "silent" crash when opening Developer Options programmatically from application

I'm experiencing a "silent" crash when Attempting to open the Developer Options programmatically with
override fun openDevelopmentSettings() {
val intent = Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS) //Silent-crashes the app on my phone, but not emulator. What?
startActivity(intent)
}
Opening the About Phone Settings however works perfectly fine when replacing the above param with Settings.ACTION_DEVICE_INFO_SETTINGS
Setting Android Studio's Logcat panel to Error and No Filters produces the following, where the About Phone Settings produce no errors:
2021-04-12 20:43:03.576 1586-2265/? E/UserRestrictionsUtils: Unknown restriction queried by uid 1000 (com.android.providers.settings et al): null
2021-04-12 20:43:03.577 1586-2265/? E/UserRestrictionsUtils: Unknown restriction queried by uid 1000 (com.android.providers.settings et al): null
2021-04-12 20:43:03.592 15832-15832/? E/ndroid.setting: Can't find memory status under: /sys/block/zram0/
2021-04-12 20:43:03.641 674-9189/? E/libnos_datagram: can't send spi message: Try again
2021-04-12 20:43:03.662 674-9189/? E/libnos_datagram: can't send spi message: Try again
2021-04-12 20:43:03.745 15832-15832/? E/BtHDAudioCtr: Active device is null. To disable HD audio button
2021-04-12 20:43:03.854 15832-15832/? E/BtHDAudioCtr: Active device is null. To disable HD audio button
2021-04-12 20:43:03.864 15832-16203/? E/ndroid.setting: Can't find memory status under: /sys/block/zram0/
Please note that the Developer Options menu does open, just my application's process crashes upon opening. Clicking the back button from the Developer Options relaunches my app instead of resuming as the process is dead.
I have used another app that also programmatically opens the Developer Options and do not experience the crash.
I have tried both debug and release builds.
I have also tried wrapping the code in a try-catch block, but when debugging the catch block isn't hit.
I unfortunately don't have another physical device to test on, but an emulator of the same device and API level doesn't reproduce the crash. What's going on here? Is my Pixel 3 at Android 11 (RQ2A.210305.006) corrupted? Memory error? Any help is greatly appreciated, thanks.

Accelerometer event frequency slows down first 5 min using Angular Ionic on Android device

I am using
window.addEventListener('devicemotion', event => this.watchDeviceMotion(event))
watchDeviceMotion(event: any) {
let motionData = {
x: event.acceleration.x,
y: event.acceleration.y,
z: event.acceleration.z,
}
let rotationData = {
alpha: event.rotationRate.alpha,
beta: event.rotationRate.beta,
gamma: event.rotationRate.gamma
}
if (this.getSensorData) {
// console.log(JSON.stringify(motionData))
// console.log(JSON.stringify(rotationData))
this.userData.motionData.push(motionData)
this.userData.rotationData.push(rotationData)
}
}
to access accelerometer data on an Android device using Ionic with Angular. When inside the app, the event works at a frequency of 60 Hz but when the app is switched to background, the frequency drops around 9-10 Hz for the first 5 mins and at some point while still in background it goes back at 60 Hz and remains like that indefinitely.
I am also using the background plugin with
this.backgroundMode.enable();
this.backgroundMode.on('activate').subscribe(() => {
this.backgroundMode.disableWebViewOptimizations();
});
I tried to add disableBatteryOptimizations() to the background plugin with the corresponding condition in config.xml but still no luck.
I also tried the plugins for Device Motion and Gyroscope but they behave the same.
How should I prevent the frequency from slowing down?
Has anyone else encountered this problem before?
It is unclear which version of Android you are using, but working against the system usually leads nowhere. Guess you might have tested that with an elder version, because since Android 9, the sampling rate should have a frequency of 0Hz, when the application is in the background.
This is due to a new power management with "App Standby Buckets", where only the "active" one isn't restricted.
See the Android 9 behavior changes:
Limited access to sensors in background
Android 9 limits the ability for background apps to access user input and sensor data. If your app is running in the background on a device running Android 9, the system applies the following restrictions to your app:
Your app cannot access the microphone or camera.
Sensors that use the continuous reporting mode,
such as accelerometers and gyroscopes, don't receive events.
Sensors that use the on-change or one-shot reporting modes don't receive events.
The only way to prevent this is manually setting the bucket to "active":
adb shell am set-standby-bucket packagename active|working_set|frequent|rare
Source: Test power-related issues and there's also an UsageStatsManager.

How to prevent phone from going to idle mode

I've developed an application that streams music (via internet connection) using service and having trubles streaming content without phone going idle.
While i was developing my application each time i tried case mentioned below the music was reproducing fine.
Use case : search song, select song from results, play song, screen off -> auto play next song from result list
I'm developing using real device - Huawei Mate 20 Lite - OS v8.01 so while debugging it gotta use USB cabel.
Like i said following the use case above while hooked on USB the auto play while screen off works good. The case it doesn't work good is when the cable is not connected (only mobile data turned on).
What I've figured out is that phone when connected on USB is probably keeping the device awake and it doesn't go to idle mode while when not connected after around 5mins the device probably shuts down processes that cost energy or it shuts down connection to mobile data i'm not sure and there's where i need you guys.
Also I've tested app using HTC U Play - OS v6.0 and the streaming goes smooth without interrupts while screen off and phone wasn't touched for 10+mins.
Also I've tried to acquire wakelock inside oncreate and without releasing it just to see if it helps and it doesn't.
pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wl.acquire();
This problem you are facing can be due to the fact that after Andriod 6.0, all apps are getting optimized for optimizing the battery usage.
If you really think, the reason behind the application to go killed is inactivity. Then, probably, its because of battery optimization software itself.
You can enable another permission while installing the app on the device where you can update the list of unoptimized app by adding an entry for your app.
Originally, you will be able to do the manual settings by following below instruction.
. Head for the ‘Settings‘ app and then ‘Battery‘
. On the ‘three dots‘ menu, top right, you’ll find ‘Battery optimisation‘.
. Here you’ll see a list of all applications which shouldn’t be ‘optimised‘ (for which read ‘can be handled by Doze and App Standby’) – by default the list is usually very small, with almost all apps enabled for ‘optimisation’. Which is fine for general users, but if, like me, you want a few applications to live outside of the new battery optimisations, then tap on the ‘Not optimised‘ pick list and choose ‘All apps‘
. As you’d expect, every application on your phone is listed (this may be quite long) – swipe down until you find the application(s) that you particularly want to always keep running. Tap on the application name
. From the two choices, check the box for ‘Don’t optimise‘.

How to handle Google Tango errors caused by user

When a user hold a Tango device the wrong way/blocks the device cameras, the OS displays following message:
"Nothing detected:
Keep the device at least an arm's length from object..."
Is it possible in the Unity Google Tango SDK to detect when this happens?
It's causing my app to become inaccurate and previously placed 3d objects appear at the wrong location.
It would be useful if this error could be handled in code, so the app can show a message to request the user to recalibrate to the app.

Categories

Resources