2012-01-26 19 views
22

Chcę uzyskać orientację telefonu, ale zachowaj orientację ekranu na portret. Tak więc bez względu na to, czy użytkownik zmienia telefon w krajobraz czy portret, widok pozostaje taki sam, ale mogę uzyskać, czy jest on ustawiony na krajobraz lub portret.Pobierz orientację telefonu, ale ustaw orientację ekranu na portret

Ustawianie aktywności do android: screenOrientation = „portret” rozwiąże oba, ale nie będzie w stanie wykryć orientację telefonu przez

public void onConfigurationChanged(Configuration newConfig) { 
    switch (newConfig.orientation) { 
    case Configuration.ORIENTATION_PORTRAIT: 
     Toast.makeText(this, "Portrait", Toast.LENGTH_SHORT).show(); 
     break; 
    case Configuration.ORIENTATION_LANDSCAPE: 
     Toast.makeText(this, "Landscape", Toast.LENGTH_SHORT).show(); 
     break; 
    default: 
     break; 
    } 
} 

Ma ktoś pomysł jak to naprawić?

+0

Spójrz na to: http://stackoverflow.com/a/41104983/2267723 to rozwiązanie za pomocą SensorManager. –

Odpowiedz

19

Czy możesz zaspokoić swoje wymagania za pomocą akcelerometru? Jeśli tak, być może coś takiego (nietestowany) fragment pasowałoby do twoich celów.

SensorManager sensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE); 
     sensorManager.registerListener(new SensorEventListener() { 
      int orientation=-1;; 

      @Override 
      public void onSensorChanged(SensorEvent event) { 
       if (event.values[1]<6.5 && event.values[1]>-6.5) { 
        if (orientation!=1) { 
         Log.d("Sensor", "Landscape"); 
        } 
        orientation=1; 
       } else { 
        if (orientation!=0) { 
         Log.d("Sensor", "Portrait"); 
        } 
        orientation=0; 
       } 
      } 

      @Override 
      public void onAccuracyChanged(Sensor sensor, int accuracy) { 
       // TODO Auto-generated method stub 

      } 
     }, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); 
+0

Cześć Phillip. To jest to samo rozwiązanie, które sam wdrożyłem. W tym kontekście wydaje się, że nie ma innej możliwości uzyskania dostępu do czujnika w celu uzyskania orientacji urządzenia. – Arman

+4

Nie ma dużej wartości, jeśli urządzenie leży płasko na stole. – AndroidDev

+2

Ktoś wie, jak wykryć reverse_landscape? – edrian

0

Aby dostać się, że chcesz ustawić w pliku manifestu w tej działalności

android:configChanges="orientation|keyboardHidden" 

Potem, gdy przyszedł telefon obracania użytkownik to będzie w public void onConfigurationChanged() metody. Usuń również z tej samej działalności

android:screenOrientation="portrait" 

z tej samej działalności.

+1

Ale jeśli zostanie wywołana funkcja onConfigurationChanged(), zmiana orientacji została już wykonana ... Potrzebuję informacji wcześniej. – Arman

2

Jeśli wyłączysz zmienić orientację ekranu to oczywiście onConfigurationChanged nigdy nie będzie o nazwie ...

Myślę, że jedynym sposobem jest użycie czujnik przyspieszenia, sprawdzić this link.

+0

Uszkodzony link. Czy możesz go zaktualizować? –

+0

Uszkodzony link zaktualizowano. – vitakot

25

Oto klasa wielofunkcyjny na łatwe zarządzanie zmiany orientacji ekranu:

public class OrientationManager extends OrientationEventListener { 

    public enum ScreenOrientation { 
     REVERSED_LANDSCAPE, LANDSCAPE, PORTRAIT, REVERSED_PORTRAIT 
    } 

    public ScreenOrientation screenOrientation; 
    private OrientationListener listener; 

    public OrientationManager(Context context, int rate, OrientationListener listener) { 
     super(context, rate); 
     setListener(listener); 
    } 

    public OrientationManager(Context context, int rate) { 
     super(context, rate); 
    } 

    public OrientationManager(Context context) { 
     super(context); 
    } 

