Android 长按Menu键的监听

        看网上,大家对Home和长按Home键的监听,都有相应的监听方法,但是对于长按Menu键的监听,没有比较详细的资料,我把我的一个在launcher界面来监听长按Menu键的一个实现和大家探讨一下:


       我要实现的功能是在launcher界面,当用户长按Menu键,来执行一个XXXXXX操作。


     1.修改源码:PhoneWindowManager.java---------frameworks\base\policy\src\com\android\internal\policy\impl

     (1) 定义一个长按Menu键的标识位

    //konka	hexiaoming 20130409 start
    boolean mMenuKeyLongPressed = false;
    //konka	hexiaoming 20130409 end
    (2)重点修改interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags)方法:

       在launcher界面长按Menu,发出广播:android.intent.action.LONG_PRESS_MENU_KEY

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
        final boolean keyguardOn = keyguardOn();
        final int keyCode = event.getKeyCode();
        final int repeatCount = event.getRepeatCount();
        final int metaState = event.getMetaState();
        final int flags = event.getFlags();
        final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
        //konka	hexiaoming 20130409 start
         final boolean up = event.getAction() == KeyEvent.ACTION_UP;
        //konka	hexiaoming 20130409 end        
        final boolean canceled = event.isCanceled();

        Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
                + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed
                + " canceled=" + canceled);

        // If we think we might have a volume down & power key chord on the way
        // but we're not sure, then tell the dispatcher to wait a little while and
        // try again later before dispatching.
        if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
            if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
                final long now = SystemClock.uptimeMillis();
                final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
                if (now < timeoutTime) {
                    return timeoutTime - now;
                }
            }
            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
                    && mVolumeDownKeyConsumedByScreenshotChord) {
                if (!down) {
                    mVolumeDownKeyConsumedByScreenshotChord = false;
                }
                return -1;
            }
        }

        // First we always handle the home key here, so applications
        // can never break it, although if keyguard is on, we do let
        // it handle it, because that gives us the correct 5 second
        // timeout.
        if (keyCode == KeyEvent.KEYCODE_HOME) {
            /// M: [ALPS00054781]Dispatch the home key to the application @{
            if (win != null && win.getAttrs() != null) {
                final int flag = win.getAttrs().flags;
                if ((flag & WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED) != 0) {
                    // the window wants to handle the home key, so dispatch it to it.
                    return 0;
                }
            }
            /// @}

            // If we have released the home key, and didn't do anything else
            // while it was pressed, then it is time to go home!
            if (!down) {
                final boolean homeWasLongPressed = mHomeLongPressed;
                mHomePressed = false;
                mHomeLongPressed = false;
                if (!homeWasLongPressed) {
                    if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                        try {
                            IStatusBarService statusbar = getStatusBarService();
                            if (statusbar != null) {
                                statusbar.cancelPreloadRecentApps();
                            }
                        } catch (RemoteException e) {
                            Slog.e(TAG, "RemoteException when showing recent apps", e);
                            // re-acquire status bar service next time it is needed.
                            mStatusBarService = null;
                        }
                    }

                    mHomePressed = false;
                    if (!canceled) {
                        // If an incoming call is ringing, HOME is totally disabled.
                        // (The user is already on the InCallScreen at this point,
                        // and his ONLY options are to answer or reject the call.)
                        boolean incomingRinging = false;
                        try {
                            ITelephony telephonyService = getTelephonyService();
                            if (telephonyService != null) {
                                incomingRinging = telephonyService.isRinging();
                            }
                        } catch (RemoteException ex) {
                            Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
                        }

                        if (incomingRinging) {
                            Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
                        } else {
                            /// M:[AppLaunchTime] Improve the mechanism of AppLaunchTime
                            if (mAppLaunchTimeEnabled) Slog.i(TAG, "[AppLaunch] Home key pressed");
                            launchHomeFromHotKey();
                        }
                    } else {
                        Log.i(TAG, "Ignoring HOME; event canceled.");
                    }
                    return -1;
                }
            }

            // If a system window has focus, then it doesn't make sense
            // right now to interact with applications.
            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null) {
                final int type = attrs.type;
                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
                    // the "app" is keyguard, so give it the key
                    return 0;
                }
                final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
                for (int i=0; i<typeCount; i++) {
                    if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
                        // don't do anything, but also don't pass it to the app
                        return -1;
                    }
                }
            }
            if (down) {
                if (!mHomePressed && mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_SYSTEM_UI) {
                    try {
                        IStatusBarService statusbar = getStatusBarService();
                        if (statusbar != null) {
                            statusbar.preloadRecentApps();
                        }
                    } catch (RemoteException e) {
                        Slog.e(TAG, "RemoteException when preloading recent apps", e);
                        // re-acquire status bar service next time it is needed.
                        mStatusBarService = null;
                    }
                }
                if (repeatCount == 0) {
                    mHomePressed = true;
                } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                    if (!keyguardOn) {
                        handleLongPressOnHome();
                    }
                }
            }
            return -1;
        } else if (keyCode == KeyEvent.KEYCODE_MENU) {
            // Hijack modified menu keys for debugging features

            final int chordBug = KeyEvent.META_SHIFT_ON;
            
            //konka	hexiaoming 20130409 start
            

            if(repeatCount == 3){
            	mMenuKeyLongPressed = true;
            }
            
            Log.i("hexiaoming_debug", "repeatCount:"+repeatCount);
            Log.i("hexiaoming_debug", "mMenuKeyLongPressed:"+mMenuKeyLongPressed);
            
            
    		/**is launcher UI*************/
    		boolean isLauncherUI = false; 
    		List<String> homePackageNames = new ArrayList<String>(); //桌面应用列表 
    	    PackageManager packageManager = mContext.getPackageManager();  
    	    //属性   
    	    Intent intentL = new Intent(Intent.ACTION_MAIN);  
    	    intentL.addCategory(Intent.CATEGORY_HOME);  
    	    List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intentL,PackageManager.MATCH_DEFAULT_ONLY);  
    	    for(ResolveInfo ri : resolveInfo){  
    	    	homePackageNames.add(ri.activityInfo.packageName);  
    	    }  
    		
    		 ActivityManager mActivityManager = (ActivityManager)mContext.getSystemService(Context.ACTIVITY_SERVICE);  
    		 List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);  
    		 
    		 isLauncherUI = homePackageNames.contains(rti.get(0).topActivity.getPackageName());  
    		 
    		 Log.i("hexiaoming_debug", "isLauncherUI:"+isLauncherUI);
    		 
    		 Log.i("hexiaoming_debug", "down:"+down);
    		 Log.i("hexiaoming_debug", "up:"+up);
    		 
                      
            //if(up && mMenuKeyLongPressed){
            if(down && mMenuKeyLongPressed && isLauncherUI){
            	 		Log.i("hexiaoming_debug", "long press key:MENU");
            			Intent menuLongPress = new Intent();
						menuLongPress.setAction("android.intent.action.LONG_PRESS_MENU_KEY");
						mContext.sendBroadcast(menuLongPress);	
						mMenuKeyLongPressed = false;
						return -1;
            }else{
            
            
            if (down && repeatCount == 0) {
            //if (up && repeatCount == 0) {
            //konka	hexiaoming 20130409 end
            	Log.i("hexiaoming_debug", "press key:MENU");
            
                if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
                    Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
                    mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
                            null, null, null, 0, null, null);
                    return -1;
                } else if (SHOW_PROCESSES_ON_ALT_MENU &&
                        (metaState & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) {
                    Intent service = new Intent();
                    service.setClassName(mContext, "com.android.server.LoadAverageService");
                    ContentResolver res = mContext.getContentResolver();
                    boolean shown = Settings.Global.getInt(
                            res, Settings.Global.SHOW_PROCESSES, 0) != 0;
                    if (!shown) {
                        mContext.startService(service);
                    } else {
                        mContext.stopService(service);
                    }
                    Settings.Global.putInt(
                            res, Settings.Global.SHOW_PROCESSES, shown ? 0 : 1);
                    return -1;
                }
            }
            //konka	hexiaoming 20130410 start
          }
            //konka	hexiaoming 20130409 end


  (3)定义一个广播接收器,接收长按Menu的广播,执行XXX操作



