Meine Hauptaktivität enthält Code, der einige Datenbankänderungen vornimmt, die nicht unterbrochen werden sollten. Ich mache das schwere Heben in einem anderen Thread und verwende einen Fortschrittsdialog, den ich als nicht stornierbar eingestellt habe. Ich bemerkte jedoch, dass ich, wenn ich mein Telefon drehe, die Aktivität neu startet, was WIRKLICH schlecht für den laufenden Prozess ist.
Was ich tun möchte, ist die programmgesteuerte Deaktivierung der Bildschirmorientierungsänderungen, bis mein Prozess abgeschlossen ist. Dann werden Orientierungsänderungen aktiviert.
Wie von Chris in seiner Selbstantwort Anrufung erklärt
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
und dann
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
funktioniert wirklich charmant ... auf echten Geräten!
Denken Sie nicht, dass es beim Testen des Emulators defekt ist. Die Tastenkombination Strg + F11 ändert IMMER die Bildschirmausrichtung, ohne dass die Sensoren bewegt werden.
EDIT: Das war nicht die bestmögliche Antwort. Wie in den Kommentaren erläutert, gibt es Probleme mit dieser Methode. Die wirkliche Antwort ist hier .
Keine der anderen Antworten hat den Trick perfekt für mich gemacht, aber hier ist das, was ich gefunden habe.
Ausrichtung auf aktuelles ... sperren.
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Wenn die Änderung der Ausrichtung erneut zulässig sein soll, setzen Sie die Standardeinstellungen zurück ...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Hier ist eine umfassendere und aktuellere Lösung, die für API 8+ funktioniert, für umgekehrtes Hoch- und Querformat sowie für einen Galaxy-Tab, auf dem die "natürliche" Ausrichtung Querformat ist (Aufruf von activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
zum Entsperren der Ausrichtung).
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
public static void lockActivityOrientation(Activity activity) {
Display display = activity.getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
int height;
int width;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
height = display.getHeight();
width = display.getWidth();
} else {
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
}
switch (rotation) {
case Surface.ROTATION_90:
if (width > height)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_180:
if (height > width)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
case Surface.ROTATION_270:
if (width > height)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default :
if (height > width)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
Um auch die umgekehrten Ausrichtungsmodi zu verwalten, habe ich diesen Code verwendet, um die Aktivitätsausrichtung festzulegen:
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch(rotation) {
case Surface.ROTATION_180:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_270:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
case Surface.ROTATION_0:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
}
Und um nochmal die Orientierung zu erlauben:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Verwenden Sie setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
, um die aktuelle Ausrichtung zu sperren.
Verwenden Sie setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
zum Entsperren der Orientierung.
Ich habe die Antwort gefunden. Dazu können Sie in einer Aktivität setRequestedOrientation(int)
mit einem der hier angegebenen Werte aufrufen: http://developer.Android.com/reference/Android/R.attr.html#screenOrientation
Bevor ich meinen Thread ablegte, rief ich setRequestedOrientation(OFF)
(OFF = nosensor) an und als der Thread fertig war, rief ich setRequestedOrientation(ON)
(ON = sensor) auf. Klappt wunderbar.
Danke euch allen. Ich habe die Lösung von Pilot_51 geändert, um sicherzustellen, dass der vorherige Status wiederhergestellt wurde. Ich habe auch eine Änderung vorgenommen, um Nicht-Querformat- und Nicht-Hochformat-Bildschirme zu unterstützen (habe es jedoch nicht auf einem solchen Bildschirm getestet).
prevOrientation = getRequestedOrientation();
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
Dann um es wieder herzustellen
setRequestedOrientation(prevOrientation);
Hier ist eine Lösung, die jedes Mal funktioniert und die aktuelle Ausrichtung beibehält (beispielsweise durch Verwendung von Activity.Info.SCREEN_ORIENTATION_PORTRAIT
auf 0 °, der Benutzer kann jedoch eine 180 ° -Orientierung als aktuelle Ausrichtung haben).
// Scope: Activity
private void _lockOrientation() {
if (super.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT);
} else {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
}
}
private void _unlockOrientation() {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
protected void setLockScreenOrientation(boolean lock) {
if (Build.VERSION.SDK_INT >= 18) {
setRequestedOrientation(lock?ActivityInfo.SCREEN_ORIENTATION_LOCKED:ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
return;
}
if (lock) {
switch (getWindowManager().getDefaultDisplay().getRotation()) {
case 0: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); break; // value 1
case 2: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); break; // value 9
case 1: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); break; // value 0
case 3: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); break; // value 8
}
} else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); // value 10
}
Das funktioniert perfekt für mich. Es löst Probleme mit unterschiedlicher "natürlicher Orientierung" von Tablet/Telefon;)
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Configuration config = getResources().getConfiguration();
int naturalOrientation;
if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
naturalOrientation = Configuration.ORIENTATION_LANDSCAPE;
} else {
naturalOrientation = Configuration.ORIENTATION_PORTRAIT;
}
// because getRotation() gives "rotation from natural orientation" of device (different on phone and tablet)
// we need to update rotation variable if natural orienation isn't 0 (mainly tablets)
if (naturalOrientation == Configuration.ORIENTATION_LANDSCAPE)
rotation = ++rotation % 4;
switch (rotation) {
case Surface.ROTATION_0: //0
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90: //1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
case Surface.ROTATION_180: //2
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_270: //3
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
}
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
Ich mochte die meisten Antworten hier nicht, da sie beim Entsperren auf UNSPECIFIED gesetzt wurden, im Gegensatz zum vorherigen Zustand. ProjectJourneyman hat dies berücksichtigt, was großartig war, aber ich zog den Sperrcode von Roy vor. Meine Empfehlung wäre also eine Mischung aus beiden:
private int prevOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
private void unlockOrientation() {
setRequestedOrientation(prevOrientation);
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void lockOrientation() {
prevOrientation = getRequestedOrientation();
Display display = getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
int height;
int width;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
height = display.getHeight();
width = display.getWidth();
} else {
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
}
switch (rotation) {
case Surface.ROTATION_90:
if (width > height)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
else
setRequestedOrientation(9/* reversePortait */);
break;
case Surface.ROTATION_180:
if (height > width)
setRequestedOrientation(9/* reversePortait */);
else
setRequestedOrientation(8/* reverseLandscape */);
break;
case Surface.ROTATION_270:
if (width > height)
setRequestedOrientation(8/* reverseLandscape */);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default :
if (height > width)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
verwenden Sie ActivityInfo.SCREEN_ORIENTATION_USER
, wenn Sie den Bildschirm nur drehen möchten, wenn er auf dem Gerät aktiviert ist.
Ich habe festgestellt, dass eine Kombination aus vorhandenen Rotations-/Orientierungswerten erforderlich ist, um die vier Möglichkeiten abzudecken. Es gibt die Hoch-/Querformatwerte und die natürliche Ausrichtung des Geräts. Nehmen wir an, die natürliche Ausrichtung der Geräte hat einen Rotationswert von 0 Grad, wenn sich der Bildschirm im "natürlichen" Hochformat oder im Querformat befindet. In ähnlicher Weise gibt es einen Drehwert von 90 Grad, wenn er sich im Quer- oder Hochformat befindet (beachten Sie, dass er der Orientierung bei 0 Grad entgegengesetzt ist). Die Rotationswerte, die nicht 0 oder 90 Grad sind, implizieren eine "umgekehrte" Ausrichtung. Ok, hier ist ein Code:
public enum eScreenOrientation
{
PORTRAIT (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT),
LANDSCAPE (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE),
PORTRAIT_REVERSE (ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT),
LANDSCAPE_REVERSE (ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE),
UNSPECIFIED_ORIENTATION (ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
public final int activityInfoValue;
eScreenOrientation ( int orientation )
{
activityInfoValue = orientation;
}
}
public eScreenOrientation currentScreenOrientation ( )
{
final int rotation = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
final int orientation = getResources().getConfiguration().orientation;
switch ( orientation )
{
case Configuration.ORIENTATION_PORTRAIT:
if ( rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90 )
return eScreenOrientation.PORTRAIT;
else
return eScreenOrientation.PORTRAIT_REVERSE;
case Configuration.ORIENTATION_LANDSCAPE:
if ( rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90 )
return eScreenOrientation.LANDSCAPE;
else
return eScreenOrientation.LANDSCAPE_REVERSE;
default:
return eScreenOrientation.UNSPECIFIED_ORIENTATION;
}
}
public void lockScreenOrientation ( )
throws UnsupportedDisplayException
{
eScreenOrientation currentOrientation = currentScreenOrientation( );
if ( currentOrientation == eScreenOrientation.UNSPECIFIED_ORIENTATION )
throw new UnsupportedDisplayException("Unable to lock screen - unspecified orientation");
else
setRequestedOrientation( currentOrientation.activityInfoValue );
}
public void unlockScreenOrientation ( )
{
setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED );
}
Ich denke, dass dieser Code einfacher zu lesen ist.
private void keepOrientation() {
int orientation = getResources().getConfiguration().orientation;
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
break;
case Surface.ROTATION_90:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
break;
case Surface.ROTATION_180:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
break;
default:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
}
Sie können verwenden
public void swapOrientaionLockState(){
try{
if (Settings.System.getInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION) == 1) {
Display defaultDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, defaultDisplay.getRotation());
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0);
} else {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 1);
}
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, !orientationIsLocked() ? 1 : 0);
} catch (Settings.SettingNotFoundException e){
e.printStackTrace();
}
}
public boolean orientationIsLocked(){
if(canModifiSetting(mContext)){
try {
return Settings.System.getInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION) == 0;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
}
return false;
}
public static boolean canModifiSetting(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return Settings.System.canWrite(context);
} else {
return true;
}
}
Ich habe eine Lösung gefunden, die von der Display-Drehung abhängt und dann die Ausrichtung des Geräts festlegt. Wenn wir die Orientierung kennen, können wir die Orientierung sperren und sie später wieder freigeben, wenn sie benötigt wird. Diese Lösung kann auch feststellen, ob sich das Gerät im Reverse Landscape Modus befindet.
private void lockOrientation(){
switch (((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
// Portrait
case Surface.ROTATION_0:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
//Landscape
case Surface.ROTATION_90:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
// Reversed landscape
case Surface.ROTATION_270:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
}
}
Wenn wir später die Orientierung freigeben müssen, können wir diese Methode aufrufen:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);