I'm looking for something like this:
CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
cameraManager.setTorchMode("0", true);
cameraManager.setTorchLevel("0", 2); //change the brightness based on the number given
This will work only on devices with android 13 and new version of camera hardware abstraction layer (tested on pixel 6 pro). It might also work on some samsung devices with lower android version (not tested).
Related
I'm coding my first android app, and my app has a video recording feature. So I did some research to get the "stuff" ready and run and managed to look into the google sample on github:
https://github.com/googlesamples/android-Camera2Video
So I took a deep dive into the code and yeah quite much just to make a video..
So I do have some restrictions to my camera feature and that is that it runs smoothly with some stable constant 25 Frames per Seconds...
And what I've seen so far there are some setters from the MediaRecorder class (see https://developer.android.com/reference/android/media/MediaRecorder.html)
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mNextVideoAbsolutePath);
mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setCaptureRate(25);
mMediaRecorder.setVideoFrameRate(25);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), getHeight());
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
to set the frame rate, but hence those give a damn about my 25 fps - so generally the output "is like" 29,36 fps or 29,54 fps
I do did some resarch looked into my device support fps range and the P30 Pro does support 25 fps and the pixel 3 XL not. I don't even understand why there are such device differences (maybe someone can explain?).
So Camera2 API does provide so much things that there is a CaptureRequest.Builder and so I did some googling and set my captureRequestBuilder with those additional lines
closePreviewSession();
setUpMediaRecorder();
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range<Integer>(25,25));
mPreviewBuilder.set(
CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
mPreviewBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
But nothing has changed... Is there somebody outhere who has managed to get a stable constant frame rate with the camera2 api?
I hope there is! Thank you if you have read so far!
EDIT Possible duplicates:
Camera2 MediaRecorder changes Frame Rate on Galaxy S9
How to use android camera2 api to record 60 fps video with fixed exposure time
EDIT For the sake of completeness:
Ranges from P30 Pro:
P30 Pro ranges
Ranges from Pixel 3 XL:
Pixel 3 XL ranges
This is how I am getting the screen density using Android Studios
float density = getResources().getDisplayMetrics().density;
According to device specification, S8+ has 4.0 Density value and falls under xxxhdpi category
Refer this site https://material.io/devices/,
Have Attached a screenshot for reference
here
But the value returned by the above code is 2.9, which seems very wrong
check here
Tried using densityDpi also, but it also returns xxhdpi as opposed to xxxhdpi
int densityDpi = context.getResources().getDisplayMetrics().densityDpi;
The above code works well on other devices, tested on OnePlus 5T, Nexus 6P, Redmi Note 4, Moto g4+ and others...facing issues with the Galaxy s8+, haven't tested for Galaxy s8 but i guess the result will be same.
Is this a know Bug, or am I doing something wrong?
Its getting difficult to manage layout for S8+ devices without the correct pixel density info for s8+ devices.
Just like Surfman said. Your phone isn't at the maximum possible resolution. If you take the resolution reported within your screenshot and divide it by the reported 2.9 and multiply it by 4 you end up with roughly the maximum resolution of 2960x1440
You need to initialize display metrics object
You can try this:
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
flat density=metrics.density;
flat densityDpi=metrics.densityDpi;
I have made several values folder and dimen.xml files for configuring my app for different screen sizes. The preview in Android Studio shows them perfectly however, when I run the app on the phone, those dimensions don't take effect. And the layout shown in the Android Studio layout and the layout shown on the phone are different.
So for example on my nexus 5 the app should read dimensions from values-w640dp/dimen.xml however, it reads them from values/dimen.xml for some odd reason.
What can I do to resolve it?
Here are the screenshots.
Android Studio Preview Snapshot (Nexus 5)
Nexus 5 Phone Screenshot:
So dp are calculated using the following formula:
pixels / dp = dpi / 160dpi or pixels / dp = density
Looking at device metrics, the Nexus 5 has a density of 3 so:
dp = pixels / density
dp = 1920px / 3 = 640dp
dp = 1080px / 3 = 360dp
Using values-sw600dp would not fix it because that is not the actual smallest width of the screen since it can also be 360. So you should use values-sw300dp. Be warned though that this covers a very wide variety of devices. values-sw600dp usually targets tablets.
I have also run into issues where the true resolution of the device does not match what the emulator created, with the Nexus 5 too, so make sure you check the AVD screen and ensure that the resolution matches the real resolution of the device. Example, the Nexus 5 should be 1920x1080 and it is. If you ever encounter this issue, recreate the emulator or try a different one entirely.
My android application uses the Y Axis accelerometer to control the character in the game.
This is working fine on most mobile phones, however on my Galaxy Tab 2 10.1, the axis seems to be reversed and I have to manualy change the input for it work.
I would like to write a simple conditional statement that would swap based on device type, however I am unsure what the best practice for this would be. As I am sure someone would have come accross this issue before I ask the question.
How can I determine if the device is a table or a mobile in order to change Accelerometer axis?
I think this relates to the default orientation of the device, which tends to be portrait for phones, or landscape for tablets. There's a question here about exactly that: How to check device natural (default) orientation on Android (i.e. get landscape for e.g., Motorola Charm or Flipout) , and based on my experiences I'd say that this is the best answer . An important point to understand is that whatever the display is doing (landscape, portrait, etc), the x-y-z axes used by the sensors don't change.
I found out the best way to do this is to check the screen size on the device and base a boolean conditional to device on which axis to use. This is tested and working great.
// Check the screen layout to determine if the device is a tablet.
public boolean isTablet(Context context) {
boolean xlarge = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == 4);
boolean large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
return (xlarge || large);
}
// Changle Accelx or Accely input based on the above (Im using
OpenGLES 1.1)
if (isTablet(glGame)) {
world.update(deltaTime, game.getInput().getAccelX());
}
if (!isTablet(glGame)) {
world.update(deltaTime, game.getInput().getAccelY());
}
Is there a way to determnine if current device tablet in Android 2.2 and higher?
Currently I'm using minimal screen dimension, but there is some tablets (Viewsonic ViewPad7 480x800) with resolution like phones or even smaller (e. g. HTC Evo 3D has 960x540).
Is there any hardware property to read?
There is no reliable difference between phones and tablets, it is only possible to point it using specific features, the below can be used in conjunction with each other
The String Build.VERSION.RELEASE will give you the user-visible version string (i.e 1.5, 1.6, 2.0), while Build.VERSION.SDK_INT will give you a value from Build.VERSION_CODES. Remember Build.VERSION.SDK_INT works on Android 1.6 higher but not for 1.5. Build.VERSION.SDK will work on 1.5 or higher.
http://developer.android.com/reference/android/os/Build.html
http://developer.android.com/reference/android/os/Build.VERSION.html
And DisplayMetrics describes general information about a display
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
You can use getResources().getConfiguration()
For example:
getResources().getConfiguration().navigation
The following code will return the actual resolution of the physical device.
Display d = getWindowManager().getDefaultDisplay();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
int h = d.getWidth();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
int w = d.getWidth();