android 长按power界面,Android长按Power键弹出关机Dialog框GlobalActions解析

Android长按关机键,会弹出关机的对话框,如下图:

0818b9ca8b590ca3270a3433284dd417.png

现在分析一下详细的流程:

1)  PWM中,会调用

privatevoidinterceptPowerKeyDown(booleanhandled) {

mPowerKeyHandled = handled;

if(!handled) {

mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());

}

} 从而进入mPowerLongPress

privatefinalRunnable mPowerLongPress =newRunnable() {

@Override

publicvoidrun() {

// The context isn't read

if(mLongPressOnPowerBehavior <0) {

mLongPressOnPowerBehavior = mContext.getResources().getInteger(

com.android.internal.R.integer.config_longPressOnPowerBehavior);

}

...

switch(resolvedBehavior) {

caseLONG_PRESS_POWER_NOTHING:

break;

caseLONG_PRESS_POWER_GLOBAL_ACTIONS:

mPowerKeyHandled = true;

if(!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS,false)) {

performAuditoryFeedbackForAccessibilityIfNeed();

}

sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);

showGlobalActionsDialog();

break;

...

}

}

}; 调用showGlobalActionsDialog

voidshowGlobalActionsDialog() {

if(mGlobalActions ==null) {

mGlobalActions = newGlobalActions(mContext, mWindowManagerFuncs);

}

finalbooleankeyguardShowing = keyguardIsShowingTq();

mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());

if(keyguardShowing) {

// since it took two seconds of long press to bring this up,

// poke the wake lock so they have some time to see the dialog.

mKeyguardMediator.userActivity();

}

}

分两步来进行,首先创建GlobalActions, 然后在showDialog出来,主要的功能实在showDialog中完成的,

publicvoidshowDialog(booleankeyguardShowing,booleanisDeviceProvisioned) {

mKeyguardShowing = keyguardShowing;

mDeviceProvisioned = isDeviceProvisioned;

if(mDialog !=null) {

mDialog.dismiss();

mDialog = null;

// Show delayed, so that the dismiss of the previous dialog completes

mHandler.sendEmptyMessage(MESSAGE_SHOW);

} else{

handleShow();

}

}

然后调用handleShow

privatevoidhandleShow() {

awakenIfNecessary();

mDialog = createDialog();

prepareDialog();

WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();

attrs.setTitle("GlobalActions");

mDialog.getWindow().setAttributes(attrs);

mDialog.show();

mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);

} 在createDialog中主要是准备Dialog显示的数据,最关键的是mItems, 这代表关机时候显示的每一项,每一项实际是一个action,里面定义了如何创建Diaolg以及点击时的响应,

以添加飞行模式为例,

// last: silent mode

if(SHOW_SILENT_TOGGLE) {

mItems.add(mSilentModeAction);

}

Action接口的实现:

Implemented By

GlobalActions.SilentModeTriStateAction

GlobalActions.SinglePressAction

GlobalActions.ToggleAction

每一项的动作对应的View添加进MyAdapter,通过ListView来管理

privateMyAdapter mAdapter; 在创建Item的时候,

publicView getView(intposition, View convertView, ViewGroup parent) {

Action action = getItem(position);

returnaction.create(mContext, convertView, parent, LayoutInflater.from(mContext));

}

会分别调用每一个Action的onCreate来创建每一个Item View,每种Item View对应的实现了Action的接口,从而定义不同的点击动作

以来电模式的选择为例,

createItem:

publicView create(Context context, View convertView, ViewGroup parent,

LayoutInflater inflater) {

View v = inflater.inflate(R.layout.global_actions_silent_mode, parent, false);

intselectedIndex = ringerModeToIndex(mAudioManager.getRingerMode());

for(inti =0; i <3; i++) {

View itemView = v.findViewById(ITEM_IDS[i]);

itemView.setSelected(selectedIndex == i);

// Set up click handler

itemView.setTag(i);

itemView.setOnClickListener(this);

}

returnv;

}

item 响应事件:

publicvoidonClick(View v) {

if(!(v.getTag()instanceofInteger))return;

intindex = (Integer) v.getTag();

mAudioManager.setRingerMode(indexToRingerMode(index));

mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);

}

当点击了震动后,会调用AudioManager的setRingMode,经过AudioService处理后,会发出RINGER_MODE_CHAGNED_ACTION的广播,然后GlobalActions会接收到广播:

privateBroadcastReceiver mRingerModeReceiver =newBroadcastReceiver() {

@Override

publicvoidonReceive(Context context, Intent intent) {

if(intent.getAction().equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {

mHandler.sendEmptyMessage(MESSAGE_REFRESH);

}

}

};

privateHandler mHandler =newHandler() {

publicvoidhandleMessage(Message msg) {

switch(msg.what) {

caseMESSAGE_DISMISS:

if(mDialog !=null) {

mDialog.dismiss();

}

break;

caseMESSAGE_REFRESH:

refreshSilentMode();

mAdapter.notifyDataSetChanged();

break;

caseMESSAGE_SHOW:

handleShow();

break;

}

}

};

最终会在Handler中更新图片,然后响应刚才的dismiss事件mHandler.sendEmptyMessageDelayed(MESSAGE_DISMISS, DIALOG_DISMISS_DELAY);让对话框消失

Android通过这样的方式,让程序的扩展性得到了很大的提升,这是值得借鉴的地方

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值