在Android 2.3状态栏中添加menu,home和back快捷键的方法

在Android 2.3状态栏中添加menu,home和back快捷键的方法

1、准备资源,修改XML文
准备几张图,这里我们准备添加home back和menu图标,就需要准备6张图,三张普通状态,三张按下的高亮状态图标:
stat_home.png
stat_home_pressed.png
stat_back.png
stat_back_pressed.png
stat_menu.png
stat_menu_pressed.png
把它们放在frameworks/base/packages/SystemUI/res/drawable/目录下
同时,在frameworks/base/packages/SystemUI/res/drawable 下创建三个imageButton的xml文件
xml_stat_home.xml

1.      <?xml  version = "1.0"  encoding = "utf-8" ?>    
2.      <selector    
3.           xmlns:android = "http://schemas.android.com/apk/res/android" >    
4.           <item    
5.               android:state_focused = "true"    
6.               android:state_pressed = "false"    
7.               android:drawable = "@drawable/stat_home"  />    
8.           <item    
9.               android:state_focused = "true"    
10.            android:state_pressed = "true"    
11.            android:drawable = "@drawable/stat_home_pressed"  />    
12.        <item    
13.            android:state_focused = "false"    
14.            android:state_pressed = "true"    
15.            android:drawable = "@drawable/stat_home_pressed"  />    
16.        <item    
17.            android:drawable = "@drawable/stat_home"  />    
18.   </selector> 



 xml_stat_back.xml

1.      <?xml version="1.0" encoding="utf-8"?>   
2.      <selector   
3.          xmlns:android="http://schemas.android.com/apk/res/android">   
4.          <item   
5.              android:state_focused="true"   
6.              android:state_pressed="false"   
7.              android:drawable="@drawable/stat_back" />   
8.          <item   
9.              android:state_focused="true"   
10.           android:state_pressed="true"   
11.           android:drawable="@drawable/stat_back_pressed" />   
12.       <item   
13.           android:state_focused="false"   
14.           android:state_pressed="true"   
15.           android:drawable="@drawable/stat_back_pressed" />   
16.       <item   
17.           android:drawable="@drawable/stat_back" />   
18.   </selector>    

xml_stat_menu.xml

1.      <?xml  version = "1.0"  encoding = "utf-8" ?>    
2.      <selector    
3.           xmlns:android = "http://schemas.android.com/apk/res/android" >    
4.           <item    
5.               android:state_focused = "true"    
6.               android:state_pressed = "false"    
7.               android:drawable = "@drawable/stat_menu"  />    
8.           <item    
9.               android:state_focused = "true"    
10.            android:state_pressed = "true"    
11.            android:drawable = "@drawable/stat_menu_pressed"  />    
12.        <item    
13.            android:state_focused = "false"    
14.            android:state_pressed = "true"    
15.            android:drawable = "@drawable/stat_menu_pressed"  />    
16.        <item    
17.            android:drawable = "@drawable/stat_menu"  />    
18.   </selector>    

修改status_bar.xml成如下
目录:frameworks/base/packages/SystemUI/res/layout/status_bar.xml

