2012-01-26 2 views
22

Desidero ottenere l'orientamento del telefono ma mantenere l'orientamento dello schermo su verticale. Quindi, non importa se l'utente trasforma il telefono in orizzontale o verticale, la vista rimane la stessa, ma posso capire se è orientata in orizzontale o verticale.Ottieni l'orientamento del telefono, ma fissa l'orientamento dello schermo al verticale.

Impostare l'attività di Android: screenOrientation = "ritratto" risolverà entrambi, ma non sarebbe in grado di rilevare l'orientamento del telefono tramite

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

Qualcuno ha un'idea di come risolvere questo?

+0

Dai un'occhiata a questo: http://stackoverflow.com/a/41104983/2267723 questa soluzione utilizzando SensorManager. –

risposta

19

Potresti soddisfare i tuoi requisiti con l'accelerometro? Se è così, forse qualcosa come questo frammento (non testato) sarebbe adatto ai tuoi scopi.

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

Ciao Phillip. Questa è la stessa soluzione che ho implementato io stesso. In questo contesto sembra che non ci siano altre opzioni per accedere al sensore per ottenere l'orientamento del dispositivo. – Arman

+4

Non ha molto valore se il dispositivo è appoggiato su un tavolo. – AndroidDev

+2

Qualcuno sa come rilevare reverse_landscape? – edrian

0

per entrare in che si desidera impostare nel file manifesto in quell'attività

android:configChanges="orientation|keyboardHidden" 

Poi, quando il telefono dell'utente ruotarlo sarà entrato in public void onConfigurationChanged metodo(). Rimuovere anche

android:screenOrientation="portrait" 

dalla stessa attività.

+1

Ma se onConfigurationChanged() viene chiamato, la modifica dell'orientamento è già stata eseguita ... Ho bisogno delle informazioni precedenti. – Arman

2

Se si disattiva il cambiamento orientamento dello schermo, allora ovviamente l'onConfigurationChanged non verrà mai chiamato ...

penso che l'unico modo è quello di utilizzare il sensore accelerometro, controllare this link.

+0

Collegamento interrotto. Potete per favore aggiornarlo? –

+0

Collegamento interrotto aggiornato. – vitakot

25

Ecco una classe multi-purpose per gestire facilmente le modifiche di orientamento dello schermo:

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

Questo è il modo più semplice, riutilizzabile, e si può anche ottenere REVERSE_LANDSCAPE e orientamenti REVERSE_PORTRAIT.

È necessario implementare OrientationListener per ottenere una notifica solo quando si verifica un cambiamento di orientamento.

Non dimenticare di chiamare orientationManager.enable() per iniziare il monitoraggio orientamento, e quindi chiamando orientationManager.disable() (questo due metodi sono ereditati dalla classe OrientationEventListener)

UPDATE: caso d'uso esempio

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

Così carino, grazie mille. Non posso credere che questa risposta abbia solo un valore in più. – formatc

+4

Ottima soluzione, ma si prega di essere consapevoli che questo dà il risultato corretto solo su smartphone che hanno la modalità verticale come modalità predefinita. Sui tablet (con paesaggio come impostazione predefinita), l'orientamento avrà valore 0 in caso di orientamento orizzontale, vale a dire, è necessario aggiungere 270 al valore di orientamento prima di applicare la logica. Per l'orientamento del dispositivo predefinito, consultare http://stackoverflow.com/questions/4553650/how-to-check-device-natural-default-orientation-on-android-ie-get-landscape –

+0

e 3 anni dopo I ' trovando questo e questa è una soluzione così elegante ... se potessi darti solo più di 1 haha. –

-2

Nel caso in cui qualcuno stia cercando una soluzione Webview/javascript alla domanda, quanto segue può farlo.

Questo attiverà eventi "flip" personalizzati nella finestra, con "parametri aggiuntivi" come li ha jquery. Essa stabilisce inoltre window.flip, analogica alla 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 non è realmente necessario. Ho avuto richiesto comunque.

+0

Perché il downvote? – commonpike

+1

Risolvere un problema Android con Javascript non è molto utile. Richiede di avere una WebView o simile per eseguire lo script che potrebbe non essere il caso. – Arman

+0

oh - buon punto. vivendo nella mia stessa bolla. aggiornando la risposta. – commonpike

1

Avevo bisogno di una soluzione che mi desse l'orientamento solo su richiesta. Questo ha funzionato per me:

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; 
    } 
} 
Problemi correlati