    @Override 
    public void onOrientationChanged(int orientation) { 
     if (orientation == -1){ 
      return; 
     } 
     ScreenOrientation newOrientation; 
     if (orientation >= 60 && orientation <= 140){ 
      newOrientation = ScreenOrientation.REVERSED_LANDSCAPE; 
     } else if (orientation >= 140 && orientation <= 220) { 
      newOrientation = ScreenOrientation.REVERSED_PORTRAIT; 
     } else if (orientation >= 220 && orientation <= 300) { 
      newOrientation = ScreenOrientation.LANDSCAPE; 
     } else { 
      newOrientation = ScreenOrientation.PORTRAIT;      
     } 
     if(newOrientation != screenOrientation){ 
      screenOrientation = newOrientation; 
      if(listener != null){ 
       listener.onOrientationChange(screenOrientation); 
      }   
     } 
    } 

    public void setListener(OrientationListener listener){ 
     this.listener = listener; 
    } 

    public ScreenOrientation getScreenOrientation(){ 
     return screenOrientation; 
    } 

    public interface OrientationListener { 

     public void onOrientationChange(ScreenOrientation screenOrientation); 
    } 
} 

To sposób bardziej prosty, wielokrotnego użytku, a także można dostać REVERSE_LANDSCAPE i REVERSE_PORTRAIT orientacje.

Musisz wdrożyć OrientationListener, aby otrzymywać powiadomienia tylko w przypadku zmiany orientacji.

Nie zapomnij zadzwonić orientationManager.enable(), aby rozpocząć śledzenie orientację, a następnie wywołanie orientationManager.disable() (te dwie metody są dziedziczone z klasy OrientationEventListener)

UPDATE: przypadek użycia przykładem

MyFragment extends Fragment implements OrientationListener { 

    ... 

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

     orientationManager = new OrientationManager(getActivity(), SensorManager.SENSOR_DELAY_NORMAL, this); 
     orientationManager.enable();   
    } 

    @Override 
    public void onOrientationChange(ScreenOrientation screenOrientation) { 
     switch(screenOrientation){ 
      case PORTRAIT: 
      case REVERSED_PORTRAIT: 
       MainActivityBase.getInstance().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
      break; 
      case REVERSED_LANDSCAPE: 
       MainActivityBase.getInstance().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
      break; 
      case LANDSCAPE: 
       MainActivityBase.getInstance().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
      break; 
     } 
    } 
} 
+0

Tak miło, dziękuję bardzo. Nie mogę uwierzyć, że ta odpowiedź dostarczyła tylko jeden głos. – formatc

+4

Świetne rozwiązanie, ale pamiętaj, że daje to prawidłowy wynik tylko na smartfonach, które mają tryb portretu jako tryb domyślny. Na tabletach (domyślnie w orientacji poziomej) orientacja będzie miała wartość 0 w przypadku orientacji poziomej, tzn. Przed zastosowaniem logiki trzeba dodać 270 do wartości orientacji. Aby uzyskać domyślną orientację urządzenia, zobacz http://stackoverflow.com/questions/4553650/how-to-check-device-natural-default-orientation-on-android-ie-get-landscape –

+0

I 3 lata później " m znalezienie tego i to jest takie eleganckie rozwiązanie ... gdybym mógł dać ci więcej niż 1 haha. –

-2

W przypadku, gdy ktoś szuka rozwiązania Webview/javascript na pytanie, poniżej może to zrobić.

Spowoduje to uruchomienie niestandardowych zdarzeń "przewracania" w oknie z "dodatkowymi parametrami", takimi jak jquery. Określa ona również window.flip analogowy do window.orientation:

$(window).on('flip',function(ev,angle,orientation) { 
    console.log(angle,orientation); 
    alert(window.flip); 
}); 

