Search code examples
androidbroadcastreceiveralarmmanagerscreen-orientationandroid-broadcast

Android : Get the screen rotation from a BroadcastReceiver


I have a AlarmManager that execute an Intent Broadcast every 5min :

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 300000, PendingIntent.getBroadcast(context, 0, new Intent(context, Sensors.class), 0));

Inside the BroadcastReceiver's onReceive method, I need to know the device orientation (0°, 90°, 180°, 270°) :

int orientation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();

Everything works fine. But when I minimize or close the app, the screen's rotation always returns 0° (orientation of android home screen), even if the device is lying horizontally.

How can I know the device's rotation from a BroadcastReceiver, independently of the app or device's status?


Solution

  • I finally used the accelerometer to solve this problem :

    SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
    
    if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
    final SensorEventListener sensorEventListener = new SensorEventListener() {
        public void onSensorChanged(SensorEvent event) {
            sensorManager.unregisterListener(this);
    
            int orientation;
    
            // Vertical
            if (Math.abs(event.values[1]) > Math.abs(event.values[0]) && Math.abs(event.values[1]) > Math.abs(event.values[2]))
                if (event.values[1] > 0)
                    orientation = 0; // Head Up
                else
                    orientation = 180; // Head Down
    
            // Horizontal
            else if (Math.abs(event.values[0]) > Math.abs(event.values[1]) && Math.abs(event.values[0]) > Math.abs(event.values[2]))
                if (event.values[0] > 0)
                    orientation = 90; // Left
                else
                    orientation = 270; // Right
    
            // Flat
            else
                orientation = 0;
        }
    
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
    
        }
    };
    
    sensorManager.registerListener(sensorEventListener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
    }