在移植Android的系統中,遇到了飛行模式中在操作一次之後,globalaction(長按power鍵出來的dialog就是globalaction)中的item變成了灰色,並且不可操作,之後對代碼進行了分析,解決了問題,特此記錄,以備有需要的朋友。
現象:長按住power鍵後->彈出globalaction對話框->選擇飛行模式->對話框會自動關閉->再次長按住power鍵後->->彈出globalaction對話框->此時對話框的飛行模式一直都是灰色狀態,且不能做任何操作
其實問題的原因在於源碼在編譯的時候關閉了電話模塊或者是電話的狀態沒有接好之類的問題,下面看代碼理解流程吧:
在globalactions中靜音和飛行模式都是一個toggleaction,下面先看ToggleAction的create的代碼:
willCreate();
View v = (convertView != null) ?
convertView :
inflater.inflate(R
.layout.global_actions_item, parent, false);
ImageView icon = (ImageView) v.findViewById(R.id.icon);
TextView messageView = (TextView) v.findViewById(R.id.message);
TextView statusView = (TextView) v.findViewById(R.id.status);
messageView.setText(mMessageResId);
boolean on = ((mState == State.On) || (mState == State.TurningOn));
icon.setImageDrawable(context.getResources().getDrawable(
(on ? mEnabledIconResId : mDisabledIconResid)));
statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId);
statusView.setVisibility(View.VISIBLE);
boolean enabled = isEnabled(); //判斷現在是否是出於飛行模式切換的中間狀態,這也是第二次打開globalaction中飛行模式無法操作的問題
//下面會設置一個globalaction中toggleaction內的元素狀態
messageView.setEnabled(enabled);
statusView.setEnabled(enabled);
icon.setEnabled(enabled);
v.setEnabled(enabled);
下面再看isEnabled的實現:
return !mState.inTransition(); //實際上是返回一個boolean的state,來判斷他是不是在中間狀態,由於沒有電話信號的設置,所以在設置過一次的時候,他會一直出於中間狀態,但是這裡我還沒有弄清楚在電話狀態正常的時候這個state設怎麼更新的
再看globalactions的構造函數中有這麼一段:
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
這裡會注冊一個mPhoneStateListener來listen LISTEN_SERVICE_STATE,正是因為我們的phone有問題實際上調用不到該回調的,因為再其的回調函數中是有飛行模式的toggleaction狀態的設置(通過mAirplaneState),因此會導致上面我們說到的現象。
因此,倘若要修正的話我的方法是inTransition直接return false來認為他已經不是中間狀態,在你需要關心飛行模式狀態的地方注冊broadcastReciver來接收ACTION_AIRPLANE_MODE_CHANGED,在broadcastReciver添加相應的ACTION_AIRPLANE_MODE_CHANGED發生時需要的行為。例如statusbar的icon的變換(原來的代碼對icon的變換還是監聽的電話的service state)。