public class MenuKeyBroadcastReceiver extends BroadcastReceiver{
	
	public final String INTENT_ACTION_LONG_PRESS_MENU_KEY = "android.intent.action.LONG_PRESS_MENU_KEY";
	
	
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
//		Intent menuLongPress = new Intent();
//		menuLongPress.setAction(INTENT_ACTION_LONG_PRESS_MENU_KEY);
//		context.sendBroadcast(menuLongPress);
		
		//long time = System.currentTimeMillis();
		 String action = intent.getAction();
		 
		/**is speech client wakeup**/
		boolean isWakeUp = Settings.System.getInt(context.getContentResolver(), "SPEECH_WAKE", 0) == 1 ? true : false;
		
		/**is launcher UI*************/
		boolean isLauncherUI = false; 
		List<String> homePackageNames = new ArrayList<String>(); //桌面应用列表 
	    PackageManager packageManager = context.getPackageManager();  
	    //属性   
	    Intent intentL = new Intent(Intent.ACTION_MAIN);  
	    intentL.addCategory(Intent.CATEGORY_HOME);  
	    List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intentL,PackageManager.MATCH_DEFAULT_ONLY);  
	    for(ResolveInfo ri : resolveInfo){  
	    	homePackageNames.add(ri.activityInfo.packageName);  
	    }  
		
		 ActivityManager mActivityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);  
		 List<RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);  
		 
		 isLauncherUI = homePackageNames.contains(rti.get(0).topActivity.getPackageName());  		
		
		if(isWakeUp == true && INTENT_ACTION_LONG_PRESS_MENU_KEY.equals(action) && isLauncherUI == true){
			
				Intent intentOpenSpeechKShow = new Intent(context, SpeechKShow.class);
				intentOpenSpeechKShow.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
	     		context.startActivity(intentOpenSpeechKShow);
	     		
	     		Log.i("hexiaoming_debug", "长按MENU键,在Launcher界面弹出康佳小兵");
		}	
	}
	
}


(4)注册长按MENU键的广播接收器

        <!-- konka-hexiaoming-Speech-20130408-start  -->
        <receiver 
            android:name=".menukeybroadcastreceiver.MenuKeyBroadcastReceiver">
				<intent-filter>  
                    <action android:name="android.intent.action.LONG_PRESS_MENU_KEY"></action>   
                </intent-filter>             
        </receiver>
           <!-- konka-hexiaoming-Speech-20130408-end  -->


PhoneWindowManager.java下载地址:

http://download.csdn.net/detail/hfreeman2011/5264516



当然还有一个就是监听所有界面的长按MENU键,这个实现参考上面的修改,只要做一点点修改就能OK噢,亲,你自己来修改验证一下吧!!!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值