始终禁用自定义启动器中的状态栏和底部栏
Always disable status bar and bottom bar in a custom launcher
我需要编写自定义 android 启动器,只有一个我的应用程序并禁用 android 系统状态栏和底部栏。这是我的代码
在AndroidManifest.xml
<activity android:name=".MainActivity"
android:launchMode="singleTask"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
在styles.xml
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
ins MainActivity.class
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideSystemUi()
buttonStartMyApp.setOnClickListener {
Toast.makeText(this@MainActivity, "Start own app", Toast.LENGTH_SHORT).show()
}
}
private fun hideSystemUi() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
这个启动器启动时只有一个按钮(没问题),没有状态栏和底部导航栏。但是我们可以通过在屏幕顶部自上而下滑动来获取它们。如何禁用此功能?谢谢。
您已经实现了 IMMERSIVE_STICKY
标志,它允许通过 top-down 在屏幕顶部滑动来调用状态栏。要禁用此功能:
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
setContentView(R.layout.your_layout);
要禁用状态下拉,请使用此方法。这是覆盖状态栏并消耗所有输入事件。它阻止状态扩展。
注:
customViewGroup
是自定义的 class,它扩展任何布局(框架、相对布局等)并消耗触摸事件。
要使用触摸事件,请覆盖视图组的 onInterceptTouchEvent 方法和 return true.
Android 清单
<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);
运行 一个服务在后台并且总是关闭状态栏。对于奥利奥及以上,这是我找到的唯一一种解决方案。对于以下版本,我们可以使用上面的答案。
package your.package;
import java.lang.reflect.Method;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
public class ServiceCloseBar extends Service {
private static Timer timer;
private static TimerTask task;
private static int TIME_INTERVAL=100;
@Override
public void onCreate() {
super.onCreate();
try {
timer=new Timer();
task = new TimerTask() {
public void run() {
try {
Object sbservice = getSystemService( "statusbar" );
Class<?> statusbarManager = Class.forName( "android.app.StatusBarManager" );
Method expandMethod;
if (Build.VERSION.SDK_INT >= 17) {
expandMethod = statusbarManager.getMethod("collapsePanels");
} else {
expandMethod = statusbarManager.getMethod("collapse");
}
expandMethod .invoke( sbservice );
} catch (Exception e) {
};
}
};
timer.scheduleAtFixedRate(task, 0, TIME_INTERVAL);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
我需要编写自定义 android 启动器,只有一个我的应用程序并禁用 android 系统状态栏和底部栏。这是我的代码
在AndroidManifest.xml
<activity android:name=".MainActivity"
android:launchMode="singleTask"
android:stateNotNeeded="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
在styles.xml
<item name="android:windowShowWallpaper">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
ins MainActivity.class
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
hideSystemUi()
buttonStartMyApp.setOnClickListener {
Toast.makeText(this@MainActivity, "Start own app", Toast.LENGTH_SHORT).show()
}
}
private fun hideSystemUi() {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
}
这个启动器启动时只有一个按钮(没问题),没有状态栏和底部导航栏。但是我们可以通过在屏幕顶部自上而下滑动来获取它们。如何禁用此功能?谢谢。
您已经实现了 IMMERSIVE_STICKY
标志,它允许通过 top-down 在屏幕顶部滑动来调用状态栏。要禁用此功能:
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY);
setContentView(R.layout.your_layout);
要禁用状态下拉,请使用此方法。这是覆盖状态栏并消耗所有输入事件。它阻止状态扩展。
注:
customViewGroup
是自定义的 class,它扩展任何布局(框架、相对布局等)并消耗触摸事件。
要使用触摸事件,请覆盖视图组的 onInterceptTouchEvent 方法和 return true.
Android 清单
<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);
运行 一个服务在后台并且总是关闭状态栏。对于奥利奥及以上,这是我找到的唯一一种解决方案。对于以下版本,我们可以使用上面的答案。
package your.package;
import java.lang.reflect.Method;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
public class ServiceCloseBar extends Service {
private static Timer timer;
private static TimerTask task;
private static int TIME_INTERVAL=100;
@Override
public void onCreate() {
super.onCreate();
try {
timer=new Timer();
task = new TimerTask() {
public void run() {
try {
Object sbservice = getSystemService( "statusbar" );
Class<?> statusbarManager = Class.forName( "android.app.StatusBarManager" );
Method expandMethod;
if (Build.VERSION.SDK_INT >= 17) {
expandMethod = statusbarManager.getMethod("collapsePanels");
} else {
expandMethod = statusbarManager.getMethod("collapse");
}
expandMethod .invoke( sbservice );
} catch (Exception e) {
};
}
};
timer.scheduleAtFixedRate(task, 0, TIME_INTERVAL);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}