Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android6.0 SystemUI之網絡信號欄顯示刷新

Android6.0 SystemUI之網絡信號欄顯示刷新

編輯:關於Android編程

Android6.0 SystemUI之網絡信號欄顯示刷新。Android的網絡信號欄的顯示刷新也是SystemUI的一部分,主要業務邏輯也是在SystemUI這模塊內的,整個流程的開始是在PhoneStatusBar.java內的,

frameworks/base/packages/SystemUI/src/com/Android/systemui/statusbar/phone/PhoneStatusBar.Java;

先從布局方面入手:

由PhoneStatusBar.java的makeStatusBarView()統一加載super_status_bar.xml的。而在Android中,SystemUI上顯示信號狀態欄的地方主要由三處,分別是狀態欄、鎖屏界面下的狀態欄以及下拉通知欄的快捷設置區域。這三個引用處分別是status_bar.xml、keyguard_status_bar.xml、status_bar_expanded_header.xml;而這三個布局文件都會去include一個system_icons.xml布局,

這個布局就是所要尋找的網絡信號欄顯示和電池圖標顯示view的地方。

android:layout_width="wrap_content"

android:layout_height="match_parent"

android:gravity="center_vertical">

android:layout_height="match_parent"

android:gravity="center_vertical"

android:orientation="horizontal"/>

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginStart="2.5dp"/>

android:layout_width="9.5dp"

android:layout_marginBottom="@dimen/battery_margin_bottom"/>

這個布局又會去include一個signal_cluster_view.xml布局,即這個布局才是具體的信號欄的布局文件

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_height="match_parent"

android:layout_width="wrap_content"

android:gravity="center_vertical"

android:orientation="horizontal"

android:paddingEnd="@dimen/signal_cluster_battery_padding"

>

android:id="@+id/vpn"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:paddingEnd="6dp"

android:src="@drawable/stat_sys_vpn_ic"

/>

android:id="@+id/wifi_combo"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

>

android:id="@+id/wifi_signal"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

/>

android:id="@+id/wifi_signal_spacer"

android:layout_width="4dp"

android:layout_height="4dp"

android:visibility="gone"

/>

android:id="@+id/mobile_signal_group"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

>

android:id="@+id/no_sims"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:src="@drawable/stat_sys_no_sims"

/>

android:id="@+id/wifi_airplane_spacer"

android:layout_width="4dp"

android:layout_height="4dp"

android:visibility="gone"

/>

android:id="@+id/airplane"

android:layout_height="wrap_content"

android:layout_width="wrap_content"

/>

代碼邏輯方面:

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

makeStatusBarView()方法:

在這個方法內先去創建兩個控制器mNetworkController、mSecurityController;

mNetworkController=newNetworkControllerImpl(mContext,mHandlerThread.getLooper());

mSecurityController=newSecurityControllerImpl(mContext); NetworkControllerImpl.java繼承於BroadcastReceiver,再看下NetworkControllerImpl的構造方法:

publicNetworkControllerImpl(Contextcontext,LooperbgLooper){

this(context,(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE),

(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE),

(WifiManager)context.getSystemService(Context.WIFI_SERVICE),

SubscriptionManager.from(context),Config.readConfig(context),bgLooper,

newCallbackHandler(),

newAccessPointControllerImpl(context,bgLooper),

newMobileDataControllerImpl(context),

newSubscriptionDefaults());

mReceiverHandler.post(mRegisterListeners);

} 這個構造方法內部會先去調用一個另外的構造方法;

@VisibleForTesting

NetworkControllerImpl(Contextcontext,ConnectivityManagerconnectivityManager,

TelephonyManagertelephonyManager,WifiManagerwifiManager,

SubscriptionManagersubManager,Configconfig,LooperbgLooper,

CallbackHandlercallbackHandler,

AccessPointControllerImplaccessPointController,

MobileDataControllerImplmobileDataController,

SubscriptionDefaultsdefaultsHandler){

mContext=context;

mConfig=config;

mReceiverHandler=newHandler(bgLooper);

mCallbackHandler=callbackHandler;

mSubscriptionManager=subManager;

mSubDefaults=defaultsHandler;

mConnectivityManager=connectivityManager;

mHasMobileDataFeature=

mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE);

//telephony

mPhone=telephonyManager;

//wifi

mWifiManager=wifiManager;

mLocale=mContext.getResources().getConfiguration().locale;

mAccessPoints=accessPointController;

mMobileDataController=mobileDataController;

mMobileDataController.setNetworkController(this);

//TODO:FindawaytomovethisintoMobileDataController.

mMobileDataController.setCallback(newMobileDataControllerImpl.Callback(){

@Override

publicvoidonMobileDataEnabled(booleanenabled){

mCallbackHandler.setMobileDataEnabled(enabled);

}

});

mWifiSignalController=newWifiSignalController(mContext,mHasMobileDataFeature,

mCallbackHandler,this);

mEthernetSignalController=newEthernetSignalController(mContext,mCallbackHandler,this);

//AIRPLANE_MODE_CHANGEDissentatboot;we'veprobablyalreadymissedit

