Questa è una classe che ho scritto per gestire il blocco e lo sblocco dell'orientamento dello schermo. Io chiamo toggleScreenOrientationLock(this, prefs, isChecked)
da checkedChangedListener di un pulsante di attivazione e restoreScreenLock(this, prefs)
da onCreate(). In entrambi i casi this
è la tua attività e prefs
è un oggetto SharedPrefences
, utilizzato per il salvataggio delle informazioni sullo stato del blocco.
La parte complicata del codice è la funzione getScreenOrientation()
, which I stole from and cleaned up from here. Proverò a spiegare la logica dietro a come funziona.
Quando impostiamo l'orientamento del dispositivo con setRequestedOrienation()
, abbiamo bisogno di sapere se il dispositivo è in modalità orizzontale o verticale e abbiamo bisogno di sapere se è un orientamento inverso (ruotato di 180 gradi).
L'utilizzo di getResources().getConfiguration().orientation
risponderà alla domanda su quale orientamento ci troviamo. Se potessimo calcolare la rotazione del dispositivo, potremmo dire se è stato ruotato di 180 o meno. Sfortunatamente, a seconda del dispositivo, ROTATE_0 potrebbe essere verticale o orizzontale. In genere i telefoni mappano ROTATE_0 in verticale e i tablet in orizzontale.
Quindi la soluzione utilizzata qui è quella di utilizzare le dimensioni dello schermo per determinare se è in orizzontale o verticale. Se lo schermo è più largo di quanto è alto, allora deduciamo che il dispositivo è orientato in orizzontale e viceversa per il ritratto. Quindi possiamo calcolare la rotazione per capire se l'orientamento è invertito o meno.
Ad esempio, se lo schermo è più largo dell'altezza, allora sappiamo che siamo in un orientamento orizzontale. Se la rotazione è 0 o 180 (nella logica del codice, questo è uguale a! IsRotatedOrthogonally), allora sappiamo che 0 è LANDSCAPE e 180 è REVERSE_LANDSCAPE.
It has been noted elsewhere che questo non funziona su tutti i dispositivi, dal momento che 90 o 270 è l'orientamento invertito è specifico del dispositivo.Ma questo è probabilmente il meglio che hai intenzione di fare; nel peggiore dei casi, un orientamento ruoterà di 180 gradi quando lo si blocca, il che è ciò che probabilmente accadrà se si tenta di bloccare lo schermo in un altro modo.
public class ScreenLocker {
final private static String ROTATION_LOCKED_KEY = "LockedOrientationVal";
final private static String ROTATION_IS_LOCKED_KEY = "IsRotationLocked";
final private static String ROTATION_SAVED_KEY = "SavedOrientationVal";
public static int getScreenOrientation(Activity activity) {
final Display display = activity.getWindowManager().getDefaultDisplay();
final int rotation = display.getRotation();
Point size = new Point();
display.getSize(size);
final boolean isWiderThanTall = size.x > size.y;
final boolean isRotatedOrthogonally = (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270);
int orientation;
if (isRotatedOrthogonally) {
if (isWiderThanTall)
orientation = (rotation == Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
else
orientation = (rotation == Surface.ROTATION_90) ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; // normal and reversed switched intended
}
else {
if (isWiderThanTall)
orientation = (rotation == Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
else
orientation = (rotation == Surface.ROTATION_0) ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
}
return orientation;
}
public static void toggleScreenOrientationLock(Activity activity,SharedPreferences prefs, boolean lock) {
if(lock)
lockScreenOrientation(activity, prefs);
else
unlockScreenOrientation(activity, prefs);
}
// call this from your activity's onCreate() or onResume()
public static boolean restoreScreenLock(Activity activity, SharedPreferences prefs) {
final boolean isLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);
final int previousLockedOrientation = prefs.getInt(ROTATION_LOCKED_KEY, -999);
if(isLocked && previousLockedOrientation != -999) {
prefs.edit().putInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation()).apply();
activity.setRequestedOrientation(previousLockedOrientation);
return true;
}
return false;
}
private static void lockScreenOrientation(Activity activity, SharedPreferences prefs) {
final int currentOrientation = activity.getRequestedOrientation();
final int lockOrientation = getScreenOrientation(activity);
// checking isCurrentlyLocked prevents the ROTATION_LOCKED_KEY and ROTATION_SAVED_KEY
// becoming identical, which results in the screen not being able to be unlocked.
final boolean isCurrentlyLocked = prefs.getBoolean(ROTATION_IS_LOCKED_KEY, false);
if(!isCurrentlyLocked) {
activity.setRequestedOrientation(lockOrientation);
prefs.edit()
.putInt(ROTATION_SAVED_KEY, currentOrientation)
.putInt(ROTATION_LOCKED_KEY, lockOrientation)
.putBoolean(ROTATION_IS_LOCKED_KEY, true)
.apply();
}
}
private static void unlockScreenOrientation(Activity activity, SharedPreferences prefs) {
final int savedOrientation = prefs.getInt(ROTATION_SAVED_KEY, activity.getRequestedOrientation());
activity.setRequestedOrientation(savedOrientation);
prefs.edit().putBoolean(ROTATION_IS_LOCKED_KEY, false).apply();
}
}
Hai provato 'setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); 'e' setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); '? –
Quale modalità di orientamento avete bisogno? – GrIsHu
Voglio bloccare l'orientamento. Se è orizzontale voglio bloccarlo in orizzontale e se è ritratto voglio bloccarlo in verticale. Entrambi non stanno funzionando. Quindi sto cercando di bloccare l'orientamento orizzontale per scopi di test. – user2682527