Android · 2016年1月15日 0

Android获取手机底部虚拟按键高度

获取手机底部虚拟键盘的高度
魅族手机底部SmartBar高度

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewConfiguration;
import android.view.WindowManager;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

                Log.e(MainActivity.class.getName(), "hasNavBar1 = " + hasNavBar(MainActivity.this));
            }
        });
        Log.e(MainActivity.class.getName(),"ScreenHeight = "+getScreenHight());
        Log.e(MainActivity.class.getName(),"SmartBarHeight = "+getSmartBarHeight(this));
        Log.e(MainActivity.class.getName(),"hasNavBar = "+hasNavBar(this));

        Log.e(MainActivity.class.getName(),"getNavigationBarHeight = "+getNavigationBarHeight(this));
    }




    private int getScreenHight(){
        // 获取屏幕高
        Point point = new Point();
        getWindowManager().getDefaultDisplay().getSize(point);
        int screenHeight = point.y + (isMeizu() ? 0 : getNavigationBarHeight(this));

        return screenHeight;
    }

    /**
     * 获取虚拟按键栏高度
     * @param context
     * @return
     */
    public static int getNavigationBarHeight(Context context) {
        int result = 0;
        if (hasNavBar(context)){
            Resources res = context.getResources();
            int resourceId = res.getIdentifier("navigation_bar_height", "dimen", "android");
            if (resourceId > 0) {
                result = res.getDimensionPixelSize(resourceId);
            }
        }
        return result;
    }

    /**
     * 检查是否存在虚拟按键栏
     * @param context
     * @return
     */
    private static boolean hasNavBar(Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            boolean hasNav = res.getBoolean(resourceId);
            // check override flag
            String sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else { // fallback
            return !ViewConfiguration.get(context).hasPermanentMenuKey();
        }
    }


    /**
     * 判断虚拟按键栏是否重写
     * @return
     */
    private static String getNavBarOverride() {
        String sNavBarOverride = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method m = c.getDeclaredMethod("get", String.class);
                m.setAccessible(true);
                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
            } catch (Throwable e) {
            }
        }
        return sNavBarOverride;
    }


    /**
     * 判断是否meizu手机
     * @return
     */
    public static boolean isMeizu() {
        return Build.BRAND.equals("Meizu");
    }


    /**
     * 获取魅族手机底部虚拟键盘高度
     * @param context
     * @return
     */
    public static int getSmartBarHeight(Context context)
    {
        try {
            Class c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("mz_action_button_min_height");
            int height = Integer.parseInt(field.get(obj).toString());
            return context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
}






import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.ActionBar;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class SmartBarUtils {
public static final int SMART_BAR_HEIGH = 96;
/**
* 调用 ActionBar.setTabsShowAtBottom(boolean) 方法。 如果
* android:uiOptions=”splitActionBarWhenNarrow”,则可设置ActionBar Tabs显示在底栏。
*
* 示例: public class MyActivity extends Activity implements
* ActionBar.TabListener { protected void onCreate(Bundle
* savedInstanceState) { super.onCreate(savedInstanceState); …
*
* final ActionBar bar = getActionBar();
* bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
* SmartBarUtils.setActionBarTabsShowAtBottom(bar, true);
*
* bar.addTab(bar.newTab().setText("tab1").setTabListener(this));
* … } }
*
*/
public static void setActionBarTabsShowAtBottom(ActionBar actionbar,
boolean showAtBottom) {
try {
Method method = Class.forName(android.app.ActionBar).getMethod(
setTabsShowAtBottom, new Class[] { boolean.class });
try {
method.invoke(actionbar, showAtBottom);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 调用 ActionBar.setActionBarViewCollapsable(boolean) 方法。
* 设置ActionBar顶栏无显示内容时是否隐藏。
*
* 示例:
*
* public class MyActivity extends Activity {
*
* protected void onCreate(Bundle savedInstanceState) {
* super.onCreate(savedInstanceState); …
*
* final ActionBar bar = getActionBar();
*
* // 调用setActionBarViewCollapsable,并设置ActionBar没有显示内容,则ActionBar顶栏不显示
* SmartBarUtils.setActionBarViewCollapsable(bar, true);
* bar.setDisplayOptions(0); } }
*/
public static void setActionBarViewCollapsable(ActionBar actionbar,
boolean collapsable) {
try {
Method method = Class.forName(android.app.ActionBar).getMethod(
setActionBarViewCollapsable,
new Class[] { boolean.class });
try {
method.invoke(actionbar, collapsable);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 调用 ActionBar.setActionModeHeaderHidden(boolean) 方法。 设置ActionMode顶栏是否隐藏。
*
* public class MyActivity extends Activity {
*
* protected void onCreate(Bundle savedInstanceState) {
* super.onCreate(savedInstanceState); …
*
* final ActionBar bar = getActionBar();
*
* // ActionBar转为ActionMode时,不显示ActionMode顶栏
* SmartBarUtils.setActionModeHeaderHidden(bar, true); } }
*/
public static void setActionModeHeaderHidden(ActionBar actionbar,
boolean hidden) {
try {
Method method = Class.forName(android.app.ActionBar).getMethod(
setActionModeHeaderHidden, new Class[] { boolean.class });
try {
method.invoke(actionbar, hidden);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 原隐藏SmartBar的方法
* 此方法已从Flyme2.4.1开始失效 示例:
*
* final ActionBar actionBar = getActionBar(); SmartBarUtils.hide(this);
*
*/
@Deprecated
public static final void hide(FragmentActivity activity) {
ActionBar actionBar = activity.getActionBar();
if (actionBar == null) {
return;
}
Class<? extends ActionBar> ActionBarClass = actionBar.getClass();
Method setTabsShowAtBottom;
try {
setTabsShowAtBottom = ActionBarClass.getMethod(
setTabsShowAtBottom, Boolean.TYPE);
setTabsShowAtBottom.invoke(activity.getActionBar(), true);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/**
* 以下三个方法原作者为c跳跳(http://weibo.com/u/1698085875),
* 由Shawn(http://weibo.com/linshen2011)在其基础上改进了一种判断SmartBar是否存在的方法,
* 注意该方法反射的接口只存在于2013年6月之后魅族的flyme固件中
*/
/**
* 方法一:uc等在使用的方法(新旧版flyme均有效),
* 此方法需要配合requestWindowFeature(Window.FEATURE_NO_TITLE
* )使用,缺点是程序无法使用系统actionbar
*
* @param decorView
* window.getDecorView
*/
public static void hide(View decorView) {
if (!hasSmartBar())
return;
try {
@SuppressWarnings(rawtypes)
Class[] arrayOfClass = new Class[1];
arrayOfClass[0] = Integer.TYPE;
Method localMethod = View.class.getMethod(setSystemUiVisibility,
arrayOfClass);
Field localField = View.class
.getField(SYSTEM_UI_FLAG_HIDE_NAVIGATION);
Object[] arrayOfObject = new Object[1];
try {
arrayOfObject[0] = localField.get(null);
} catch (Exception e) {
}
localMethod.invoke(decorView, arrayOfObject);
return;
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方法二:此方法需要配合requestWindowFeature(Window.FEATURE_NO_TITLE)使用
* ,缺点是程序无法使用系统actionbar
*
* @param context
* @param window
*/
public static void hide(Context context, Window window) {
hide(context, window, 0);
}
private static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier(
status_bar_height, dimen, android);
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
/**
* 方法三:需要使用顶部actionbar的应用请使用此方法
*
* @param context
* @param window
* @param smartBarHeight
* set SmartBarUtils.SMART_BAR_HEIGHT_PIXEL
*/
public static void hide(Context context, Window window, int smartBarHeight) {
if (!hasSmartBar()) {
return;
}
if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
return;
}
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
int statusBarHeight = getStatusBarHeight(context);
window.getDecorView()
.setPadding(0, statusBarHeight, 0, smartBarHeight);
}
/**
* 新型号可用反射调用Build.hasSmartBar()来判断有无SmartBar
* @return
*/
public static boolean hasSmartBar() {
try {
Method method = Class.forName(android.os.Build).getMethod(
hasSmartBar);
return ((Boolean) method.invoke(null)).booleanValue();
} catch (Exception e) {
}
if (Build.DEVICE.equals(mx2)) {
return true;
} else if (Build.DEVICE.equals(mx) || Build.DEVICE.equals(m9)) {
return false;
}
return false;
}
}

Share this: