简体   繁体   English

检测Android主屏幕的旋转

[英]Detect rotation of Android home screen

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 ).我有一个App Widget ,当它更新时,它会获取一个具有与小部件匹配的尺寸的图像,然后将该图像放入ImageView (通过RemoteViews )。 It works just fine.它工作得很好。

But for devices that support rotation of the home screen (and I'm not talking about rotation of eg 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... ie a fixed size is not maintained.但是对于支持主屏幕旋转的设备(我不是在谈论基于设备方向的Activity的旋转,而是关于主屏幕本身的旋转)小部件的尺寸和纵横比在运行时会发生一些变化从横向到纵向,反之亦然......即不保持固定大小。

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?有什么线索吗?

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));
    }

Maybe you could frame your image with a transparent background. 也许你可以用透明背景构图。 If the image is small enough to fit also when rotated, you won't need to re-fetch it. 如果图像小到足以在旋转时也适合,则无需重新获取图像。

You can listen for broadcast ACTION_CONFIGURATION_CHANGED which is sent by android system when the current device Configuration (orientation, locale, etc) has changed.当当前设备配置(方向、区域设置等)发生变化时,您可以侦听由 android 系统发送的广播 ACTION_CONFIGURATION_CHANGED。 As per documentation :根据文档:

ACTION_CONFIGURATION_CHANGED : 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;当这种变化发生时,UI(视图层次结构)将需要根据这些新信息重新构建; 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().您无法通过清单中声明的​​组件接收此信息,只能通过使用 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();
                    }
                }
            }
        };
    }

Use the onConfigurationChanged method of Activity.使用 Activity 的 onConfigurationChanged 方法。 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 -->

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();

   }
  });

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));
}

Since Android API 16, there is a new override that receives configuration information.从 Android API 16 开始,有一个新的覆盖来接收配置信息。

@Override
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions)
{
    int width = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
    int height = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT);
    int orientation = context.getResources().getConfiguration().orientation;

    if (BuildConfig.DEBUG) logWidgetEvents("UPDATE " + width + "x" + height + " - " + orientation, new int[] { appWidgetId }, appWidgetManager);

    onUpdate(context, appWidgetManager, new int[] { appWidgetId });
}

The onUpdate() can then check orientation, like this:然后 onUpdate() 可以检查方向,如下所示:

int rotation = context.getResources().getConfiguration().orientation;
if (rotation == Configuration.ORIENTATION_PORTRAIT)
{
    ... portrait ...
}
else
{
    ... landscape ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM