私の主な活動には、中断されるべきではないデータベースの変更を行うコードがあります。別のスレッドで重い作業を行っており、キャンセル不可として設定した進行状況ダイアログを使用しています。しかし、私は自分の電話を回転させると、実行中のプロセスにとって本当に悪いアクティビティを再開し、強制的に閉じることに気づきました。
私がやりたいことは、プロセスが完了するまで画面の向きの変更をプログラムで無効にし、その時点で向きの変更を有効にすることです。
私の主な活動には、中断されるべきではないデータベースの変更を行うコードがあります。別のスレッドで重い作業を行っており、キャンセル不可として設定した進行状況ダイアログを使用しています。しかし、私は自分の電話を回転させると、実行中のプロセスにとって本当に悪いアクティビティを再開し、強制的に閉じることに気づきました。
私がやりたいことは、プロセスが完了するまで画面の向きの変更をプログラムで無効にし、その時点で向きの変更を有効にすることです。
回答:
クリスが自己回答で説明したように、
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
その後
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
本当に魅力のように動作します...実際のデバイスで!
エミュレーターでテストするときに壊れているとは思わないでください。センサーの動きをエミュレートすることなく、ctrl + F11ショートカットは常に画面の向きを変更します。
編集:これは可能な最良の答えではありませんでした。コメントで説明されているように、この方法には問題があります。本当の答えはここにあります。
ActivityInfo.SCREEN_ORIENTATION_SENSOR
Androidのネイティブ方向ロックを尊重しません。方向をリセットActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
します。
他の答えはどれも私にとって完璧なトリックはしませんでしたが、これが私が見つけたものです。
現在の方向にロック...
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
方向の変更を再度許可する必要がある場合は、デフォルトに戻します...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Configuration.ORIENTATION_PORTRAIT
は、両方のランドスケープモード(つまり、「通常」モードと反転)で返されることです。そのため、スマートフォンが横向きに反転してActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
いて、それに設定すると、上下が逆になります。API 9では、ActivityInfoによってSCREEN_ORIENTATION_REVERSE_LANDSCAPE
定数が導入されていますが、Configuration
クラスを通じてそのような方向を検出する方法がわかりません。
これは、API 8+で機能し、逆ポートレートとランドスケープで機能し、「自然な」方向がランドスケープであるGalaxyタブで機能する、より完全で最新のソリューションです(activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
方向をロック解除するための呼び出し)。
@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);
}
}
static
を作成しActivity activity
て、パラメータとして追加できます。
逆方向モードも管理するために、そのコードを使用してアクティビティの方向を修正しました。
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;
}
そして再びオリエンテーションを許可するには:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
現在の向きを横向きまたは縦向きにロックするために使用 します。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
方向のロックを解除するために使用します。
答えを見つけました。これを行うには、アクティビティsetRequestedOrientation(int)
で、ここで指定された値の1つを使用して呼び出すことができます:http : //developer.android.com/reference/android/R.attr.html#screenOrientation
スレッドを開始する前にsetRequestedOrientation(OFF)
(OFF = nosensor)を呼び出し、スレッドが完了したときにsetRequestedOrientation(ON)
(ON = sensor)を呼び出しました。魅力のように機能します。
皆さんありがとう。Pilot_51のソリューションを変更して、確実に前の状態に復元するようにしました。また、非横長および非縦長の画面をサポートするための変更も加えました(ただし、そのような画面ではテストしていません)。
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);
}
それを復元するには
setRequestedOrientation(prevOrientation);
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
}
これは毎回機能し、現在の方向を維持するソリューションです(Activity.Info.SCREEN_ORIENTATION_PORTRAIT
たとえば、0°に設定を使用しますが、ユーザーは現在の方向として180°の方向を持つことができます)。
// 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);
}
使用ActivityInfo.SCREEN_ORIENTATION_USER
あなたがそのデバイス上で有効になっている場合にのみ回転画面にしたい場合。
これは私にとっては効果的です。タブレット/電話の「自然な向き」の問題を解決します;)
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);
}
ディスプレイの回転に依存し、デバイスの向きを決定するソリューションを考え出しました。向きを知ることで、向きをロックし、後で必要に応じて解放することができます。このソリューションは、デバイスがリバースランドスケープモードであるかどうかも判別できます。
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;
}
}
その後、方向を解放する必要がある場合は、このメソッドを呼び出すことができます。
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
このコードは読みやすいと思います。
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);
}
}
}
4つの可能性をカバーするには、既存の回転/方向の値の組み合わせが必要であることがわかりました。ポートレート/ランドスケープの値とデバイスの自然な向きがあります。画面が「自然な」縦向きまたは横向きの場合、デバイスの自然な向きは0度の回転値を持つとしましょう。同様に、横向きまたは縦向きの場合、回転値は90度になります(0度の向きとは反対です)。したがって、0度または90度以外の回転値は「逆」方向を意味します。さて、ここにいくつかのコードがあります:
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 );
}
ロック解除では以前の状態とは対照的にUNSPECIFIEDに設定されていたため、ここではほとんどの回答が気に入らなかった。ProjectJourneymanはそれを考慮に入れましたが、それは素晴らしかったですが、私はロイによるロックコードを好みました。したがって、私の推奨は2つの組み合わせです。
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);
}
}
使用できます
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;
}
}
そのコード行を使用する
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
urアクティビティのoncreateメソッド