In my app I have set preferred orientations of portrait
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
])
But I would like to listen for changes in the orientation without changing what is displayed on the screen
I want to listen for orientation changes even though it is locked
I would like some code equivalent to this
MediaQuery.of(context).orientation
However, since I have locked it to portrait it will always say portrait
You can use SensorManager class for this:
SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
sensorManager.registerListener(new SensorEventListener() {
int orientation=-1;;
#Override
public void onSensorChanged(SensorEvent event) {
if (event.values[1]<6.5 && event.values[1]>-6.5) {
if (orientation!=1) {
Log.d("Sensor", "Landscape");
}
orientation=1;
} else {
if (orientation!=0) {
Log.d("Sensor", "Portrait");
}
orientation=0;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
There are also other ways you can check in this post: Get phone orientation but fix screen orientation to portrait
I suggest using this package native_device_orientation it provides accurate orientation and doesn't just look at the devices width.
// Gets the devices orientation
NativeDeviceOrientation orientation = await NativeDeviceOrientationCommunicator().orientation(useSensor:true);
Related
This is Code for getting proximity sensor.On sensor change i show a Toast message.
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mSensor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
#Override
public void onSensorChanged(SensorEvent event) {
Toast.makeText(this, "Sensor Changed", Toast.LENGTH_LONG).show();
if (event.values[0] == 0) {
Toast.makeText(this, "Screen off", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Screen on", Toast.LENGTH_LONG).show();
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
}
For the testing this app i connect to the emulator via telnet like this telnet localhost 5554. The i change the proximity like this sensor set proximity 5. but it doesn't work. What is the wrong thing i did ?
This is achievable with following steps:
Open AS, run the emulator
Click on Extended controls
Choose Virtual sensors
In upper tab choose Additional sensors
And there you have it, play with proximity as you want
No, You cannot use proximity sensors on the emulator but you can test them on the real device because they contains that kind of sensors you want to test like accelerometer, gyroscope , magnetometer. But yes you can try gps like application in emulator using DDMS. You can use Genymotion with limited functionality on free version but real devices are advantageous.
One solution will be use a third party virtualized android machine like Genymotion .
The application has neat controls to change location data and sensor data , it even has built in java libraries to implement test cases
I have a custom Camera that works just fine,except for the implementation of flash that Iam using.I have tried using FLASH_MODE_AUTO in surfaceChanged.I have also tried using the following code using a Light Sensor:
SensorEventListener listener=new SensorEventListener(){
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
//Not touching this with a ten foot pole
}
#Override
public void onSensorChanged(SensorEvent event) {
float lux=event.values[0];
Log.d(TAG, "The light sensor says: "+lux+" lux");
Camera.Parameters params=mCamera.getParameters();
cancelAutoFocus();
if(lux<50)
{
if(params.getFlashMode()!=Parameters.FLASH_MODE_ON)
params.setFlashMode(Parameters.FLASH_MODE_ON);
if(params.getExposureCompensation()!=params.getMinExposureCompensation())
params.setExposureCompensation(params.getMinExposureCompensation());
Log.d(TAG, "Exposure has been set to "+params.getMinExposureCompensation());
mCamera.setParameters(params);
}
else
{
params.setFlashMode(Parameters.FLASH_MODE_OFF);
mCamera.setParameters(params);
}
}
};
Whatever I do,when I take a picture and the flash fires,my picture ends up looking like this:
However when I take a picture with the default Camera app,it looks ordinary,even a little dim.
I would like to get rid of this workaround using the Light Sensor entirely and use FLASH_MODE_AUTO.How can I get my camera to behave in low-light conditions and/or with the flash turned on?
Or is there any post-processing that I must do in order to ensure that the image is of lesser brightness.
In my project I need to use proximity sensor to manage screen light.
From last 3 days I'm trying to do the same thing. But still I din't got success.
My half code is working fine. Am able to off the screen light using proximity sensor. but screen light not getting on. When I'm covering the sensor with my hand, screen light is getting off. but light not getting on after removing my hand from sensor.
My code is:
#Override
public void onSensorChanged(SensorEvent event)
{
if(event.sensor.getType() == Sensor.TYPE_PROXIMITY)
{
switch (lastSensorPosition)
{
//case 1 will turn on screen light
case 1:
lastSensorPosition = 2;
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL;
getWindow().setAttributes(lp);
break;
//case 2 will turn off screen light
case 2:
lastSensorPosition = 1;
WindowManager.LayoutParams lp1 = getWindow().getAttributes();
lp1.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_OFF;
getWindow().setAttributes(lp1);
break;
default:
break;
}
}
}
I'm expecting a great help from you guys...
private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
public class SensorActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mProximity;
#Override
public final void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get an instance of the sensor service, and use that to get an instance of
// a particular sensor.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
}
#Override
public final void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do something here if sensor accuracy changes.
}
#Override
public final void onSensorChanged(SensorEvent event) {
float distance = event.values[0];
// Do something with this sensor data.
}
#Override
protected void onResume() {
// Register a listener for the sensor.
super.onResume();
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// Be sure to unregister the sensor when the activity pauses.
super.onPause();
mSensorManager.unregisterListener(this);
}
}
Some proximity sensors return binary values that represent "near" or "far." In this case, the sensor usually reports its maximum range value in the far state and a lesser value in the near state. Typically, the far value is a value > 5 cm, but this can vary from sensor to sensor. You can determine a sensor's maximum range by using the getMaximumRange() method.
I have an application that I only want to run in landscape mode (e.g. landscape or reverse landscape) so I am using sensorLandscape in the manifest.
My problem is here:
I also have a video recorder working (eg using the camera). Now I set the display orientation when i prepare the camera, but the problem is that if I change orientation that change stays (preview is upside down). When using sensor landscape how do I know when the UI is changed. I have tried using onConfigurationCanged() but unfortunately I need to have the app run on both pre honeycomb devices (mainly gingerbread) and post honeycomb devices (jelly bean).
Since in order to properly have onConfigurationChanged called i need to set target api to like 8, but sensor landscape is only available 9+. I need to set it to 8 because in the older api's you need to add screenSize to your "configChanges" otherwise it will not be called. So these calls have alot of incompatabilities between eachother.
Now that the background is done and you guys know what I have tried already. My question is
How can I find out when my orientation changes (callback, or something else) so that I can change my camera display orientation?
Thank you in advance.
I have figured out how to get this done. It is a round about way but here it is:
Set up a sensor manager and an oreitnation senosr
public class ActivityRecordVideo extends ActivityBase implements SensorEventListener
{
private SensorManager mSensorManager;
private Sensor mOrientation;
#Override
public void onCreate(Bundle savedInstanceState)
{
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
}
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
public void onSensorChanged(SensorEvent event) {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if(camId != -1 && currentDisplayRotation != rotation)
{
if(!isRecording)
setCameraOrientation(camId, cameraRecorder);
}
}
I also set the listeners in onResume() and remove them in onPause().
This allows for a camera orientation to flip with everything else (e.g. when in reverse landscape all views are in reverse landscape along with the camera preview)
Also decided to show setCameraOrientation code, it is a stipped down version of the android developers code
private void setCameraOrientation(int camId, Camera camera)
{
CameraInfo info = new CameraInfo();
Camera.getCameraInfo(camId, info);
currentDisplayRotation = getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch(currentDisplayRotation)
{
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; //compensate for mirror effect
if(Build.VERSION.SDK_INT < 14)
camera.stopPreview();
camera.setDisplayOrientation(result);
if(Build.VERSION.SDK_INT < 14)
camera.startPreview();
}
Hopefully this will help others
I am implementing a camera in android. I have kept the activity as landscape in the manifest.
Since i have given the orientation as fixed, i am not able to get orientation by display. it always gives as LandScape. But i want to know when my device is held in portrait or vertical position. I do not want the screen orientation. Can any one suggest a good way to detect device orientation.
Thanks all
I think you will have to listen to the accelerometer sensor updates and parse them to determine when the orientation changes. there is some examples of listening to the sensors here: http://www.anddev.org/accessing_the_accelerometer-t499.html and here http://mobilestrategist.blogspot.com/2010/01/android-accelerometer-and-orientation.html
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
// Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
// Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
// Checks whether a hardware keyboard is available
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
// Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
} else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
// Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
}
}
To detect screen orientation you can use the following code in your activity
#Override
public void onConfigurationChanged(Configuration newConfig)
{ super.onConfigurationChanged(newConfig);
}
Thanks
Deepak
Try this:
First implement SensorEventListener and get the RotationSensor
sensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
rotationSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
sensorManager.registerListener(this, rotationSensor, SENSOR_INTERVAL);
int FROM_RADS_TO_DEGS = -57;
Then you can detect the angle of the device like this:
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor == rotationSensor) {
if (event.values.length > 4) {
float[] truncatedRotationVector = new float[4];
System.arraycopy(event.values, 0, truncatedRotationVector, 0, 4);
updateRotation(truncatedRotationVector);
} else {
updateRotation(event.values);
}
}
}
private void updateRotation(float[] vectors) {
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(rotationMatrix, vectors);
int worldAxisX = SensorManager.AXIS_X;
int worldAxisZ = SensorManager.AXIS_Z;
float[] adjustedRotationMatrix = new float[9];
SensorManager.remapCoordinateSystem(rotationMatrix, worldAxisX, worldAxisZ, adjustedRotationMatrix);
float[] orientation = new float[3];
SensorManager.getOrientation(adjustedRotationMatrix, orientation);
float pitch = orientation[1] * FROM_RADS_TO_DEGS;
if(pitch < -45 && pitch > -135) {
// if device is laid flat on a surface, we don't want to change the orientation
return;
}
float roll = Math.abs(orientation[2] * FROM_RADS_TO_DEGS);
if((roll > 45 && roll < 135)) {
// The device is closer to landscape orientation. Enable fullscreen
if(!player.isFullScreen()) {
if(getActivity() != null) {
player.setFullScreenOn();
}
}
}
else {
// The device is closer to portrait orientation. Disable fullscreen
if(player.isFullScreen()) {
if(getActivity() != null) {
player.setFullScreenOff();
}
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Do nothing
}
This got the original code from a tutorial, but it was a while ago, so I cant remember where the tutorial was. This version is heavily customised to my requirements, but if anyone recognises it from the original, please drop in the link.
I used this code to detect when a video player should go fullscreen inside a ViewPage that I didn't want to allow landscape orientation on. It works well except for one thing:
It uses RotationSensor hardware, and not all Android devices have a RotationSensor. If anyone knows of a way to do it using some hardware that is included on all devices (There definitely is a way because Android knows when to switch orientation), please let me know in a comment so I can update my own code.
I use this:
#Override
public void onConfigurationChanged(Configuration _newConfig){
super.onConfigurationChanged(_newConfig);
int height = getWindowManager().getDefaultDisplay().getHeight();
int width = getWindowManager().getDefaultDisplay().getWidth();
if(width > height){
// landscape
}else{
// portrait
}
}
It is crude but effective.