您的位置:首页 > 其它

How to Add Virtual Keys on Status Bar

2011-05-07 10:24 363 查看
How to add virtual keys on status bar?
--------------------------------------(for the version before Froyo)

There are 6 .png for touch up and touch down of 3 buttons
Put 72 dpi and 48 dpi which can be found in Google native source code into
frameworks/base/core/res/res/drawable-hdpi
frameworks/base/core/res/res/drawable-mdpi
respectively (P.S. it has xhdpi for supporting tablet device in Gingerbread)
(in Gingerbread the directory has been changed to frameworks/base/packages/SystemUI/res/... )
and add 3 ImageView in frameworks/base/core/res/res/layout/status_bar.xml
status_search, status_back, and status_menu
<ImageView android:id="@+id/status_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingTop="1dip"
android:src="@drawable/search"/>
<ImageView android:id="@+id/status_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingTop="1dip"
android:src="@drawable/back"/>
<ImageView android:id="@+id/status_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingTop="1dip"
android:src="@@drawable/menu"/>
in frameworks/base/core/res/res/value/dimens.xml
you can simply change the height of status bar by assigning
<!-- Height of the status bar -->
<dimen name="status_bar_height">34dip</dimen>
in frameworks/base/services/java/com/android/server/status/StatusBarView.java
(in Gingerbread the directory has been changed to frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/... )
add
//ImageView for virtual key
ImageView mSearchIcon;
ImageView mBackIcon;
ImageView mMenuIcon;
//KeyEevent set
public static final int RESV_KEY_SEARCH = KeyEvent.KEYCODE_SEARCH;
public static final int RESV_KEY_BACK = KeyEvent.KEYCODE_BACK;
public static final int RESV_KEY_MENU = KeyEvent.KEYCODE_MENU;
//Handle touch event
int mResvKeyState = -1;
int mResvKeyCode = -1;
in protected void onFinishInflate() {}
add
//ImageView for virtual key
mSearchIcon = (ImageView)findViewById(R.id.status_search);
mBackIcon = (ImageView)findViewById(R.id.status_back);
mMenuIcon = (ImageView)findViewById(R.id.status_menu);
in public boolean onTouchEvent(MotionEvent event) {}
add
//Added
if(mResvKeyState == -1){
switch(getResvKeyArea(event)){
case RESV_KEY_SEARCH:
case RESV_KEY_BACK:
case RESV_KEY_MENU:
{
mResvKeyState = event.getAction();
mResvKeyCode = getResvKeyArea(event);
updateResvKeyIcon(mResvKeyState, mResvKeyCode);
}
break;
default:
{
if(event.getAction() != MotionEvent.ACTION_DOWN)
mService.interceptTouchEvent(event);
}
break;
}
}
else{
mResvKeyState = event.getAction();
if(mResvKeyState == MotionEvent.ACTION_MOVE){
if(mResvKeyCode != getResvKeyArea(event)){
updateResvKeyIcon(MotionEvent.ACTION_UP, mResvKeyCode);
mResvKeyCode = -1;
mResvKeyState = -1;
}
}
else if (mResvKeyState == MotionEvent.ACTION_UP){
updateResvKeyIcon(mResvKeyState, mResvKeyCode);
Intent intent = new Intent(Intent.ACTION_ICONKEY_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
intent.putExtra("keycode", mResvKeyCode);
mService.sendIntent(intent);
mResvKeyCode = -1;
mResvKeyState = -1;
}
else{
Slog.d(TAG, "error");
}
Add 2 private functions
//Private methods
private int getResvKeyArea(MotionEvent event){
if((event.getX() >= mSearchIcon.getLeft() && event.getX() <= mSearchIcon.getRight())
&& (event.getY() <= this.getHeight())){
return RESV_KEY_SEARCH;
}
else if((event.getX() >= mBackIcon.getLeft() && event.getX() <= mBackIcon.getRight())
&& (event.getY() <= this.getHeight())){
return RESV_KEY_BACK;
}
else if((event.getX() >= mMenuIcon.getLeft() && event.getX() <= mMenuIcon.getRight())
&& (event.getY() <= this.getHeight())){
return RESV_KEY_MENU;
}
else
return -1;
}
//Private methods added
private int updateResvKeyIcon(int state, int key){
if(key == RESV_KEY_SEARCH){
if(state == MotionEvent.ACTION_UP){
mSearchIcon.setImageResource(com.android.internal.R.drawable.search);
}
else if(state == MotionEvent.ACTION_DOWN){
mSearchIcon.setImageResource(com.android.internal.R.drawable.search_pressed);
}
}
else if(key == RESV_KEY_BACK){
if(state == MotionEvent.ACTION_UP){
mBackIcon.setImageResource(com.android.internal.R.drawable.back);
}
else if(state == MotionEvent.ACTION_DOWN){
mBackIcon.setImageResource(com.android.internal.R.drawable.back_pressed);
}
}
else if(key == RESV_KEY_MENU){
if(state == MotionEvent.ACTION_UP){
mMenuIcon.setImageResource(com.android.internal.R.drawable.menu);
}
else if(state == MotionEvent.ACTION_DOWN){
mMenuIcon.setImageResource(com.android.internal.R.drawable.menu_pressed);
}
}
return 0;
}
Change public boolean onInterceptTouchEvent(MotionEvent event) {} to
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if(event.getX() < mSearchIcon.getLeft()){
return mService.interceptTouchEvent(event)
? true : super.onInterceptTouchEvent(event);
}
return false;
}
in frameworks/base/core/java/android/content/intent.java
add our new intent
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_ICONKEY_CHANGED = "android.intent.action.ICONKEY_CHANGED";
in frameworks/base/services/java/com/android/server/status/StatusBarService.java
add
//function added
void sendIntent(Intent intent){
mContext.sendBroadcast(intent);
}
in frameworks/base/services/java/com/android/server/status/StatusBaPolicy.java
find the field where to add registration for intents and add
//Action added
  filter.addAction(Intent.ACTION_ICONKEY_CHANGED);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
in private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {}
add
//added
else if (action.equals(Intent.ACTION_ICONKEY_CHANGED)) {
    updateIconKeyAction(intent);
}
add our private function
//added
private final void updateIconKeyAction(Intent intent){
  int keycode = intent.getIntExtra("keycode", -1);
  if(keycode != -1){
    long now = SystemClock.suptimeMillis();
    try {
      KeyEvent down = new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keycode, 0);
      KeyEvent up = new KeyEvent(now, now, KeyEvent.ACTION_UP, keycode, 0);
      (IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(down, false);
       (IWindowManager.Stub.asInterface(ServiceManager.getService("window"))).injectKeyEvent(up, false);
    }
     catch (RemoteException e) {
    }
  }
}
Done
Remember to make update-api to update frameworks/base/api/current.xml and see if our intent is already added
<field name="ACTION_ICONKEY_CHANGED"
type="java.lang.String"
transient="false"
volatile="false"
value=""android.intent.action.ICONKEY_CHANGED""
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
Result








内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: