Запретить строку состояния для появления андроида (изменено)
Я использую приложение режима киоска, и я успешно сделал приложение полноэкранным без появления строки состояния 4.3, но не смог скрыть строку состояния в 4.3 и 4.4, поскольку строка состояния появляется, когда мы прокручиваем вверх в верхней части экран.
Я попытался сделать это на весь экран
- определение полноэкранной темы в манифесте
- установочное окно Flags ie setFlags
- setSystemUiVisibility
Возможное дублирование, но не найдено конкретного решения
Постоянно скрывать строку состояния Android
Наконец то, что я хочу, как скрывать статус-бар постоянно в активности? в android 4.3,4.4,5,6versions
Ответы
Ответ 1
Мы не смогли предотвратить появление статуса в полноэкранном режиме на устройствах kitkat, поэтому сделали взломать, который по-прежнему соответствует требованию, т.е. блокировать расширение строки состояния.
Для этого приложение не было в полноэкранном режиме. Мы помещаем оверлей поверх строки состояния и потребляем все входные события. Это предотвратило расширение статуса.
Примечание:
- customViewGroup - это настраиваемый класс, который расширяет любые
макет (рамка, относительный макет и т.д.) и потребляет событие касания.
- чтобы использовать событие touch, переопределить метод 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);
Ответ 2
В Android M вам нужно получить дополнительное разрешение на создание оверлеев. android.permission.SYSTEM_ALERT_WINDOW
недостаточно! Поэтому я использовал код из ответа Abhimaan в disableStatusBar()
и должен был сделать намерение открыть правильный диалог настроек. Я также добавил удаление представления в onDestroy()
, чтобы включить строку состояния, когда приложение выходит. Я также уменьшил высоту наложения до 40, как кажется, достаточно. Код работает здесь с 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);
}
Ответ 3
Для проекта, над которым я работал, я нашел решение для этого, но это заняло много времени. Различные темы на Stackoverflow и в других местах помогли мне придумать это. Это был обходной путь на Android M, но он работал отлично. Как кто-то просил об этом, так что я подумал, что я должен опубликовать это здесь, если это может кому-нибудь помочь
Теперь, когда прошло некоторое время, я не помню всех деталей, но CustomViewGroup - это класс, который переопределяет основную ViewGroup и обнаруживает, что пользователь провел пальцем сверху, чтобы показать строку состояния. Но мы не хотели показывать это, поэтому пользовательский перехват был обнаружен, и любые дальнейшие действия были проигнорированы, то есть ОС Android не получит сигнал, чтобы открыть скрытую строку состояния.
А затем включены методы отображения и скрытия строки состояния, которые вы можете копировать/вставлять, как есть в вашем коде, где вы хотите показать/скрыть строку состояния.
/**
* 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/info/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);
}