其实,假如我们能够获取系统服务WindowManagerService在应用进程的代理的话,直接调用其hasNavigationBar方法来判断,是不是会更简单呢?但问题是如何获取WindowManagerService在应用进程的代理呢?
查阅源码,我们发现,android.view.WindowManagerGlobal中有一个静态方法就是获取WindowManagerService在本地的代理实现:
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.class) {
if (sWindowManagerService == null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("window"));
try {
if (sWindowManagerService != null) {
ValueAnimator.setDurationScale(
sWindowManagerService.getCurrentAnimatorScale());
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowManagerService;
}
}
因此,我们可以通过反射调用此方法获取IWindowManager,再调用IWindowManager的hasNavigationBar方法来判断NavigationBar存在与否,具体请看代码:
/**
* 判断设备是否存在NavigationBar
*
* @return true 存在, false 不存在
*/
public static boolean deviceHasNavigationBar() {
boolean haveNav = false;
try {
//1.通过WindowManagerGlobal获取windowManagerService
// 反射方法:IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
Class<?> windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal");
Method getWmServiceMethod = windowManagerGlobalClass.getDeclaredMethod("getWindowManagerService");
getWmServiceMethod.setAccessible(true);
//getWindowManagerService是静态方法,所以invoke null
Object iWindowManager = getWmServiceMethod.invoke(null);
//2.获取windowMangerService的hasNavigationBar方法返回值
// 反射方法:haveNav = windowManagerService.hasNavigationBar();
Class<?> iWindowManagerClass = iWindowManager.getClass();
Method hasNavBarMethod = iWindowManagerClass.getDeclaredMethod("hasNavigationBar");
hasNavBarMethod.setAccessible(true);
haveNav = (Boolean) hasNavBarMethod.invoke(iWindowManager);
} catch (Exception e) {
e.printStackTrace();
}
return haveNav;
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/sanxing/article-66607-5.html
国家连年扩招