updateAirplaneMode(true/*forcecallback*/);

} 1、給相應的成員變量賦值;

2、創建handler,mReceiverHandler、mCallbackHandler;

3、創建mMobileDataController控制器,並為其設置回調;

4、創建mWifiSignalController,mEthernetSignalController控制器;

5、檢查更新飛行模式;

然後執行完這個內部的構造方法後,接下來會去使用mReceiverHandler去執行一個注冊廣播的操作,負責監控 wifi, SIM卡狀態, service state ,飛行模式等等,最後調用updateMobileControllers()方法初始化一下信號欄顯示:

mReceiverHandler.post(mRegisterListeners);

/**

*UsedtoregisterlistenersfromtheBGLooper,thiswaythePhoneStateListenersthat

*getcreatedwillalsorunontheBGLooper.

*/

privatefinalRunnablemRegisterListeners=newRunnable(){

@Override

publicvoidrun(){

registerListeners();

}

};

privatevoidregisterListeners(){

for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){

mobileSignalController.registerListener();

}

if(mSubscriptionListener==null){

mSubscriptionListener=newSubListener();

}

mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);

//broadcasts

IntentFilterfilter=newIntentFilter();

filter.addAction(WifiManager.RSSI_CHANGED_ACTION);

filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);

filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);

filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);

filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);

filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);

filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);

filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);

filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);

filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);

filter.addAction(Intent.ACTION_LOCALE_CHANGED);

filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);

if(carrier!=null&&(CarrierAppUtils.CARRIER.TELEPHONY_CARRIER_ONE

==carrier)){

filter.addAction(ACTION_EMBMS_STATUS);

}

mContext.registerReceiver(this,filter,null,mReceiverHandler);

mListening=true;

updateMobileControllers();

} 分析完NetworkControllerImpl.java的構造方法之後,基本上我們可以知道NetworkControllerImpl.java是作為信號欄數據控制類,負責監控 wifi, service state ,飛行模式等。

再來看SecurityControllerImpl.java的構造方法,主要先獲取一些系統服務的實例,然後再去注冊一個用戶切換時候的網絡回調接口;

publicSecurityControllerImpl(Contextcontext){

mContext=context;

mDevicePolicyManager=(DevicePolicyManager)

context.getSystemService(Context.DEVICE_POLICY_SERVICE);

mConnectivityManager=(ConnectivityManager)

context.getSystemService(Context.CONNECTIVITY_SERVICE);

mConnectivityManagerService=IConnectivityManager.Stub.asInterface(

ServiceManager.getService(Context.CONNECTIVITY_SERVICE));

mUserManager=(UserManager)

context.getSystemService(Context.USER_SERVICE);

//TODO:re-registernetworkcallbackonuserchange.

mConnectivityManager.registerNetworkCallback(REQUEST,mNetworkCallback);

onUserSwitched(ActivityManager.getCurrentUser());

}

回到PhoneStatusBar.java的makeStatusBarView()方法,接下來實例化自定義的view對象SignalClusterView,上面說過在android SystemUI的三個地方都需要使用網絡信號狀態欄,所以分別實例化了三次,並為其添加相應的接口。

finalSignalClusterViewsignalCluster=

(SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);

finalSignalClusterViewsignalClusterKeyguard=

(SignalClusterView)mKeyguardStatusBar.findViewById(R.id.signal_cluster);

finalSignalClusterViewsignalClusterQs=

(SignalClusterView)mHeader.findViewById(R.id.signal_cluster);

mNetworkController.addSignalCallback(signalCluster);

mNetworkController.addSignalCallback(signalClusterKeyguard);

mNetworkController.addSignalCallback(signalClusterQs);

signalCluster.setSecurityController(mSecurityController);

signalCluster.setNetworkController(mNetworkController);

signalClusterKeyguard.setSecurityController(mSecurityController);

signalClusterKeyguard.setNetworkController(mNetworkController);

signalClusterQs.setSecurityController(mSecurityController);

signalClusterQs.setNetworkController(mNetworkController); 

先來看下addSignalCallback()方法,傳入的參數為SignalClusterView.java的對象,也就是可以大膽推測這個方法的作用應該就是將SignalClusterView.java和NetworkControllerImpl.java建立callback調用。可以具體來分析下,這個方法的主要實現是在NetworkControllerImpl.java中

publicvoidaddSignalCallback(SignalCallbackcb){

mCallbackHandler.setListening(cb,true);

mCallbackHandler.setSubs(mCurrentSubscriptions);

mCallbackHandler.setIsAirplaneMode(newIconState(mAirplaneMode,

TelephonyIcons.FLIGHT_MODE_ICON,R.string.accessibility_airplane_mode,mContext));

mCallbackHandler.setNoSims(mHasNoSims);

mWifiSignalController.notifyListeners();

mEthernetSignalController.notifyListeners();

for(MobileSignalControllermobileSignalController:mMobileSignalControllers.values()){

mobileSignalController.notifyListeners();

}

} 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved