web-dev-qa-db-ja.com

Android(変更)

キオスクモードアプリケーションを実装していますが、4.3以降のステータスバーの表示なしでアプリケーションを全画面表示できましたが、画面上部を下にスワイプするとステータスバーが表示されるため、4.3および4.4ではステータスバーを非表示にできません。

私はそれをフルスクリーンにしようとしました

  • マニフェストで全画面テーマを指定する
  • 設定ウィンドウのフラグ、つまりsetFlags
  • setSystemUiVisibility

重複する可能性があるが、具体的な解決策は見つからない

永続的に非表示Androidステータスバー

最後に私が欲しいのは、アクティビティでステータスバーを永久に隠す方法ですか?? in Android 4.3,4.4,5,6versions

26
Abhimaan

KitKatデバイスでは、フルスクリーンモードでステータスが表示されるのを防ぐことができなかったため、要件に合ったハックを作成しました。つまり、ステータスバーの拡張をブロックしました。

それが機能するために、アプリは全画面表示されませんでした。ステータスバーにオーバーレイを配置し、すべての入力イベントを消費しました。ステータスの拡大を防ぎました。

注:

  • customViewGroupは、任意のレイアウト(フレーム、相対レイアウトなど)を拡張し、タッチイベントを消費するカスタムクラスです。
  • タッチイベントを消費するには、ビューグループのonInterceptTouchEventメソッドをオーバーライドし、trueを返します。

更新済み

<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW"/> 

customViewGroup実装

コード:

WindowManager manager = ((WindowManager) getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
localLayoutParams.gravity = Gravity.TOP;
localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE|

            // this is to enable the notification to recieve touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (50 * getResources()
            .getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    customViewGroup view = new customViewGroup(this);

    manager.addView(view, localLayoutParams);
86
Abhimaan

Android Mでは、オーバーレイを作成するための追加の許可を取得する必要があります。Android.permission.SYSTEM_ALERT_WINDOWでは十分ではありません!そこで、disableStatusBar()適切な設定ダイアログを開くことを意図しなければなりませんでした。また、アプリの終了時にステータスバーを有効にするためにonDestroy()にビューを削除する機能を追加しました。コードは、ここで5.1および6.0で動作します。

public static final int OVERLAY_PERMISSION_REQ_CODE = 4545;
protected CustomViewGroup blockingView = null;

@Override
protected void onDestroy() {

    super.onDestroy();

    if (blockingView!=null) {
        WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
        manager.removeView(blockingView);
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {

        if (Android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            if (!Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "Please give my app this permission!", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, OVERLAY_PERMISSION_REQ_CODE);
            } else {
                disableStatusBar();
            }
        }
        else {
            disableStatusBar();
        }
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            Toast.makeText(this, "User can access system settings without this permission!", Toast.LENGTH_SHORT).show();
        }
        else
        { disableStatusBar();
        }
    }
}

protected void disableStatusBar() {

    WindowManager manager = ((WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE));

    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    localLayoutParams.height = (int) (40 * getResources().getDisplayMetrics().scaledDensity);
    localLayoutParams.format = PixelFormat.TRANSPARENT;

    blockingView = new CustomViewGroup(this);
    manager.addView(blockingView, localLayoutParams);
}
17
Alexey Ozerov

私が取り組んだプロジェクトでは、この解決策を見つけましたが、長い時間がかかりました。 Stackoverflowや他の場所のさまざまなスレッドは、私がそれを思い付くのに役立ちました。 Android Mの回避策でしたが、完全に機能しました。誰かがそれを求めたので、誰かに利益をもたらすことができるなら、ここに投稿すべきだと思いました。

しばらくして、すべての詳細を覚えていませんが、CustomViewGroupはメインViewGroupをオーバーライドするクラスであり、ユーザーがステータスバーを表示するために上からスワイプしたことを検出します。しかし、表示したくなかったため、ユーザーのインターセプトが検出され、それ以降のアクションはすべて無視されました。つまり、Android OSは非表示のステータスバーを開く信号を取得しません。

そして、ステータスバーを表示/非表示にするメソッドも含まれており、ステータスバーを表示/非表示にするコードにそのままコピー/貼り付けできます。

/**
 * This class creates the overlay on the status bar which stops it from expanding.
 */
public static class CustomViewGroup extends ViewGroup {

    public CustomViewGroup(Context context) {
        super(context);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.v("customViewGroup", "********** Status bar swipe intercepted");
        return true;
    }
}

public static void allowStatusBarExpansion(Context context) {
    CustomViewGroup view = new CustomViewGroup(context);
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));
    manager.removeView(view);
}

// Stop expansion of the status bar on swipe down.
public static void preventStatusBarExpansion(Context context) {
    WindowManager manager = ((WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE));

    Activity activity = (Activity) context;
    WindowManager.LayoutParams localLayoutParams = new WindowManager.LayoutParams();
    localLayoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
    localLayoutParams.gravity = Gravity.TOP;
    localLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |

            // this is to enable the notification to receive touch events
            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |

            // Draws over status bar
            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;

    localLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
    //http://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels
    int resId = activity.getResources().getIdentifier("status_bar_height", "dimen", "Android");
    int result = 0;
    if (resId > 0) {
        result = activity.getResources().getDimensionPixelSize(resId);
    }

    localLayoutParams.height = result;

    localLayoutParams.format = PixelFormat.TRANSPARENT;

    CustomViewGroup view = new CustomViewGroup(context);

    manager.addView(view, localLayoutParams);
}
0
zeeshan