Detect rotation of Android home screen-ThrowExceptions

Exception or error:

I have an App Widget which, when it updates, fetches an image having dimensions to match the widget, and places that image into an ImageView (via RemoteViews). It works just fine.

But for devices that support rotation of the home screen (and I’m not talking about rotation of e.g. an Activity based on device orientation, but about rotation of the home screen itself) the dimensions and aspect ratio of the widget changes a bit when going from landscape to portrait and vice versa… i.e. a fixed size is not maintained.

So, my widget needs to be able to detect when the home screen rotates, and fetch a new image (or at least load a different pre-fetched image).

I can’t for the life of me work out whether and how this is possible. Any clues?

How to solve:

Use below code to detect orientation:-

    View view = getWindow().getDecorView();
    int orientation = getResources().getConfiguration().orientation;

    if (Configuration.ORIENTATION_LANDSCAPE == orientation) {
       relativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.log_landscape));
        imageview_Logo.setImageResource(R.drawable.log_landscape_2);
        Log.d("Landscape", String.valueOf(orientation));
        //Do SomeThing; // Landscape
    } else {
       relativeLayout.setBackgroundDrawable( getResources().getDrawable(R.drawable.login_bg) );
       imageview_Logo.setImageResource(R.drawable.logo_login);
        //Do SomeThing;  // Portrait
        Log.d("Portrait", String.valueOf(orientation));
    }

###

Check this code it works:

 myButton.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {

    int rotation = getWindowManager().getDefaultDisplay()
      .getRotation();
    // DisplayMetrics dm = new DisplayMetrics();
    // getWindowManager().getDefaultDisplay().getMetrics(dm);
    int orientation;
    CharSequence text;

    switch (rotation) {
    case Surface.ROTATION_0:
     text = "SCREEN_ORIENTATION_PORTRAIT";
     break;
    case Surface.ROTATION_90:
     text = "SCREEN_ORIENTATION_LANDSCAPE";
     break;
    case Surface.ROTATION_180:
     text = "SCREEN_ORIENTATION_REVERSE_PORTRAIT";
     break;
    case Surface.ROTATION_270:
     text = "SCREEN_ORIENTATION_REVERSE_LANDSCAPE";
     break;
    default:
     text = "SCREEN_ORIENTATION_PORTRAIT";
     break;
    }

    // CharSequence text = String.valueOf(orientation);
    Toast toast = Toast.makeText(getApplicationContext(), text,
      Toast.LENGTH_SHORT);
    toast.setGravity(Gravity.CENTER | Gravity.CENTER, 10, 0);
    toast.show();

   }
  });

###

Use the onConfigurationChanged method of Activity. See the following code:

@Override
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();
}
}

Okay so for widgets we have to add our application class as below and don’t forget to declare it in manifest also, the method basically sends an update broadcast to all instances of your widget.

public class MyApplication extends Application {

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // create intent to update all instances of the widget
    Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, this, MyWidget.class);

    // retrieve all appWidgetIds for the widget & put it into the Intent
    AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(this);
    ComponentName cm = new ComponentName(this, MyWidget.class);
    int[] appWidgetIds = appWidgetMgr.getAppWidgetIds(cm);
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

    // update the widget
    sendBroadcast(intent);
}
}

and in manifest…

<application
android:name="yourpackagename.MyApplication"
android:description="@string/app_name"
android:label="@string/app_name"
android:icon="@drawable/app_icon">

<!-- here go your Activity definitions -->

###

You can listen for broadcast ACTION_CONFIGURATION_CHANGED which is sent by android system when the current device Configuration (orientation, locale, etc) has changed.
As per documentation :

ACTION_CONFIGURATION_CHANGED :

Broadcast Action: The current device Configuration (orientation,
locale, etc) has changed. When such a change happens, the UIs (view
hierarchy) will need to be rebuilt based on this new information; for
the most part, applications don’t need to worry about this, because
the system will take care of stopping and restarting the application
to make sure it sees the new changes. Some system code that can not be
restarted will need to watch for this action and handle it
appropriately.

You cannot receive this through components declared in manifests, only
by explicitly registering for it with Context.registerReceiver().

This is a protected intent that can only be sent by the system.

public class YourWidgetProvider extends AppWidgetProvider {

        @Override
        public void onEnabled(Context context) {
            super.onEnabled(context);
            context.registerReceiver(mOrientationChangeReceiver,new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
        }

        @Override
        public void onDisabled(Context context) {
            context.unregisterReceiver(mOrientationChangeReceiver);
            super.onDisabled(context);
        }

        public BroadcastReceiver mOrientationChangeReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent myIntent) {
                if ( myIntent.getAction().equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                    if(context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
                        // landscape orientation
                        //write logic for building remote view here
                        // buildRemoteViews();
                    }
                    else {
                        //portrait orientation
                        //write logic for building remote view here
                        // buildRemoteViews();
                    }
                }
            }
        };
    }

###

You could checking it using the widgets width and height as done in the following code snippet:

WindowManager wm; 
Display ds; 
public boolean portrait; 

public void checkOrientation() { 
    wm = getWindowManager(); 
    ds=wm.getDefaultDisplay(); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    checkOrientation(); 
    if (ds.getWidth() > ds.getHeight()) { 
        // ---landscape mode--- 
        portrait = false; 
    } else if (ds.getWidth() < ds.getHeight()) { 
        // ---portrait mode--- 
        portrait = true; 
    } 
} 

###

View view = getWindow().getDecorView();
int orientation = getResources().getConfiguration().orientation;

if (Configuration.ORIENTATION_LANDSCAPE == orientation) {
   relativeLayout.setBackgroundDrawable(getResources().getDrawable(R.drawable.log_landscape));
    imageview_Logo.setImageResource(R.drawable.log_landscape_2);
    Log.d("Landscape", String.valueOf(orientation));
    //Do SomeThing; // Landscape
} else {
   relativeLayout.setBackgroundDrawable( getResources().getDrawable(R.drawable.login_bg) );
   imageview_Logo.setImageResource(R.drawable.logo_login);
    //Do SomeThing;  // Portrait
    Log.d("Portrait", String.valueOf(orientation));
}

Leave a Reply

Your email address will not be published. Required fields are marked *