1.       <?xml version="1.0" encoding="utf-8"?>
2.       <!--
3.       /* apps/common/assets/default/default/skins/StatusBar.xml
4.       **
5.       ** Copyright 2006, The Android Open Source Project
6.       **
7.       ** Licensed under the Apache License, Version 2.0 (the "License");
8.       ** you may not use this file except in compliance with the License.
9.       ** You may obtain a copy of the License at
10.     **
11.     **     http://www.apache.org/licenses/LICENSE-2.0
12.     **
13.     ** Unless required by applicable law or agreed to in writing, software
14.     ** distributed under the License is distributed on an "AS IS" BASIS,
15.     ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16.     ** See the License for the specific language governing permissions and
17.     ** limitations under the License.
18.     */
19.     -->
20.      
21.     <!--    android:background="@drawable/status_bar_closed_default_background" -->
22.     <com.android.systemui.statusbar.StatusBarView
23.         xmlns:android="http://schemas.android.com/apk/res/android"
24.         android:background="@drawable/statusbar_background"
25.         android:orientation="vertical"
26.         android:focusable="true"
27.         android:descendantFocusability="afterDescendants"
28.         >
29.      
30.         <LinearLayout android:id="@+id/icons"
31.             android:layout_width="match_parent"
32.             android:layout_height="match_parent"
33.             android:orientation="horizontal">              
34.             <com.android.systemui.statusbar.IconMerger android:id="@+id/notificationIcons"
35.                 android:layout_width="0dip"
36.                 android:layout_weight="1"
37.                 android:layout_height="match_parent"
38.                 android:layout_alignParentLeft="true"
39.                 android:paddingLeft="6dip"
40.                 android:gravity="center_vertical"
41.                 android:orientation="horizontal"/> 
42.                 
43.             <LinearLayout android:id="@+id/statusIcons"
44.                 android:layout_width="wrap_content"
45.                 android:layout_height="match_parent"
46.                 android:layout_alignParentRight="true"
47.                 android:paddingRight="6dip"
48.                 android:gravity="center_vertical"
49.                 android:orientation="horizontal"/>   
50.     <ImageButton android:id="@+id/go_home" 
51.            android:layout_width="32px" 
52.            android:layout_height="32px" 
53.            android:layout_alignParentLeft="true"
54.                     android:paddingLeft="10dip"
55.            android:paddingTop="10dip"
56.                     android:gravity="center_vertical"
57.            android:clickable="true"  
58.            android:background="@drawable/xml_stat_home" 
59.            />  
60.       <ImageButton android:id="@+id/pop_menu" 
61.            android:layout_width="32px" 
62.            android:layout_height="32px" 
63.            android:layout_alignParentRight="true"
64.             android:paddingLeft="10dip"
65.            android:paddingTop="10dip"
66.             android:gravity="center_vertical"
67.             android:orientation="horizontal" 
68.            android:clickable="true"  
69.            android:background="@drawable/xml_stat_menu" 
70.            />         
71.       <ImageButton android:id="@+id/go_back" 
72.            android:layout_width="32px" 
73.            android:layout_height="32px" 
74.            android:layout_alignParentRight="true"
75.             android:paddingLeft="10dip"
76.            android:paddingTop="10dip"
77.             android:gravity="center_vertical"
78.             android:orientation="horizontal" 
79.            android:clickable="true"  
80.            android:background="@drawable/xml_stat_back" 
81.            />                  
82.             <com.android.systemui.statusbar.Clock
83.                 android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
84.                 android:layout_width="wrap_content"
85.                 android:layout_height="match_parent"
86.                 android:singleLine="true"
87.                 android:paddingRight="6dip"
88.                 android:gravity="center_vertical|left"
89.                 />
90.         </LinearLayout>
91.             
92.         <LinearLayout android:id="@+id/ticker"
93.             android:layout_width="match_parent"
94.             android:layout_height="match_parent"
95.             android:paddingLeft="6dip"
96.             android:animationCache="false"
97.             android:orientation="horizontal" >
98.             <ImageSwitcher android:id="@+id/tickerIcon"
99.                 android:layout_width="wrap_content"
100.              android:layout_height="match_parent"
101.              android:layout_marginRight="8dip"
102.              >
103.              <com.android.systemui.statusbar.AnimatedImageView
104.                  android:layout_width="25dip"
105.                  android:layout_height="25dip"
106.                  />
107.              <com.android.systemui.statusbar.AnimatedImageView
108.                  android:layout_width="25dip"
109.                  android:layout_height="25dip"
110.                  />
111.          </ImageSwitcher>
112.          <com.android.systemui.statusbar.TickerView android:id="@+id/tickerText"
113.              android:layout_width="0dip"
114.              android:layout_weight="1"
115.              android:layout_height="wrap_content"
116.              android:paddingTop="2dip"
117.              android:paddingRight="10dip">
118.              <TextView
119.                  android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
120.                  android:layout_width="match_parent"
121.                  android:layout_height="wrap_content"
122.                  android:singleLine="true"
123.                  />
124.              <TextView
125.                  android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
126.                  android:layout_width="match_parent"
127.                  android:layout_height="wrap_content"
128.                  android:singleLine="true"
129.                  />
130.          </com.android.systemui.statusbar.TickerView>
131.      </LinearLayout>
132.   
133.      <com.android.systemui.statusbar.DateView android:id="@+id/date"
134.          android:textAppearance="@*android:style/TextAppearance.StatusBar.Icon"
135.          android:layout_width="wrap_content"
136.          android:layout_height="match_parent"
137.          android:singleLine="true"
138.          android:gravity="center_vertical|left"
139.          android:paddingLeft="6px"
140.          android:paddingRight="6px"
141.          android:background="@drawable/statusbar_background"
142.          />
143.  </com.android.systemui.statusbar.StatusBarView> 


