Android 2.3 修改 statusbar

Android 2.2 和android 2.3 在源码结构上有一些变化:tatusbar 的位置的变化,2.3中 statusbar 的源码在 frameworks/base/packages/SystemUI中。

修改statusbar的背景,frameworks/base/packages/SystemUI/res/drawable-mdpi,替换       statusbar_background.9.png

调整statusbar的高度,frameworks/base/core/res/res/values/dimens.xml 中,修改 <dimen name="status_bar_height">25dip</dimen> 的值

调整statusbar中的日期和时钟的字体:frameworks/base/packages/SystemUI/res/layout/status_bar.xml 中,会有如下的代码 <com.Android.systemui.statusbar.Clock 定义时钟的样式,可以添加字体的属性 如: android:textSize等;<com.android.systemui.statusbar.DateView  定义的是日期的样式,可以添加字体的属性 如: android:textSize等。

去掉statusbar中的图标,在平板开发的过程中,有一些手机的功能可能在平板上用不到,如3G功能,但是怎么样把statusbar中的3G的图标去掉呢?在 framework/base/packages/SystemUI/src/com/Android/systemui/statusbar/StatusBarPolicy.java 中会有下面的代码 mService.setIcon("phone_signal", mPhoneSignalIconId, 0);  这里是设置手机信号的图标,去掉3G信号图标只需将这个文件中的 这句话注释即可。相应的也可以修改其他的图标。

修改完之后可以直接编译SystemUI,然后push 到/system/app 中,即可看到效果。

编译 SystemUI: 在Android根目录执行 source build/envsetup.sh ,然后在根目录执行 mm SystemUI ,最后会在 out/target/product/generic/system/app 中生成一个SystemUI.apk,

adb push SystemUI.apk    /system/app;

statusbar是一种服务,需要启动satusbar服务:Android 启动服务 命令: adb shell am start -n com.android.systemui/com.android.systemui.statusbar.StatusBarService,即可看到效果。

关于Android启动Activity: adb shell am start -n 包名/包名.Activity名;启动服务:adb shell am start -n 包名/包名.服务名

##########################################################


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/core/res/res/drawable下创建三个imageButton的xml文件:

xml_stat_home.xml

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

xml_stat_back.xml

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

xml_stat_menu.xml

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

修改status_bar.xml,如下:

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

如上篇,修改statusbar的高度,编译一下,即可看到效果。

2。 添加按钮的动作效果
在statusBarView.java中,活的button的handler

类中新增加三个成员:

1
2
3
 ImageButton mHomeBtn;
 ImageButton mBackBtn;
 ImageButton mMenuBtn;

增加三个常量:

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;;

在onFinishInflate中,获取几个button 的handler,并设置touch事件,添加如下代码:

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

各button的touch事件添加如下:

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

也就是简单的广播一个intent消息给statusBarPolicy处理。

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

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

修改StatusBarService.java,发送Intent消息需要content,这个目前只能在StatusBarService中添加一个方法:

1
2
3
4
void sendIntent(Intent intent)
    {
     mContext.sendBroadcast(intent);
    }

要发送intent,需要自己添加Intent:

在framework/base/core/java/android/content/intent.java中增加

1
2
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)   
public static final String ACTION_ICONKEY_CHANGED = "android.intent.action.ICONKEY_CHANGED";

接收并处理intent, 如前篇:

接收并处理intent

这个就要修改StatusBarPolicy.java了

首先,在构造函数中加入Intent的filter,注册号这个intent的receiver。

1
filter.addAction(Intent.ACTION_ICONKEY_CHANGED);

然后再private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() 加入Intent的receiver动作;

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

及处理函数:

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

3. StatusBar通知栏屏蔽按钮

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

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

拉出或收回通知栏中,就可以调用这个函数来显示或隐藏这几个按钮。

修改文件: statusBarService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    void performExpand() {
        if (SPEW) Log.d(TAG, "performExpand: mExpanded=" + mExpanded);
        if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) {
            return ;
        }
        if (mExpanded) {
            return;
        }
 
        // It seems strange to sometimes not expand...
        if (false) {
            synchronized (mNotificationData) {
                if (mNotificationData.size() == 0) {
                    return;
                }
            }
        }
 
        mExpanded = true;
        makeExpandedVisible();
		mStatusBarView.hiddenHotIcons(); // Changed!!!
        updateExpandedViewPos(EXPANDED_FULL_OPEN);
 
        if (false) postStartTracing();
    }
 
    void performCollapse() {
        if (SPEW) Log.d(TAG, "performCollapse: mExpanded=" + mExpanded
                + " mExpandedVisible=" + mExpandedVisible);
 
        if (!mExpandedVisible) {
            return;
        }
        mExpandedVisible = false;
        panelSlightlyVisible(false);
        mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
        mExpandedDialog.getWindow().setAttributes(mExpandedParams);
        mTrackingView.setVisibility(View.GONE);
 
		mStatusBarView.showHotIcons(); // Changed!!!!
        if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
            setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
        }
        setDateViewVisibility(false, com.android.internal.R.anim.fade_out);
 
        if (!mExpanded) {
            return;
        }
        mExpanded = false;
    }

原文链接:http://blog.csdn.net/freshui/archive/2010/11/24/6033377.aspx



你可能感兴趣的:(Android 2.3 修改 statusbar)