Android P Auto版本Home画面解析

发布时间:2024-12-01 21:31

CarPlay 或 Android Auto:连接手机,享受音乐与导航 #生活技巧# #自驾游建议# #自驾游必备APP#

一、Auto版简介

从Android O系统后,安卓发布了针对车机的Auto版本系统。

比较Android P的的Auto比起Android O来说,更加成熟,逻辑功能更加完善。

Auto系统启动后第一页是用户界面:
在这里插入图片描述
选择用户后,进入Home画面:
在这里插入图片描述

二、Auto版SystemUI分析

Auto版本的导航栏和抬头栏也是在SystemUI中实现的。

1.加载SystemBar

代码路径:frameworks\base\packages\SystemUI\src\com\android\systemui\SystemBars.java

private void createStatusBarFromConfig() { if (DEBUG) Log.d(TAG, "createStatusBarFromConfig"); //根据config_statusBarComponent配置来决定选择哪个StatusBar final String clsName = mContext.getString(R.string.config_statusBarComponent); if (clsName == null || clsName.length() == 0) { throw andLog("No status bar component configured", null); } Class<?> cls = null; try { cls = mContext.getClassLoader().loadClass(clsName); } catch (Throwable t) { throw andLog("Error loading status bar component: " + clsName, t); } try { mStatusBar = (SystemUI) cls.newInstance(); } catch (Throwable t) { throw andLog("Error creating status bar component: " + clsName, t); } mStatusBar.mContext = mContext; mStatusBar.mComponents = mComponents; mStatusBar.start(); if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName()); }

1234567891011121314151617181920212223

手机版xml文件:\frameworks\base\packages\SystemUI\res\values\config.xml

<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar </string> 12

Auto版xml文件:\packages\services\Car\car_product\overlay\frameworks\base\packages\SystemUI\res\values\config.xml

<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.car.CarStatusBar </string> 12

可以看到两个版本的差异化,在我们编译系统时,会进行lunch选择:

//... 33. mek_8q-eng 34. mek_8q-userdebug 35. mek_8q_car-eng 36. mek_8q_car-userdebug 37. mek_8q_car2-eng 38. mek_8q_car2-userdebug //... 12345678

如果选择lunch 36则是进行Auto版本编译,会自动根据Auto版本编译配置进行区分,所以Auto版使用的是com.android.systemui.statusbar.car.CarStatusBar的状态栏。

2.分析NavigationBar

底部那一栏就是我们的NavigationBar。

代码路径:
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\car\CarStatusBar.java
\frameworks\base\packages\SystemUI\res\layout\navigation_bar_window.xml
\packages\services\Car\car_product\overlay\frameworks\base\packages\SystemUI\res\layout\car_navigation_bar.xml

CarStatusBar中加载NavigationBar的代码逻辑:

@Override protected void createNavigationBar() { mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar); mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar); mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar); buildNavBarWindows(); buildNavBarContent(); attachNavBarWindows(); } private void buildNavBarContent() { if (mShowBottom) { buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar : R.layout.car_navigation_bar_unprovisioned); }//省略一部分代码//... } private void buildNavBarWindows() { if (mShowBottom) { //navigation_bar_window这个布局文件是kong mNavigationBarWindow = (ViewGroup) View.inflate(mContext, R.layout.navigation_bar_window, null); } if (mShowLeft) { mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext, R.layout.navigation_bar_window, null); } if (mShowRight) { mRightNavigationBarWindow = (ViewGroup) View.inflate(mContext, R.layout.navigation_bar_window, null); } } private void attachNavBarWindows() {//可以看到最终的窗口是放在TYPE_NAVIGATION_BAR这个系统窗口中的 if (mShowBottom) { WindowManager.LayoutParams lp = new WindowManager.LayoutParams( LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.setTitle("CarNavigationBar"); lp.windowAnimations = 0; mWindowManager.addView(mNavigationBarWindow, lp); }//省略一部分代码//... }//得到mNavigationBarViewprivate void buildBottomBar(int layout) { // SystemUI requires that the navigation bar view have a parent. Since the regular // StatusBar inflates navigation_bar_window as this parent view, use the same view for the // CarNavigationBarView. View.inflate(mContext, layout, mNavigationBarWindow); mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0); if (mNavigationBarView == null) { Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar"); throw new RuntimeException("Unable to build botom nav bar due to missing layout"); } mNavigationBarView.setStatusBar(this); }

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071

根据上面的代码,最终layout\car_navigation_bar.xml的布局是放到navigation_bar_window.xml中去,加载到TYPE_NAVIGATION_BAR的系统窗口中去。

分析\packages\services\Car\car_product\overlay\frameworks\base\packages\SystemUI\res\layout\car_navigation_bar.xml代码可以看到,Auto版本的布局都在这个文件里。

从左到右的布局:Home,地图,音乐,电话,菜单,空调,通知,设置和时间。

3.分析Home

布局:\packages\services\Car\car_product\overlay\frameworks\base\packages\SystemUI\res\layout\car_navigation_bar.xml

其中Home的按钮:

<com.android.systemui.statusbar.car.CarNavigationButton android:id="@+id/home" style="@style/NavigationBarButton" systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end" android:src="@drawable/car_ic_overview" android:background="?android:attr/selectableItemBackground" /> 1234567

intent指定跳转界面就是我们的Launcher。

