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.
2.
8.
12.
16.
18.
xml_stat_back.xml
1.
2.
8.
12.
16.
18.
xml_stat_menu.xml
1.
2.
8.
12.
16.
18.
修改status_bar.xml成如下
目录:
frameworks/base/packages/SystemUI/res/layout/status_bar.xml
1.
2.
20.
21.
22.
29.
30.
34. 42.
43. 50.
60.
71.
82.
90.
91.
92. 98.
103.
107.
111.
112. 118.
124.
130.
131.
132.
133.
143.
二 为按钮添加动态效果
修改
frameworks/base/packages/SystemUI/src/com/android/systemui/st
atusbar/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. voidsendIntent(Intentintent)
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/st
atusbar/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开发板上的效果如下图