Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect orientation change from the statusbar

Under the Statusbar, there are five buttons - Wifi, Bluetooth, GPS, Silent Mode and Auto Rotation. I haven't figured out a way yet to detect when a user click the Auto Rotation button.

What I have done is have a Service that listen for orientation changes, like:

public class MyService extends Service {

    @Override
    public void onCreate() {
       super.onCreate();
       IntentFilter intentFilter = new IntentFilter();
       intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
       this.registerReceiver(myReceiver, intentFilter);     
    }

    public BroadcastReceiver myReceiver = new BroadcastReceiver() {
       @Override
       public void onReceive(Context context, Intent intent) {
          if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
             // Show a message about orientation changes.
             // This method is only called when the phone is physically rotated.
          }
       }
    }  
}

The above BroadcastReceiver will only work if the phone is physically rotated, but if the Auto Rotation button is clicked without any physical rotation of the phone, then the BroadcastReceiver method is never called.

I have also tried OrientationEventListener - but same behaviour as the BroadcastReceiver method.

To set orientation, I used the following method:

Settings.System.getInt(context.getContentResolver(), "accelerometer_rotation")

So I know there's a method to interrogate System settings. Is there an Intent that traps system setting's [orientation] changes? I've gone through Android docs but can't find one - perhaps, I'm looking in the wrong place, or there's no Intent for it.

Does anyone know a way to trap changes to the Auto Rotation button in the Statusbar?

UPDATE 1: The devices I'm working with are: Samsung Galaxy S3, Samsung Galaxy S2, Samsung Galaxy S and Samsung Galaxy Ace and many other. All of these devices are running stock ROM and have the Auto Rotation button under the Statusbar.

UPDATE 2: There have been suggestions advising to use the ContentObserver to listen for changes to system setting, for example:

public class SettingsContentObserver extends ContentObserver {
    public SettingsContentObserver(Handler handler) {
       super(handler);
    }

    @Override
    public boolean deliverSelfNotifications() {
       return super.deliverSelfNotifications(); 
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);
        Logging.writeDebug("Settings change detected: " + selfChange);
    }

    public void registerContentObserver(Context context) {
        context.getContentResolver().registerContentObserver(Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION), true, this);
    }

    public void unregisterContentObserver(Context context) {
       context.getContentResolver().unregisterContentObserver(this);
    }
}

However, I found that the selfChange variable in onChange method always return false.

like image 517
ChuongPham Avatar asked Dec 12 '22 23:12

ChuongPham


1 Answers

I guess you will have to listen for Settings.System.ACCELEROMETER_ROTATION. Havent tried but this should work.

getContentResolver().registerContentObserver(Settings.System.getUriFor
(Settings.System.ACCELEROMETER_ROTATION),
true,contentObserver);

Edit: Just like Onrecieve of BroadcastReceiver there is a onchange of contentobserver. SO whenever the button is clicked you will get a callback here.

private ContentObserver contentObserver = new ContentObserver(new Handler()) {
        @Override
        public void onChange(boolean selfChange) {
           // show a toast here
        }
};
like image 80
nandeesh Avatar answered Dec 31 '22 00:12

nandeesh