2012-01-26 31 views
22

我想獲取手機方向,但保持屏幕方向爲人像。 因此,無論用戶將手機變爲橫向還是縱向,視圖都保持不變,但是我可以判斷它是轉向橫向還是縱向。獲取手機方向,但將屏幕方向修復爲人像

設置活動機器人:screenOrientation =「肖像」會同時修改,但我不會能夠通過

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

檢測手機的方向有沒有人一個想法如何解決呢?

+0

看看這個:http://stackoverflow.com/a/41104983/2267723這個解決方案使用SensorManager。 –

回答

19

您能滿足您對加速度計的要求嗎?如果是這樣,也許像這樣(未經測試)的片段將適合您的目的。

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

嗨菲利普。 這就是我自己實施的同樣的解決方案。在這種情況下,似乎沒有其他選擇,然後訪問傳感器,以獲得設備的方向。 – Arman

+4

如果設備平放在桌子上,沒有多大價值。 – AndroidDev

+2

任何人都知道如何檢測reverse_landscape? – edrian

0

要進入要在清單文件來設置該活動

android:configChanges="orientation|keyboardHidden" 

然後,當用戶旋轉手機它會來到公共無效onConfigurationChanged()方法。 同樣來自同一個活動中刪除

android:screenOrientation="portrait" 

+1

但是,如果調用onConfigurationChanged()方向更改已經執行......我需要之前的信息。 – Arman

2

如果禁用屏幕方向變化,則顯然onConfigurationChanged將永遠不會被稱爲...

我認爲唯一的方法是使用加速度傳感器,檢查this link

+0

斷開的鏈接。你能否更新它? – 2017-01-19 02:45:43

+0

已更新斷開的鏈接。 – vitakot

25

這裏是一個多用途類易管理屏幕方向的變化:

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

這是方式更簡單,可重複使用,而且還可以得到REVERSE_LANDSCAPE和REVERSE_PORTRAIT方向。

您必須實現OrientationListener只有當方向發生變化時得到通知。

不要忘記調用orientationManager.enable()開始姿勢的跟蹤,然後調用orientationManager.disable()(這兩種方法是從OrientationEventListener類繼承)

更新:使用情況實例

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

太好了,非常感謝。不能相信這個答案只有一個upvote。 – formatc

+4

偉大的解決方案,但請注意,只有在具有縱向模式作爲默認模式的智能手機上才能得到正確的結果。 在平板電腦上(默認情況下爲橫向),橫向方向的方向將爲0,也就是說,在應用邏輯之前,必須將方向值添加270。 對於默認設備方向,請參閱http://stackoverflow.com/questions/4553650/how-to-check-device-natural-default-orientation-on-android-ie-get-landscape –

+0

而3年後,發現這一點,這是一個優雅的解決方案...如果我只能給你多1 upvote哈哈。 –

-2

如果有人正在尋找一個Webview/JavaScript解決方案的問題,下面可以做到這一點。

這將觸發窗口自定義「炫」事件,「額外的參數」爲jQuery有他們。它還設置window.flip,模擬到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的。無論如何,我都需要它。

+0

爲什麼downvote? – commonpike

+1

用Javascript解決Android問題並不是很有幫助。它需要有一個WebView或類似的腳本才能運行腳本。 – Arman

+0

哦 - 好點。生活在我自己的泡沫中。更新答案。 – commonpike

1

我需要一個解決方案,只會按需提供給我的方向。這一個爲我工作:

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