HOME界面其实就是上面我们看到的 Let’s Driver界面。就是Auto版本的Launcher。

Auto版本代码路径:\packages\apps\Car\Launcher
Carlauncher这个应用的代码比较简单,就不多讲了。

4.分析StatusBar

CarStatusBar的代码中,CarStatusBar类是继承自phone/StatusBar 这个类的。
所以车机版的状态栏加载跟手机版的加载差不多,不错,在、、、、、、\packages\services\Car\car_product\overlay\frameworks\base\packages\SystemUI\res\layout\status_bar.xml对状态栏的功能做了简化。

/** * A status bar (and navigation bar) tailored for the automotive use case. */ public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler { private static final String TAG = "CarStatusBar"; public static final boolean ENABLE_HVAC_CONNECTION = !SystemProperties.getBoolean("android.car.hvac.demo", true); 12345678 5.分析用户选择界面

Auto系统启动后,第一个界面是用户选择界面,并不是我们的CarLauncher界面。所以我们来分析一下用户界面的加载过程。

相关代码路径:
\frameworks\base\packages\SystemUI\res\layout\car_fullscreen_user_switcher.xml
\frameworks\base\packages\SystemUI\res\layout\super_status_bar.xml
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\car\UserGridRecyclerView.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\car\FullscreenUserSwitcher.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\UserSwitcherController.java
\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.java

代码\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\car\CarStatusBar.java中会去加载car_fullscreen_user_switcher.xml
布局文件,布局默认改界面是隐藏,生成FullscreenUserSwitcher的对象并对用户选择界面进行操作:

@Override protected void createUserSwitcher() { UserSwitcherController userSwitcherController = Dependency.get(UserSwitcherController.class); if (userSwitcherController.useFullscreenUserSwitcher()) { mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);//加载fullscreen_user_switcher_stub布局 } else { super.createUserSwitcher(); } } @Override public void onUserSwitched(int newUserId) { super.onUserSwitched(newUserId); if (mFullscreenUserSwitcher != null) { mFullscreenUserSwitcher.onUserSwitched(newUserId); } } @Override public void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) { super.updateKeyguardState(goingToFullShade, fromShadeLocked); if (mFullscreenUserSwitcher != null) {//是否为FULLSCREEN_USER_SWITCHER状态 if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) { mFullscreenUserSwitcher.show();//显示用户选择界面 } else { mFullscreenUserSwitcher.hide();//隐藏用户选择界面 } } }

1234567891011121314151617181920212223242526272829303132

其中,StatusBar.java中:

public void showKeyguardImpl() { mIsKeyguard = true; if (mLaunchTransitionFadingAway) { mNotificationPanel.animate().cancel(); onLaunchTransitionFadingEnded(); } mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT); //根据useFullscreenUserSwitcher的状态来决定是否设置FULLSCREEN_USER_SWITCHER状态 if (mUserSwitcherController != null && mUserSwitcherController.useFullscreenUserSwitcher()) { setBarState(StatusBarState.FULLSCREEN_USER_SWITCHER); } else { setBarState(StatusBarState.KEYGUARD); } updateKeyguardState(false /* goingToFullShade */, false /* fromShadeLocked */); updatePanelExpansionForKeyguard(); if (mDraggedDownRow != null) { mDraggedDownRow.setUserLocked(false); mDraggedDownRow.notifyHeightChanged(false /* needsAnimation */); mDraggedDownRow = null; } }

123456789101112131415161718192021

UserSwitcherController.java中:

public boolean useFullscreenUserSwitcher() { // Use adb to override: // adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off. // adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on. // Restart SystemUI or adb reboot. final int DEFAULT = -1; final int overrideUseFullscreenUserSwitcher = Settings.System.getInt(mContext.getContentResolver(), "enable_fullscreen_user_switcher", DEFAULT); if (overrideUseFullscreenUserSwitcher != DEFAULT) { return overrideUseFullscreenUserSwitcher != 0; } // Otherwise default to the build setting. return mContext.getResources().getBoolean(R.bool.config_enableFullscreenUserSwitcher); } 123456789101112131415

使用以下的命令进行设置
// Use adb to override:
// adb shell settings put system enable_fullscreen_user_switcher 0 # Turn it off.
// adb shell settings put system enable_fullscreen_user_switcher 1 # Turn it on.
// Restart SystemUI or adb reboot.

所以只要使用 adb shell settings put system enable_fullscreen_user_switcher 0 ,就可以开机不显示用户选择界面。直接进入Home画面。

使用adb reboot后生效。

网址:Android P Auto版本Home画面解析 https://www.yuejiaxmz.com/news/view/338736

相关内容

小米Note驾驭智能新体验:Android Auto如何让驾驶更安全有趣?
解决Android开发难题:50个黑客技巧解析
解析 static auto x = []() { std::ios::sync
Dumbbell Home Workout Premium「哑铃家庭锻炼」 v4.17 for Android 解锁高级版—— 在家就能通过哑铃锻炼来锻炼肌肉并增强力量
解决Android P/9.0 系统 网络请求错误
https://img0.baidu.com/it/u=284048081,2392616724&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500
Android有关Home按键的TYPE
https://img1.baidu.com/it/u=1917673473,3807601873&fm=253&fmt=auto&app=138&f=JPEG?w=836&h=500
https://img0.baidu.com/it/u=408397787,3154992387&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=353
基于Android平台的记事本软件(Android Studio项目+报告+app文件)

随便看看