Android : 从 BroadcastReceiver 获取屏幕旋转
Android : Get the screen rotation from a BroadcastReceiver
我有一个 AlarmManager 每 5 分钟执行一次 Intent Broadcast :
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));
在BroadcastReceiver的onReceive方法中,我需要知道设备方向(0°、90°、180°、270°):
int orientation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
一切正常。但是当我最小化或关闭应用程序时,屏幕的旋转总是 returns 0°(android 主屏幕的方向),即使设备水平放置。
我如何从 BroadcastReceiver 知道设备的旋转,而与应用程序或设备的状态无关?
也许 this 就是您要搜索的内容。
context.getResources().getConfiguration().orientation
您可以获得实时更改this way。
我终于用加速度计解决了这个问题:
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);
}
This tutorial 可能对未来的搜索者有用。
要完成这项工作,首先需要做的是创建一个 class,它继承自 BroadcastReceiver
并实现 onReceive()
方法。此方法告诉 BroadcastReceiver
在检测到正确的 Intent 时应该做什么。因此,目前,BroadcastReceiver
class 的子项被定义为当 BroadcastReceiver
被触发时必须执行的代码。在本教程的后面,您将了解如何过滤意图以检测方向变化。为了简单起见,下面的代码检测设备的方向变化和角度,并在 Toast 通知中显示此信息。这是代码:
package fortyonepost.com.orientationbrec;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;
public class OrientationBroadcastReceiver extends BroadcastReceiver
{
//An integer that holds the value of the orientation given by the current configuration
private int configOrientation;
//A WindowManager object that will act as a handle to the window service
private WindowManager wm;
//An integer that holds the value of the orientation (in degrees) given by the window service
private int windowServOrientation;
@Override
public void onReceive(Context context, Intent intent)
{
//Get the orientation from the current configuration object
configOrientation = context.getResources().getConfiguration().orientation;
//Display the current orientation using a Toast notification
switch (configOrientation)
{
case Configuration.ORIENTATION_LANDSCAPE:
{
Toast.makeText(context, "Orientation is LANDSCAPE", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_PORTRAIT:
{
Toast.makeText(context, "Orientation is PORTRAIT", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_SQUARE:
{
Toast.makeText(context, "Orientation is SQUARE", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_UNDEFINED:
default:
{
Toast.makeText(context, "Orientation is UNDEFINED", Toast.LENGTH_SHORT).show();
break;
}
}
//Get a handle to the Window Service
wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//Query the current orientation made available by the Window Service
//The getOrientation() method is deprecated. Instead, use getRotation() when targeting Android API 8 (Android 2.2 - Froyo) or above.
windowServOrientation = wm.getDefaultDisplay().getOrientation();
//Display the current orientation using a Toast notification
switch (windowServOrientation)
{
case Surface.ROTATION_0:
{
Toast.makeText(context, "Rotation is 0 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_90:
{
Toast.makeText(context, "Rotation is 90 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_180:
{
Toast.makeText(context, "Rotation is 180 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_270:
{
Toast.makeText(context, "Rotation is 270 degrees.", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
这里是负责注册的Activity和unregistering
BroadcastReceiver
。这是代码:
package fortyonepost.com.orientationbrec;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class OrientationBroadcastReceiverActivity extends Activity
{
//Create and initialize an OrientationBroadcastReceiver object
private OrientationBroadcastReceiver orientationBR = new OrientationBroadcastReceiver();
//Create and initialize a new IntentFilter
private IntentFilter orientationIF = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume()
{
//Register the Orientation BroadcasReceiver
this.registerReceiver(orientationBR, orientationIF);
super.onResume();
}
@Override
protected void onPause()
{
//Unregister the Orientation BroadcasReceiver to avoid a BroadcastReceiver leak
this.unregisterReceiver(orientationBR);
super.onPause();
}
}
我有一个 AlarmManager 每 5 分钟执行一次 Intent Broadcast :
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));
在BroadcastReceiver的onReceive方法中,我需要知道设备方向(0°、90°、180°、270°):
int orientation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
一切正常。但是当我最小化或关闭应用程序时,屏幕的旋转总是 returns 0°(android 主屏幕的方向),即使设备水平放置。
我如何从 BroadcastReceiver 知道设备的旋转,而与应用程序或设备的状态无关?
也许 this 就是您要搜索的内容。
context.getResources().getConfiguration().orientation
您可以获得实时更改this way。
我终于用加速度计解决了这个问题:
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);
}
This tutorial 可能对未来的搜索者有用。
要完成这项工作,首先需要做的是创建一个 class,它继承自 BroadcastReceiver
并实现 onReceive()
方法。此方法告诉 BroadcastReceiver
在检测到正确的 Intent 时应该做什么。因此,目前,BroadcastReceiver
class 的子项被定义为当 BroadcastReceiver
被触发时必须执行的代码。在本教程的后面,您将了解如何过滤意图以检测方向变化。为了简单起见,下面的代码检测设备的方向变化和角度,并在 Toast 通知中显示此信息。这是代码:
package fortyonepost.com.orientationbrec;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.Toast;
public class OrientationBroadcastReceiver extends BroadcastReceiver
{
//An integer that holds the value of the orientation given by the current configuration
private int configOrientation;
//A WindowManager object that will act as a handle to the window service
private WindowManager wm;
//An integer that holds the value of the orientation (in degrees) given by the window service
private int windowServOrientation;
@Override
public void onReceive(Context context, Intent intent)
{
//Get the orientation from the current configuration object
configOrientation = context.getResources().getConfiguration().orientation;
//Display the current orientation using a Toast notification
switch (configOrientation)
{
case Configuration.ORIENTATION_LANDSCAPE:
{
Toast.makeText(context, "Orientation is LANDSCAPE", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_PORTRAIT:
{
Toast.makeText(context, "Orientation is PORTRAIT", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_SQUARE:
{
Toast.makeText(context, "Orientation is SQUARE", Toast.LENGTH_SHORT).show();
break;
}
case Configuration.ORIENTATION_UNDEFINED:
default:
{
Toast.makeText(context, "Orientation is UNDEFINED", Toast.LENGTH_SHORT).show();
break;
}
}
//Get a handle to the Window Service
wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
//Query the current orientation made available by the Window Service
//The getOrientation() method is deprecated. Instead, use getRotation() when targeting Android API 8 (Android 2.2 - Froyo) or above.
windowServOrientation = wm.getDefaultDisplay().getOrientation();
//Display the current orientation using a Toast notification
switch (windowServOrientation)
{
case Surface.ROTATION_0:
{
Toast.makeText(context, "Rotation is 0 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_90:
{
Toast.makeText(context, "Rotation is 90 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_180:
{
Toast.makeText(context, "Rotation is 180 degrees.", Toast.LENGTH_SHORT).show();
break;
}
case Surface.ROTATION_270:
{
Toast.makeText(context, "Rotation is 270 degrees.", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
这里是负责注册的Activity和unregistering
BroadcastReceiver
。这是代码:
package fortyonepost.com.orientationbrec;
import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
public class OrientationBroadcastReceiverActivity extends Activity
{
//Create and initialize an OrientationBroadcastReceiver object
private OrientationBroadcastReceiver orientationBR = new OrientationBroadcastReceiver();
//Create and initialize a new IntentFilter
private IntentFilter orientationIF = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onResume()
{
//Register the Orientation BroadcasReceiver
this.registerReceiver(orientationBR, orientationIF);
super.onResume();
}
@Override
protected void onPause()
{
//Unregister the Orientation BroadcasReceiver to avoid a BroadcastReceiver leak
this.unregisterReceiver(orientationBR);
super.onPause();
}
}