web-dev-qa-db-ja.com

Android 8.1画面の向きの問題:ポートレート画面を横向きに反転する

常に横長のビデオを再生するために使用するアクティビティを除き、すべてのアクティビティがポートレートモードで実行されます。 Android 8.1では、ビデオアクティビティを開いて閉じるたびに、マニフェストで「ポートレート」に設定されていても、前のアクティビティが横向きになることがわかりました。

  1. 時々ポートレートに移動してからランドスケープに移動し、ランドスケープにとどまることがあります。
  2. 時々、ポートレートに移動してから風景に移動し、最後にポートレートに戻ります。

これは、ランドスケープであるアクティビティから戻るときにのみ発生します。

これを経験している人はいますか?

ありがとう。

編集

Googleでバグを報告します: https://issuetracker.google.com/issues/69168442

EDIT 2

Android 9で修正されたようです

49
Sol

私自身のアプリでこの問題に出くわしました。

私のために働く解決策は次のとおりです:

onCreate(){
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  if (Android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
  }
}

onResume(){
  if (Android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

上記のコードは、ランドスケープモードのアクティビティ(つまり、2番目のアクティビティと、戻るボタンを押すアクティビティ)に配置する必要があります

この解決策は私自身のものではないことを指摘したいと思います。次のリンクの#20の投稿からそれを取り上げました(OPにも記載されています)。

https://issuetracker.google.com/issues/69168442

別のページで検索する必要がなければ、人々がアクセスしやすいと思いました。

15
TheTestSpecimen

これにより問題が修正されました。

onBackPressed()Landscape activityのメソッドをオーバーライドし、向きをPortraitに設定します。

@Override
public void onBackPressed() {
    super.onBackPressed();
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
9
Krishna

マニフェストにtheme = Theme.AppCompat.Light.DialogのようなDialogThemeがある場合、マニフェストからそのDialogアクティビティの方向設定タグを削除します。前のアクティビティからOrientationを取得し、remaingアクティビティのsetorientationタグを配置します

そして、以下のバージョンではoncreateにこれを配置します

if (Android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  }

アプリケーションTheme.AppCompat.Light.DarkActionBarのテーマを設定し、アクティビティにテーマを追加する必要はありません

4
VV W

前のアクティビティでintent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)を使用すると、問題が解決しました。

4
Luvnish Monga

親アクティビティで方向の変更をサポートする必要がある場合は、ランドスケープアクティビティのonPause()で現在の方向を使用することを検討してください。

onCreate(){
   super.onCreate();
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  super.onPause();
  if (Android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(getResources().getConfiguration().orientation);
  }
}

onResume(){
  super.onResume();
  if (Android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

この答えはTheTestSpecimen s oneに基づいています。

1
hkpogo

この問題を修正するには:

アクティビティBからアクティビティAに戻るときに、アクティビティAの画面の向きがわかっている場合は、画面の向きをアクティビティBのondestroyに設定します。

@Override
protected void onDestroy() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}
0
Narmi

各アクティビティのonCreateメソッドで、この行を挿入します

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

風景と

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

ポートレート用

0
Carlos Mion

次の回避策は、問題の解決に役立つ場合があります。

コード内のアクティビティを使用して、すべてのアクティビティを拡張する必要があります。 onPause/onResumeメソッドが呼び出されるたびに、正しい方向の設定と復元を行います。

回避策は、マニフェストアクティビティタグで定義されたあらゆるタイプの向きに対して機能します。

私自身の目的のために、このクラスをComponentActivityから拡張するため、これをActivityActivityCompat、またはその他のタイプコードで使用しているアクティビティ。

public abstract class AbsBaseActivity extends ComponentActivity
{
    private int currentActivityOrientation   = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    private int parentActivityOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

    @CallSuper
    @Override
    protected void onCreate(@Nullable final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        this.cacheOrientations();
    }

    private void cacheOrientations()
    {
        if (this.currentActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            final Intent parentIntent = this.getParentActivityIntent();

            if (parentIntent != null)
            {
                final ComponentName parentComponentName = parentIntent.getComponent();

                if (parentComponentName != null)
                {
                    this.currentActivityOrientation = this.getConfiguredOrientation(this.getComponentName());
                    this.parentActivityOrientation = this.getConfiguredOrientation(parentComponentName);
                }
            }
        }
    }

    private int getConfiguredOrientation(@NonNull final ComponentName source)
    {
        try
        {
            final PackageManager packageManager = this.getPackageManager();
            final ActivityInfo   activityInfo   = packageManager.getActivityInfo(source, 0);
            return activityInfo.screenOrientation;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }

        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    }

    @CallSuper
    @Override
    protected void onPause()
    {
        if (this.parentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.parentActivityOrientation);
        }

        super.onPause();
    }

    @CallSuper
    @Override
    protected void onResume()
    {
        super.onResume();

        if (this.currentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.currentActivityOrientation);
        }
    }
}
0
PerracoLabs

私はそのような問題を抱えており、上記のユースケースをすべて試していました。それらのほとんどは機能しますが、知っておくべきケースが1つあります。

最後の理由は、Android 8の場合のアクティビティコンテンツレイアウト内でのfragmentsの使用です。例:アクティビティはLandscapeモードで起動しますが、フラグメントにはPortraitレイアウトが表示されます。

フラグメントを避けるようにしてください。

0
Taras Vovkovych