修改状态栏的时间

来源:互联网 发布:乐视网络电视微博 编辑:程序博客网 时间:2024/06/05 10:15
ps:Android4.2
首先介绍什么是SystemUI:
对于Phone来说SystemUI指的是:StatusBar、NavigationBar.而对于平板或是TV来说SystemUI指的是CombineBar.
SystemUI也就是我们Phone的信号、蓝牙、WIFI标志等等这些状态,当我们的设备开机后首先呈现给用户的就是各种界面(包括SystemUI)。
下面介绍SystemUI的启动流程:
首先来看看SystemUI的代码结构,如下图:
    
       在android4.2中,谷歌整合了phone和平板(TV)的SystemUI,也就是说可以根据设备的类型可以自动匹配相关的SystemUI。
分析应用程序我们一般从AndroidManifest.xml开始,SystemUI也是如此,我们打开AndroidManifest,有如下相关代码:
 
我们发现SystemUIService,他是在一开机就启动的服务。而SystemUIService是在SystemServer.java中真正启动的,如下代码:static final void startSystemUi(Context context) {        Intent intent = new Intent();        intent.setComponent(new ComponentName("com.android.systemui",                    "com.android.systemui.SystemUIService"));        //Slog.d(TAG, "Starting service: " + intent);        context.startServiceAsUser(intent, UserHandle.OWNER);        }而这里的startSystemUi是在android系统启动过程中的ServerThread的run方法中调用的。在SystemServer中,初始化了Android系统中的Java层服务,如PowerManagerService、WindowManagerService等等,当然也包括了SystemUIService,它们通过ServiceManager的addService()方法,添加到ServiceManager的管理中。而我们要关注的就是StatusBarManagerService 代码如下:...        StatusBarManagerService statusBar = null;...try {                Slog.i(TAG, "Status Bar");                statusBar = new StatusBarManagerService(context, wm);                ServiceManager.addService(Context.STATUS_BAR_SERVICE, statusBar);            } catch (Throwable e) {                reportWtf("starting StatusBarManagerService", e);            }...try {                Slog.i(TAG, "Notification Manager");                notification = new NotificationManagerService(context, statusBar, lights);                ServiceManager.addService(Context.NOTIFICATION_SERVICE, notification);                networkPolicy.bindNotificationManager(notification);            } catch (Throwable e) {                reportWtf("starting Notification Manager", e);            }...既然到这里SystemUIService已经启动,那么我们就继续跟踪该Service吧。在SystemUIService的onCreate中:  @Override    public void onCreate() {        // Tell the accessibility layer that this process will        // run as the current user, i.e. run across users.        AccessibilityManager.createAsSharedAcrossUsers(this);        // Pick status bar or system bar.        IWindowManager wm = WindowManagerGlobal.getWindowManagerService();        try {            SERVICES[0] = wm.hasSystemNavBar()                    ? R.string.config_systemBarComponent                    : R.string.config_statusBarComponent;        } catch (RemoteException e) {            Slog.w(TAG, "Failing checking whether status bar can hide", e);        }        final int N = SERVICES.length;        mServices = new SystemUI[N];        for (int i=0; i<N; i++) {            Class cl = chooseClass(SERVICES[i]);            Slog.d(TAG, "loading: " + cl);            try {                mServices[i] = (SystemUI)cl.newInstance();            } catch (IllegalAccessException ex) {                throw new RuntimeException(ex);            } catch (InstantiationException ex) {                throw new RuntimeException(ex);            }            mServices[i].mContext = this;            Slog.d(TAG, "running: " + mServices[i]);            mServices[i].start();        }    }在这段代码中,通过AIDL的方式获取了WindowManager的对象wm,并调用其方法hasSystemNavBar()来判断当前设备的类型,也就是说如果我们使用的Phone那么后续就会加载StatusBar和NivagationBar;而如果我们设备类型是Tablet(TV)之类的(可以在配置文档里面配置),就会加载CombiedBar。而对于平板 R.string.config_systemBarComponent  在config.xml中的值为:com.android.systemui.statusbar.tablet.TabletStatusBar ,我们继续跟踪,在TabletStatusBar中根据函数名我们可以判断在makeStatusBarView() 中对statusbar进行绘制。见代码:    ........    final TabletStatusBarView sb = (TabletStatusBarView)View.inflate( context, R.layout.system_bar, null); mBarContents = (ViewGroup) sb.findViewById(R.id.bar_contents);.........   mNotificationArea = sb.findViewById(R.id.notificationArea);mBackButton = (ImageView)sb.findViewById(R.id.back);        mNavigationArea = (ViewGroup) sb.findViewById(R.id.navigationArea);        mHomeButton = mNavigationArea.findViewById(R.id.home);        mMenuButton = mNavigationArea.findViewById(R.id.menu);mVolumeDownButton = mNavigationArea.findViewById(R.id.volume_down);mVolumeUpButton = mNavigationArea.findViewById(R.id.volume_up);        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);......由此可以看出状态栏所有相关的东东在这里都体现出来了。下面我们进入布局system_bar中看看:<!-- notification icons & panel access -->            <include layout="@layout/system_bar_notification_area"                 android:layout_width="wrap_content"                android:layout_height="match_parent"                android:layout_alignParentRight="true"                android:layout_marginTop="1dp"                />而在system_bar_notification_area中有: <LinearLayout        android:id="@+id/notificationTrigger"        android:layout_width="wrap_content"        android:layout_height="match_parent"        android:gravity="center"        >        <com.android.systemui.statusbar.policy.Clock            android:id="@+id/clock"            android:textAppearance="@style/TextAppearance.StatusBar.Clock"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:singleLine="true"            android:paddingLeft="6dip"            android:layout_marginRight="8dip"            android:gravity="center_vertical|left"            />对此我们进入到com.android.systemui.statusbar.policy.Clock中进一步查看:final void updateClock() {       mCalendar.setTimeInMillis(System.currentTimeMillis());        setText(getSmallTime());    }private final CharSequence getSmallTime() {        Context context = getContext();        boolean b24 = DateFormat.is24HourFormat(context);        int res; if (b24) {            res = R.string.twenty_four_hour_time_format;        } else {            res = R.string.twelve_hour_time_format;        }...String result = sdf.format(mCalendar.getTime());if (AM_PM_STYLE != AM_PM_STYLE_NORMAL) {            int magic1 = result.indexOf(MAGIC1);            int magic2 = result.indexOf(MAGIC2);            if (magic1 >= 0 && magic2 > magic1) {                SpannableStringBuilder formatted = new SpannableStringBuilder(result);                if (AM_PM_STYLE == AM_PM_STYLE_GONE) {                    formatted.delete(magic1, magic2+1);                } else {                    if (AM_PM_STYLE == AM_PM_STYLE_SMALL) {                        CharacterStyle style = new RelativeSizeSpan(0.7f);                        formatted.setSpan(style, magic1, magic2,                                          Spannable.SPAN_EXCLUSIVE_INCLUSIVE);                    }                   formatted.delete(magic2, magic2 + 1);                formatted.delete(magic1, magic1 + 1);           }                 return formatted;            }        }return result;}所以我们只要在getSmallTime中返回之前对其返回指进行处理即可达到我们的目地:比如修改显示方式等。
原创粉丝点击