I know is possible to detect if camera has flash integrated, using a method like this:
/**
* #return true if a flash is available, false if not
*/
public static boolean isFlashAvailable(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
but if the device has 2 cameras how can I test for each of them if has flash available?
For example on a Samsung S2 device, on native camera application when using the front camera the flash button is disabled, meaning is not available.
Thanks.
Paul's answer didn't work for me.
The front camera on a Galaxy Nexus has a valid flash-mode of FLASH_MODE_OFF, but it is the only supported option. This method will work in all situations:
private boolean hasFlash(){
Parameters params = mCamera.getParameters();
List<String> flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Parameters.FLASH_MODE_ON.equals(flashMode)) {
return true;
}
}
return false;
}
If your app supports more than just FLASH_MODE_OFF and FLASH_MODE_ON, you'll need to tweak the if-check inside the loop.
-- Update --
Also you can add torch for flash in if condition if you really need to use torch.
if (Camera.Parameters.FLASH_MODE_ON.equals(flashMode) || Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode)) {
I figured this by myself and I post here the solution, which is actually very simple:
/**
* Check if Hardware Device Camera can use Flash
* #return true if can use flash, false otherwise
*/
public static boolean hasCameraFlash(Camera camera) {
Camera.Parameters p = camera.getParameters();
return p.getFlashMode() == null ? false : true;
}
The above method is different by this one:
/**
* Checking availability of flash in device.
* Obs.: If device has 2 cameras, this method doesn't ensure both cameras can use flash.
* #return true if a flash is available in device, false if not
*/
public static boolean isFlashAvailable(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
}
Related
I have a application which uses camera functionality in it but part of its functionality can also run without camera feature. SO I have put this in my manifest.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
and in my code I check whether the device has camera or not using this
final boolean deviceHasCameraFlag = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
Now I am testing my code on a tablet which runs Android 4.0(ICS) and has no camera. But still I get True value for the deviceHasCameraFlag. Is this weird or am I missing something.
I tried different things and even tried the same thing on Bluetooth feature as Tablet even doesn't have Bluetooth feature. It works fine for Bluetooth but gives me true for camera.
Which device is it? The answer you get is a bug, and 4.0 is very old nowadays. Many tablets that still run this version were not crafted correctly, both hardware and software featuring multiple problems.
Regardless, you should always be prepared to handle failure on Camera.open() or Camera.open(0): for example, in some cases other software on your device will not release the camera gracefully.
So, in your case you have a false positive, you try to open the camera, it fails, and you continue as if there is no camera on the device, even if PackageManager thinks that PackageManager.FEATURE_CAMERA is availabe.
Though I have accepted Alex's answer I still want to put this one collectively as what can be the best solution in such condition.
What I found was in case of some low standard android devices
pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)
returns true even if camera doesn't exist and that seems to be a device bug for me which in unchecked.
So whenever there is scenario that you need to check if camera exists for a device or not best practice is something that I am putting below (best practice as per my knowledge if there is something more interesting and best solution that this you are welcome to put it here on this post)
int numberOfCameras = Camera.getNumberOfCameras();
context = this;
PackageManager pm = context.getPackageManager();
final boolean deviceHasCameraFlag = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
if( !deviceHasCameraFlag || numberOfCameras==0 )
{
Log.e(TAG, "Device has no camera" + numberOfCameras);
Toast.makeText(getApplicationContext(), "Device has no camera", Toast.LENGTH_SHORT).show();
captureButton.setEnabled(false);
}
else
{
Log.e(TAG, "Device has camera" + deviceHasCameraFlag + numberOfCameras);
}
In this I am checking both number of cameras as well as device has camera feature Boolean , so in any case it would not fail my condition.
In my case I had this code:
public boolean hasCameraSupport() {
boolean hasSupport = false;
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) { //<- this constant caused problems
hasSupport = true;
}
return hasSupport;
}
and it kept returning false on a Genymotion device running Android 4.1.1 (API 16). Once I changed the constant PackageManager.FEATURE_CAMERA_ANY to PackageManager.FEATURE_CAMERA, my problems went away. I am guessing that not all devices/API levels support PackageManager.FEATURE_CAMERA_ANY.
I got it you will try this one definitely it will work....
import android.hardware.Camera;
int numCameras = Camera.getNumberOfCameras();
if (numCameras > 0) {
System.out.println("camera");
} else {
System.out.println("No Camera");
}
For CameraX, if the FEATURE_CAMERA_ANY method is still returning true when there is no Camera on device, you can add the below method. So whether FEATURE_CAMERA_ANY returns true or false when CameraX is getting initialized, Below method will make sure to do what you want if a camera is actually not available on device.
private CameraSelector cameraSelector;
private ProcessCameraProvider cameraAvailableCheck;
private ListenableFuture<ProcessCameraProvider> cameraAvailableCheckFuture;
private void checkIfAnyCameraExist()
{
cameraAvailableCheckFuture = ProcessCameraProvider.getInstance(context);
cameraAvailableCheckFuture.addListener(new Runnable() {
#Override
public void run() {
try {
cameraAvailableCheck = cameraAvailableCheckFuture.get();
if ((cameraAvailableCheck.hasCamera(cameraSelector.DEFAULT_BACK_CAMERA) || cameraAvailableCheck.hasCamera(cameraSelector.DEFAULT_FRONT_CAMERA) ))
{
//Do what you want if at least back OR front camera exist
}
else
{
//Do what you want if any camera does not exist
}
}
catch (ExecutionException | InterruptedException | CameraInfoUnavailableException e)
{
// No errors need to be handled for this Future.
// This should never be reached.
}
}
}, ContextCompat.getMainExecutor(this));
}
Please try this code:
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
Still it does't work then please let me know
Can we get the flash settings from the native camera app programmatically?
I mean to say, for example, if the user meddles with the flash modes in the default camera app, I want to read the flash mode set by him on my app, which is to run in the background. Is this possible?
In order to get the current flash mode, as Mr. Harshit suggested you need to getFlashMode(). For getting the same you may use the below code
Parameters params;
Camera cam;
cam=Camera.open();
params=cam.getParameters();
System.out.println(params.getFlashMode());
Try this and see if this works...
private boolean hasFlash(){
Parameters params = mCamera.getParameters();
List<String> flashModes = params.getSupportedFlashModes();
if(flashModes == null) {
return false;
}
for(String flashMode : flashModes) {
if(Parameters.FLASH_MODE_ON.equals(flashMode)) {
return true;
}
}
return false;
}
First check whether flashLight is supported or not
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
which will return true if a flash is available, false if not.
Check if flash is AUTO, ON, or OFF as:
List<String> flashModes = cameraParams.getSupportedFlashModes();
if(flashModes!=null && flashModes.size()>0)
{
if(cameraParams.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_ON))
{
//DO STUFF...
}
else if(cameraParams.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_OFF))
{
//DO STUFF......
}
else if(cameraParams.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_TORCH))
{
//DO STUFF......
}
else if(cameraParams.getFlashMode().equals(android.hardware.Camera.Parameters.FLASH_MODE_AUTO))
{
//DO STUFF......
}
}
I need to detect if the phone has a front facing camera, and if so, I need to calculate the megapixels. The same thing goes for a rear facing camera.
I know how to get the megapixels of a "Camera" object, but I don't know how to check for the other things.
P.s.: I would also be nice if you know a way to check if the Camera has flash or not, and other cool statistics about the camera
I always try to create helpers
check if you have a front Camera:
public static boolean checkCameraFront(Context context) {
if(context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) {
return true;
} else {
return false;
}
}
Check if you have Camera in your device
public static boolean checkCameraRear() {
int numCamera = Camera.getNumberOfCameras();
if(numCamera > 0) {
return true;
} else {
return false;
}
}
http://developer.android.com/reference/android/hardware/Camera.html#getNumberOfCameras() , introduced in API lvl 9. This gets you the number of cameras
http://developer.android.com/reference/android/hardware/Camera.CameraInfo.html contains information of its facing direction.
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getPictureSize() is megapixels, if counted
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#getFlashMode() returns null if no flash..
many other parameters can be gotten from the camera object too
http://developer.android.com/reference/android/hardware/Camera.html has step by step instructions for using camera. You can follow these instructions if you understand any object oriented language.
I have been working with the CAMERA module for my application since few days.
I have customized the complete camera module instead of invoking the hardware inbuilt mobile camera through an intent. I have used the call backs for shutter, picture etc
Now I am trying to add the ZOOM and AUTO-FOCUS features to this customized camera. Can anybody please let me know the way to add the ZOOM and AUTO-FOCUS features along with the required permissions which should be mentioned in the manifest file..hope i will be helped as soon as possible.
Couple of observations from my end.
1) Camera.autoFocus is a one-time call, applicable when
Camera.getParameters.getFocusMode() is either FOCUS-MODE-AUTO or
FOCUS-MODE-MACRO, in other cases you don't need to invoke the
autoFocus method. See the API Docs and follow them devotedly.
2) By one-time call, it means that this method does not register the
AutoFocusCallback instance to receive notifications continuously.
3) Rather, FOCUS-MODE-AUTO isn't even a dynamic and continuous focus
constant. Instead, you might want to use FOCUS-MODE-EDOF or
FOCUS-MODE-CONTINUOUS-PICTURES depending on the API Level and the
SDK version that you are using and building for.
4) There is every
possibility that the actual Device Camera may not support some
FOCUS-MODE constants, such as EDOF or INFINITE. Always make sure
when you are creating the camera-parameters, you check for
getSupportedFocusModes and use the applicable constants.
5) Calling
camera.autoFocus just before camera.takePicture can bloat the
resulting jpeg-byte-array in the PictureCallBack to at least 50%
more than it's original size. Not calling autoFocus() explicitly may
sometimes cause the previous autoFocus() to end at a very
low-resolution that may result a jpeg-byte-array length of only a
10K bytes, resulting in a null image bitmap from the BitmapFactory.
6) Regarding auto-focus permissions, see the API Docs.
7) Regarding
Zoom, it is not as complicated as implementing the Auto-focus
feature. Depending on screen-interaction such as slider, or hardware
keys such as volume-keys, you could implement a ZoomChangeListener
that you can register with the Camera as soon as the Camera instance
is received from open(int cameraId).
For zoom (2x):
Camera.Parameters parameters = camera.getParameters();
parameters.set("zoom", "2.0");
parameters.set("taking-picture-zoom", "20");
For api level > 5 use the api's like setZoom() etc
For autofocussing (taken from zxing)
public final boolean onKeyDown(int keyCode, KeyEvent event) {
synchronized(this) {
if (!bIsPictureTaking) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_CAMERA) {
if (!bIsPictureTaking && !bIsAutoFocusStarted){
YourAutoFocusCallback autoFocusCallBack = new YourAutoFocusCallback();
camera.autoFocus(autoFocusCallBack);
.
final class YourAutoFocusCallback implements Camera.AutoFocusCallback {
private static final long AUTOFOCUS_INTERVAL_MS = 1500L;
private final CameraConfigurationManager configManager;
private boolean reinitCamera;
private Handler autoFocusHandler;
private int autoFocusMessage;
AutoFocusCallback(CameraConfigurationManager configManager) {
this.configManager = configManager;
}
void setHandler(Handler autoFocusHandler, int autoFocusMessage) {
this.autoFocusHandler = autoFocusHandler;
this.autoFocusMessage = autoFocusMessage;
}
public void onAutoFocus(boolean success, Camera camera) {
if (autoFocusHandler != null) {
Message message = autoFocusHandler.obtainMessage(autoFocusMessage, success);
autoFocusHandler.sendMessageDelayed(message, AUTOFOCUS_INTERVAL_MS);
autoFocusHandler = null;
configManager.setDesiredCameraParameters(camera);
} else {
}
}
}
I am trying to write an app that requires the LED flash to go into torch mode. The problem is, Android 2.1 does not support this mode and therefore I cannot support the platform yet. Wouldn't be an issue, but I am writing it for my fiance and her Epic 4G only has 2.1 right now. I found some code samples that use some undocumented API calls and therefore work on the Motorola Droid and such, but they do not work on the Epic. Does anyone have some suggestions on where to look to find code that should help me get this working?
I'm finding that torch mode is generally working fine on 2.1 but I had the same problem with the Samsung Epic and found a hack around it.
Looking at the params returned by Camera.getParameters() when run on the Samsung Epic, I noticed that the flash-modes it claims to support are: flash-mode-values=off,on,auto;
torch-mode is not listed, implying it's not supported.
However, I found that this model would still accept that mode and WOULD turn the LED on! The bad news was that when later setting the flash-mode back to auto or off left the LED still lit! It will not turn off until you call Camera.release().
I guess that's why Samsung dont include it in the list of supported!?!
So...the method I use to toggle torch in a CameraHelper class is...
/***
* Attempts to set camera flash torch/flashlight mode on/off
* #param isOn true = on, false = off
* #return boolean whether or not we were able to set it
*/
public boolean setFlashlight(boolean isOn)
{
if (mCamera == null)
{
return false;
}
Camera.Parameters params = mCamera.getParameters();
String value;
if (isOn) // we are being ask to turn it on
{
value = Camera.Parameters.FLASH_MODE_TORCH;
}
else // we are being asked to turn it off
{
value = Camera.Parameters.FLASH_MODE_AUTO;
}
try{
params.setFlashMode(value);
mCamera.setParameters(params);
String nowMode = mCamera.getParameters().getFlashMode();
if (isOn && nowMode.equals(Camera.Parameters.FLASH_MODE_TORCH))
{
return true;
}
if (! isOn && nowMode.equals(Camera.Parameters.FLASH_MODE_AUTO))
{
return true;
}
return false;
}
catch (Exception ex)
{
MyLog.e(mLOG_TAG, this.getClass().getSimpleName() + " error setting flash mode to: "+ value + " " + ex.toString());
}
}
The activities that use this call it as follows...
private void toggleFlashLight()
{
mIsFlashlightOn = ! mIsFlashlightOn;
/**
* hack to fix an issue where the Samsung Galaxy will turn torch on,
* even though it says it doesnt support torch mode,
* but then will NOT turn it off via this param.
*/
if (! mIsFlashlightOn && Build.MANUFACTURER.equalsIgnoreCase("Samsung"))
{
this.releaseCameraResources();
this.initCamera();
}
else
{
boolean result = mCamHelper.setFlashlight(mIsFlashlightOn);
if (! result)
{
alertFlashlightNotSupported();
}
}
}
The magic that makes this work in releaseCameraResources() is that it calls Camera.release()....and then I have to reinitialize all my camera stuff for Samsung devices.
Not pretty but seems to be working for plenty of users.
Note that I do have a report of torch mode not working at all with this code on Nexus one but have been able to dig into it. It definitely works on HTC EVO and Samsung Epic.
Hope this helps.
In my case for Samsung devices I needed to set focus mode to infinity and it started to work
params.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
mCamera.setParameters(params);
mCamera.startPreview();