android手机虚拟按钮开发有关问题点

android手机虚拟按钮开发问题点

         最近做了手机虚拟按钮开发,和华为荣耀的虚拟按钮类似,效果如下(屏幕底下部分):

android手机虚拟按钮开发有关问题点


       功能描述:手机开机,“虚拟按钮”自动隐藏,当从手机下边沿往上滑动时候,就自动出现! 没有操作的话,3秒就自动消失。

       要实现这个功能需要解决这几个问题:(1)如何让其在手机开机的时候启动;(2)如何能在任何界面都能够响应手机使用者需要“虚拟按钮”的意图,并且弹出“虚拟按钮”;(3)如何检测使用者从手机下边沿往上滑动的事件;(4)如何模拟真实的home_key, menu_key和return_key事件。

      下面一个一个的来解决这几个问题:

      (1)如何让其在手机开机的时候启动:

                这简单,定义一个receiver,其action为:android.intent.action.BOOT_COMPLETED这样就可以了。不过,你会发现手机开机完成后起码有一个较长的延时我们定义的action来能接收到!

      (2)要在任何界面都能出现“虚拟按钮”,并且能做一些事情,很显然我们需要一个Service,这里我的Service是:NavBarService。在所有界面都能出现“虚拟按钮”,我们就只能用WindowManager,我们都知道可以用WindowManager来实现悬浮窗口,其实我们“虚拟按钮”就是一个悬浮view.

       首先通过以下代码获取WindowManager的实列:WindowManager wm;

wm = (WindowManager)mContext.getSystemService("window");
         后面把我们布局好的view(LinearLayout holder;)添加上去就可以了:

wm.addView(holder, layoutparams);
         这里的LinearLayout holder;就是采用了一个LinearLayout来布局的!里面已经布局好了三个按钮:return按钮; home按钮;menu按钮。

        这里我们要注意的是第二个参数:layoutparams

            	WindowManager.LayoutParams layoutparams = new WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT);
            	layoutparams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
            	layoutparams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                	    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
            	layoutparams.format = PixelFormat.TRANSLUCENT;
     (3)如何检测使用者从手机下边沿往上滑动的事件;

        这个简单!就是用wm.addView添加一个简单view, 其view设置为全部透明的!并且高度只需要15dip,将这个view放置于屏幕的底部。用该view来检测使用者往上滑动的意图。

     所以最后就形成了该全部透明的view和上面提到的三个按钮的view(holder)    相互切换,切换时候用WindowManager的renove来移除暂时不需要的view就可以了,如这样: wm.removeView(holder);         

      (4)如何模拟真实的home_key, menu_key和return_key事件。

         首先通过三个按钮view的setOnLongClickListenerset和setOnClickListener来监听长按和短按事件!接下来就是如何模拟真实按键的方法,这里采用的是Instrumentation

    public static void home_LongDown() {
      // Log.i(TAG, "home home_LongDown  SystemClock.uptimeMillis()="+SystemClock.uptimeMillis());

       new Thread() {
            public void run() {
                try {
					KeyEvent ev = new KeyEvent(SystemClock.uptimeMillis()-100, SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HOME, 1,
							0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
							KeyEvent.FLAG_LONG_PRESS | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
							InputDevice.SOURCE_KEYBOARD);

                    new Instrumentation().sendKeySync(ev);
                   // Log.i(TAG, "home_LongDown");
                    return;
                } catch (Exception e) {
                    Log.d(TAG, e.toString());
                }
            }
        }.start();

		//playSoundEffect(android.view.SoundEffectConstants.CLICK);
    }


    public static void home_click() {
        //Log.i(TAG, "home click");
        //playSoundEffect(android.view.SoundEffectConstants.CLICK);
        new Thread() {
            public void run() {
                try {
                    new Instrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_HOME);
                  //  Log.i(TAG, "Home");
                    return;
                } catch (Exception e) {
                    Log.d(TAG, e.toString());
                }
            }
        }.start();
    }

     上面的代码就是模拟home-key长按和短按事件的代码!其他的menu-key和return-key是一样的