二 为按钮添加动态效果
修改frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java
在类中新增加四个成员(须导入android.widget.ImageButton和android.content.Context):

1.       ImageButton mHomeBtn;  
2.       ImageButton mBackBtn;  
3.       ImageButton mMenuBtn; 
4.       final Context mContext;


增加三个常量:(须导入android.view.KeyEvent;)
 public static final int RESV_KEY_HOME = KeyEvent.KEYCODE_HOME;
 public static final int RESV_KEY_BACK = KeyEvent.KEYCODE_BACK;
 public static final int RESV_KEY_MENU = KeyEvent.KEYCODE_MENU;;
在构造函数StatusBarView中初始化mContext

1.       public StatusBarView(Context context, AttributeSet attrs) {   
2.               super(context, attrs);
3.                mContext=context;
4.           } 


注意”mContext=context;”须在”super(context, attrs);”后面,不然编译会报错
在onFinishInflate中,获取几个button 的handler,并设置touch事件,添加如下代码:

1.       mHomeBtn  = (ImageButton)findViewById(R.id.go_home);  
2.       mBackBtn  = (ImageButton)findViewById(R.id.go_back);  
3.       mMenuBtn  = (ImageButton)findViewById(R.id.pop_menu);  
4.         
5.       mHomeBtn.setOnTouchListener(homeOnTouch);  
6.       mBackBtn.setOnTouchListener(backOnTouch);  
7.       mMenuBtn.setOnTouchListener(menuOnTouch);  


各button的touch事件添加如下:

1.          void sendIntent ( Intent intent
2.        { 
3.              mContext.sendBroadcast(intent); 
4.         }
5.       private  void  sendKeyIntent( int  keycode){  
6.           Intent intent =  new  Intent(Intent.ACTION_ICONKEY_CHANGED);  
7.           intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
8.           intent.putExtra( "keycode" ,   keycode);  
9.           sendIntent(intent);              
10.     }  
11.       
12.     private  OnTouchListener homeOnTouch =  new  OnTouchListener(){  
13.          //@Override      
14.             public  boolean  onTouch(View v, MotionEvent event)   
15.            {     
16.                 // TODO Auto-generated method stub        
17.                 switch  (event.getAction()) {  
18.                     case  MotionEvent.ACTION_UP:  
19.                    {  
20.                     sendKeyIntent(RESV_KEY_HOME);             
21.                 }  
22.                     break ;  
23.                }  
24.                 return  false ;     
25.            }   
26.     };  
27.       
28.     private  OnTouchListener backOnTouch =  new  OnTouchListener(){  
29.          //@Override      
30.             public  boolean  onTouch(View v, MotionEvent event)   
31.            {     
32.                 // TODO Auto-generated method stub        
33.                 switch  (event.getAction()) {  
34.                     case  MotionEvent.ACTION_UP:  
35.                    {  
36.                     sendKeyIntent(RESV_KEY_BACK);      
37.                    }  
38.                     break ;  
39.                }  
40.                 return  false ;     
41.            }   
42.     };  
43.       
44.     private  OnTouchListener menuOnTouch =  new  OnTouchListener(){  
45.          //@Override      
46.             public  boolean  onTouch(View v, MotionEvent event)   
47.            {     
48.                 // TODO Auto-generated method stub        
49.                 switch  (event.getAction()) {  
50.                     case  MotionEvent.ACTION_UP:  
51.                    {  
52.                     sendKeyIntent(RESV_KEY_MENU);    
53.                    }  
54.                     break ;  
55.                }  
56.                 return  false ;     
57.            }   
58.     }; 


为防止点击statusBar上的按钮, 触发标题栏的expend事件, 修改一下函数onInterceptTouchEvent,点击到不属于button区域时才允许解析Motion的event:

1.            public  boolean  onInterceptTouchEvent(MotionEvent event) {  
2.                if (  (event.getX() > mHomeBtn.getRight())      
3.                   &&  (event.getX() < mMenuBtn.getLeft())){        
4.                    return  mService.interceptTouchEvent(event)      
5.                       ?  true  :  super .onInterceptTouchEvent(event);       
6.                   }       
7.                return  false ;  
8.                //return mService.interceptTouchEvent(event)                  
9.                //  ? true : super.onInterceptTouchEvent(event);   
10.         }  
11.     }  


需要自己添加Intent
打开frameworks/base/core/java/android/content/Intent.java,增加下面的内容,由于我们的使用的API不公开,须加上
/**@hide*/,不然编译会报错

