私の主な活動には、中断してはならないデータベースの変更を行うコードがあります。私は別のスレッドで重労働を行っており、キャンセル不可に設定した進行状況ダイアログを使用しています。ただし、携帯電話を回転させると、実行中のプロセスにとって非常に悪いアクティビティが再開され、強制終了されることに気付きました。
私がやりたいことは、プロセスが完了するまで画面の向きの変更をプログラムで無効にすることです。プロセスが完了すると、向きの変更が有効になります。
私の主な活動には、中断してはならないデータベースの変更を行うコードがあります。私は別のスレッドで重労働を行っており、キャンセル不可に設定した進行状況ダイアログを使用しています。ただし、携帯電話を回転させると、実行中のプロセスにとって非常に悪いアクティビティが再開され、強制終了されることに気付きました。
私がやりたいことは、プロセスが完了するまで画面の向きの変更をプログラムで無効にすることです。プロセスが完了すると、向きの変更が有効になります。
クリスが自己回答で説明したように、
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
その後
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
本当に魅力的に機能します...実際のデバイスで!
エミュレーターでテストするときに壊れているとは思わないでください。ctrl + F11 ショートカットは、センサーの動きをエミュレートすることなく、常に画面の向きを変更します。
編集:これは可能な限り最良の答えではありませんでした。コメントで説明されているように、この方法には問題があります。本当の答えはここにあります。
他の答えはどれも私にとって完璧なトリックではありませんでしたが、これが私が見つけたものです。
現在の方向にロック...
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
向きの変更を再度許可する必要がある場合は、デフォルトに戻します...
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
これは、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);
}
}
逆向きモードも管理するために、そのコードを使用してアクティビティの向きを修正しました。
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 =センサーなし)、スレッドが終了したら電話をかけましたsetRequestedOrientation(ON)
(ON =センサー)。チャームのように機能します。
皆さんありがとう。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);
}
アンロックでは、以前の状態とは対照的に UNSPECIFIED に設定されているため、ここでの回答のほとんどは気に入りませんでした。ProjectJourneyman はそれを考慮に入れましたが、それは素晴らしいことでしたが、私は Roy によるロック コードの方が好みでした。したがって、私の推奨事項は、次の 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);
}
}
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 );
}
ディスプレイの回転に依存し、デバイスの向きを決定するソリューションを思いつきました。向きを知ることで、向きをロックし、必要に応じて後で解放できます。このソリューションは、デバイスが逆ランドスケープモードであるかどうかも判断できます。
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);
そのコード行を使用する
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
あなたの活動のoncreateメソッドで