if (window.DeviceOrientationEvent) { 
    jQuery.flip = { 
     debug  : false, 
     interval : 1000, 
     checked  : false, 
     betaflat : 25, 
     gammaflat : 45, 
     orientation : 'portrait-primary', 
     angles  : { 
      'portrait-primary'  : 0, 
      'portrait-secondary' : 0, 
      'landscape-primary'  : 90, 
      'landscape-secondary' : -90  
     }, 
     timer  : null, 
     check  : function(ev) { 
      if (!this.checked) { 
       var trigger=false; 
       if (this.debug) console.log([ev.alpha,ev.beta,ev.gamma]); 
       if (ev.beta>this.betaflat) { 
        // if beta is big its portrait 
        if (this.debug) console.log('beta portrait pri'); 
        if (this.orientation!='portrait-primary') { 
         this.orientation='portrait-primary'; 
         trigger=true; 
        } 
       } else if (ev.beta<-this.betaflat) { 
        // if beta is big its portrait 
        if (this.debug) console.log('beta portrait sec'); 
        if (this.orientation!='portrait-secondary') { 
         this.orientation='portrait-secondary'; 
         trigger=true; 
        } 
       } else if (ev.gamma>this.gammaflat) { 

        // else if gamma is big its landscape 
        if (this.debug) console.log('gamma landscape pri'); 
        if (this.orientation!='landscape-primary') { 
         this.orientation='landscape-primary'; 
         trigger=true; 
        } 

       } else if (ev.gamma<-this.gammaflat) { 

        // else if gamma is big its landscape 
        if (this.debug) console.log('gamma landscape sec'); 
        if (this.orientation!='landscape-secondary') { 
         this.orientation='landscape-secondary'; 
         trigger=true; 
        } 

       } 
       if (trigger) { 
        if (this.debug) console.log('trigger flip'); 
        window.flip = this.angles[this.orientation]; 
        $(window).trigger('flip',[window.flip,this.orientation]); 
        this.checked=true; 
       } 
      } 
     } 
    } 
    $(document).ready(function() { 
     setInterval(function() {jQuery.flip.checked=false},jQuery.flip.interval); 
     $(window).on('deviceorientation',function(ev) { jQuery.flip.check(ev.originalEvent) }); 
    }); 
} else { 
    if (this.debug) console.log('DeviceOrientationEvent not supported'); 
} 

jQuery nie jest naprawdę potrzebne. I tak go miałem.

+0

Dlaczego upadek? – commonpike

+1

Rozwiązywanie problemów z Androidem za pomocą Javascriptu nie jest zbyt pomocne. Wymaga posiadania WebView lub podobnego do uruchomienia skryptu, co może nie być prawdą. – Arman

+0

oh - dobry punkt. żyjąc w mojej własnej bańce. aktualizowanie odpowiedzi. – commonpike

1

Potrzebowałem rozwiązania, które dałoby mi orientację tylko na żądanie. Ten pracował dla mnie:

public class SensorOrientationChecker { 

public final String TAG = getClass().getSimpleName(); 

int mOrientation = 0; 
private SensorEventListener mSensorEventListener; 
private SensorManager mSensorManager; 

private static SensorOrientationChecker mInstance; 

public static SensorOrientationChecker getInstance() { 
    if (mInstance == null) 
     mInstance = new SensorOrientationChecker(); 

    return mInstance; 
} 

private SensorOrientationChecker() { 
    mSensorEventListener = new Listener(); 
    Context applicationContext = GlobalData.getInstance().getContext(); 
    mSensorManager = (SensorManager) applicationContext.getSystemService(Context.SENSOR_SERVICE); 

} 

/** 
* Call on activity onResume() 
*/ 
public void onResume() { 
    mSensorManager.registerListener(mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); 
} 

/** 
* Call on activity onPause() 
*/ 
public void onPause() { 
    mSensorManager.unregisterListener(mSensorEventListener); 
} 

private class Listener implements SensorEventListener { 

    @Override 
    public void onSensorChanged(SensorEvent event) { 
     float x = event.values[0]; 
     float y = event.values[1]; 

     if (x<5 && x>-5 && y > 5) 
      mOrientation = 0; 
     else if (x<-5 && y<5 && y>-5) 
      mOrientation = 90; 
     else if (x<5 && x>-5 && y<-5) 
      mOrientation = 180; 
     else if (x>5 && y<5 && y>-5) 
      mOrientation = 270; 

     //Log.e(TAG,"mOrientation="+mOrientation+" ["+event.values[0]+","+event.values[1]+","+event.values[2]+"]"); 
                     } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 

    } 

} 

public int getOrientation(){ 
    return mOrientation; 
    } 
} 
Powiązane problemy