halo,
i have an issue with my app i'm trying to get all cameras of my phone.
my app detects only 2 cameras
i'm using :
val manager = context!!.getSystemService(Context.CAMERA_SERVICE) as CameraManager
var listOfCamer as = manager.cameraIdList;
When I tried openCamera (https://opencamera.sourceforge.io/help.html), it detects 4 cameras!
Or we use the same method/class
CameraManager manager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
try {
return manager.getCameraIdList().length;
}
am I missing some config / permissions?
(Android 10 or higher) Hide physical sub-cameras from getCameraIdList. This reduces the number of cameras that can be directly opened by apps, eliminating the need for apps to have complex camera selection logic.
I think this is the reason. Try the same with old Camera API (though it is deprecated now), perhaps, it would allow you to see all your 4 devices.
Related
I want to disable camera functionality in my app, if the device does not have a camera. However, I seem to have stumbled into a bug when doing so.
According to the official Android Developer docs, I can use hasSystemFeature() to detect device features at runtime, as shown below:
boolean hasAnyCamera = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
Log.i(LOG_TAG, "hasAnyCamera = " + hasAnyCamera);
boolean hasBackCamera = this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
Log.i(LOG_TAG, "hasBackCamera = " + hasBackCamera);
However, I tried to create an emulator without a front-facing or back-facing camera, and it still returns true for both checks. Is there some other way that I can detect the camera in Android?
Relevant documentation:
Take Photos > Request the camera feature
PackageManager.hasSystemFeature()
PackageManager.FEATURE_CAMERA_ANY
PackageManager.FEATURE_CAMERA
After some research, it appears that this is a known bug, which has been unresolved for 10+ years now.
See: Emulator does not honour Camera support flag
It seems that the only know work-around is to detect the number of cameras using the Camera.getNumberOfCameras() method, which has been deprecated since Android 5.0.
boolean hasCamera = Camera.getNumberOfCameras() > 0;
Log.i(LOG_TAG, "hasCamera = " + hasCamera);
The above method seems to work on my emulator, despite the warning that it is deprecated.
Now according to the docs for Camera.getNumberOfCameras():
"The return value of [getNumberOfCameras()] might change dynamically if the device supports external cameras and an external camera is connected or disconnected."
So perhaps hasSystemFeature() always returns true, because the device might later have an external camera attached?
An emulator started by using a hardware configuration which enables or disables some features in runtime. It would be possible to add / change some configuration for your emulator.
I think, It is not removing camera hardware, just disables them. I created an emulator as you mentionned and there was no camera. When I changed the configuration I was able to use the camera. However, hasSystemFeature returned true for both situtation.
When you create an emulator, the settings you choose is written in hardware-qemu.ini for that AVD. You can find it in ~/.android/avd/YOUR_EMULATOR.avd/hardware-qemu.ini. You can get exact path in show on disk on Device Manager.
Im currently trying to activate the built in front flashlight on a Samsung Galaxy A6, but the device provides information like there is no built in front flash.
I've already tried different methods, which can be found by searching for activating flash.
First Try was to get supportedFlashModes and then activate the flash by using setParameters (API < 23). But simply the getParameters() for the front camera doesn't return any information of the built in front flash. For the app it just seems like there is no front flash available.
Then i tried to use the Camera2 API, introduced in API >= 23 and there the same Problem occurs. Fetching camera characteristics and then check if FLASH_INFO is available just results in returning false. Also trying to just activate the flash unit with setTorchMode(FRONT_CAMERA, true) throws an exception which says: No flash unit available.
I currently only have Samsung Galaxy A6 as test device with built in front flash. The same code works fine for the rear (back) camera without any problems.
ad 1)
try {
Camera camera;
camera = Camera.open(cameraId);
if (camera == null) {
return false;
}
Camera.Parameters parameters = camera.getParameters();
if (parameters.getFlashMode() == null) {
camera.release();
return false;
}
...
It just quits at that point because .getFlashMode() returns null for the front camera. Next steps would be to check the supportedFlashModes and then call setParamater of Camera.
ad 2)
try {
String camID = null;
for(String cameraID : mCameraManager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraID);
int orientation = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
if (orientation == CameraCharacteristics.LENS_FACING_FRONT) {
if(cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE)) {
camID = cameraID;
}
}
if(camID != null) {
mCameraManager.setTorchMode(camID, true);
}
} catch (Exception exc) {
...
}
These are only snippets for simply activating the front flash, but both methods act like the hardware response without a built in front flash.
After research it seems that some phone manufacturers are using private APIs to control hardware. Especially Samsung and Huawei are making use of that. The main camera app on a device is mainly controlled by that API and Frontflash can be used as expected. But even big camera apps like Instagram and Snapchat can't get rid of that and are also not able to activate e.g. Frontflash.
For own purposes the hardware just doesn't provide any features for activating Frontflash on some devices, it just reacts like there is no built-in frontflash. For now there are no solutions available for this problem.
Exisiting workarounds are doing a whitening of the screen to lighten up the environment in front of the phone.
I would like to know if there is some kind of an API in android studio that enables communication between a device and the android phone through a USB. For example, external camera.
I have used SetupAPI and WINUSB before to accomplish such a task. So something similar to those two would be appreciated.
The company that created the device does not provide an SDK, driver or any extra information.
Thank you very much.
It depends on what you want to do BUT short answer is yes.
To detect an external camera you may try this:
public String getExternalCamera(){
CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
String exCamId = null;
for (String cameraId : cameraManager.getCameraIdList()) {
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId);
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
//LENS_FACING_EXTERNAL will return Value: 2
if (facing != null && facing.equals(CameraCharacteristics.LENS_FACING_EXTERNAL)) {
exCamId = cameraId;
}
}
return exCamId;
}
LENS_FACING_EXTERNAL
added in API level 23
public static final int LENS_FACING_EXTERNAL
The camera device is an external camera and has no fixed facing relative to the device's screen.
You can also use:
INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
added in API level 28
public static final int INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL
This camera device is backed by an external camera connected to this Android device.
The device has capability identical to a LIMITED level device, with some exceptions.
For more info see Android documentation here!
I use this code for turning on airplane mode on android:
Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 1);
newIntent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
newIntent.putExtra("state", true);
context.sendBroadcast(newIntent);
It works on API 16 but on API 23 doesn't work and application terminates. What should I do?
And second question is: How to turn on and off mobile data in android without root?
As per docs Settings.System.AIRPLANE_MODE_ON constant is deprecated since API Level 17 and onwards, That's why your application is crashing.
You should use Settings.Global.AIRPLANE_MODE_ON instead.
i use this method to record video from front camera:
Recording video via Mediarecorder
it works fine in my Nexus 4 but some people says that there is a lot of phones that their front camera cant record video and they only can take pictures. My Android App functionality based on recording video from front camera and my question is that is this true that some phones can't record video via front camera? and how i can detect this and inform user?
Try calling some code like this
CameraInfo cameraInfo = new CameraInfo();
if (cameraInfo.facing = CameraInfo.CAMERA_FACING_FRONT) {
//do your code?
} else {
//alert the user via toast or dialog
}
no built in way to figure it out though.
EDIT:
should work on API 9 and above.
maybe try calling these methods to first get a camera object, then check to see if there is a camcorderProfile available for the front facing camera?
hasProfile (int cameraId, int quality)
setCamera(camera);