1.          /**
2.            * @hide
3.            */   
4.         public static final String ACTION_ICONKEY_CHANGED ="android.intent.action.ICONKEY_CHANGED";
5.            


接收并处理intent
修改StatusBarPolicy.java
目录:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java
首先在构造函数中加入Intent的filter,注册号这个intent的receiver。
filter.addAction(Intent.ACTION_ICONKEY_CHANGED);
接着在private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() 加入Intent的receiver动作;

1.       else  if  (action.equals(Intent.ACTION_ICONKEY_CHANGED)) {  
2.                       Log.d(TAG,  "Received ACTION_ICONKEY_CHANGED" );  
3.                       updateIconKeyAction(intent);  
4.                   }  


及处理函数:
须导入以下包
import android.view.IWindowManager;
import android.os.SystemClock;
import android.view.KeyEvent;

1.       private  final  void  updateIconKeyAction(Intent intent){  
2.            int      keycode = intent.getIntExtra( "keycode" , - 1 );  
3.           IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService( "window" ));  
4.             
5.            if (keycode != - 1 ){  
6.                long  now = SystemClock.uptimeMillis();  
7.         
8.                  KeyEvent down =  new  KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode,  0 );  
9.                  KeyEvent up =  new  KeyEvent(now, now, KeyEvent.ACTION_UP, keycode,  0 );  
10.       
11.              try  {  
12.                 wm.injectKeyEvent(down,  false );  
13.             } catch  (RemoteException e) {  
14.                 Log.i( "Input" "DeadOjbectException" );  
15.             }  
16.       
17.              try {  
18.                 wm.injectKeyEvent(up,  false );  
19.             } catch (RemoteException e) {  
20.                 Log.i( "Input" "DeadOjbectException" );  
21.             }  
22.         }  
23.     }  


StatusBar通知栏屏蔽按钮
当拉出expand的通知栏时,按钮的响应非常慢,这时最好将按钮给屏蔽掉,我们在 statusBarView.java中增加两个方法:

1.       public  void  hiddenHotIcons(){  
2.           mHomeBtn.setVisibility(View.INVISIBLE);  
3.           mBackBtn.setVisibility(View.INVISIBLE);  
4.           mMenuBtn.setVisibility(View.INVISIBLE);  
5.       }  
6.         
7.       public  void  showHotIcons(){  
8.           mHomeBtn.setVisibility(View.VISIBLE);  
9.           mBackBtn.setVisibility(View.VISIBLE);  
10.         mMenuBtn.setVisibility(View.VISIBLE);  
11.     }


拉出或收回通知栏中,就可以调用这个函数来显示或隐藏这几个按钮。
修改文件: statusBarService.java
目录:frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java

1.       void performExpand() { 
2.          if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded); 
3.          if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { 
4.            return ;
5.       }
6.       if (mExpanded) {
7.                   return;
8.               }  
9.        mExpanded = true;
10.      makeExpandedVisible();
11.       mStatusBarView.hiddenHotIcons();
12.     updateExpandedViewPos(EXPANDED_FULL_OPEN);
13.     if (false) postStartTracing();
14.     }
15.        void performCollapse() {
16.             if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded
17.                     + " mExpandedVisible=" + mExpandedVisible
18.                     + " mTicking=" + mTicking);
19.      
20.             if (!mExpandedVisible) {
21.                 return;
22.             }
23.             mExpandedVisible = false;
24.             visibilityChanged(false);
25.             mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
26.             mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
27.             mExpandedDialog.getWindow().setAttributes(mExpandedParams);
28.             mTrackingView.setVisibility(View.GONE);
29.             mExpandedView.setVisibility(View.GONE);
30.      
31.              mStatusBarView.showHotIcons();
32.      
33.             if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
34.                 setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
35.             }
36.             if (mDateView.getVisibility() == View.VISIBLE) {
37.                 setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
38.             }
39.      
40.             if (!mExpanded) {
41.                 return;
42.             }
43.             mExpanded = false;
44.         }

编译工程 
#source  /opt/android_froyo_smdk/build/envsetup.sh
#export   TARGET_PRODUCT=full_smdkv210
#mmm frameworks/base/
把编译生成的相关文件放进SD卡对应的目录即可,   在伟研科技 WY-S5PV210开发板上的效果如下图

你可能感兴趣的:(在Android 2.3状态栏中添加menu,home和back快捷键的方法)