关于 Android 4.4 系统屏幕旋转调研

本文档详细探讨了Android 4.4系统中屏幕旋转的实现机制,从Framework层的SystemUI分析,包括SystemUIService启动、Statusbar和RotationLockController的工作原理。此外,还介绍了如何修改快速设置中的旋转屏幕按钮,涉及RotationPolicy类的修改和图标标签的定制。最后,讲解了如何在系统设置中添加屏幕旋转选项,模仿休眠菜单的原理构建相关功能。
摘要由CSDN通过智能技术生成






Android 系统屏幕旋转调研

2015-4-20修订版)

 


目录

目录 2

前言 4

1.关于 5

1.1.Framework 层屏幕旋转原理 6

1.1.1.初识SystemUI 6

1.1.2.分析 SystemUI 代码 6

1.1.2.1.AndroidManifest.xml开始 6

1.1.2.2.SystemUIService分析 7

1.1.2.3.Statusbar分析 9

1.1.3.关于Settings.System 16

1.2.旋转监听机制分析 17

1.3.加速度传感器架构分析 17

1.3.1.内核驱动层 18

1.3.2.HAL硬件抽象层 18

1.3.3.JNI 18

1.3.4.Java Framework 18

2.修改快速设置中旋转屏幕按钮 19

2.1.需求: 19

2.2.功能上的修改: 19

2.3.关于图标: 19

2.4.关于图标标签: 20

3.系统设置添加选项 21

3.1.研究休眠菜单原理 21

3.2.模仿休眠菜单原理构建 22

3.2.1.调用读取键值部分 22

3.2.2.updateRotationPreferenceDescription方法的构建 22

3.2.3.设置标签 23

3.2.4.添加菜单标题 24

菜单的设置 24

4.应用程序设置屏幕旋转方法 25


前言

 

本文档是在全志A33平台 Android 系统中,关于屏幕旋转方面的技术调研。

李瀚

2015414


1.关于 

决定屏幕方向有两个层面,一个是 Linux 内核层的 FB 方向(这里暂不深入),驱动上做的修改,另一个是 Android OS 上的修改。

在 Linux 内核初始化以后,init进程启动,紧接着启动了Zygote。ZygoteDalvik虚拟机共享代码、低内存占用以及最小的启动时间成为可能。Zygote是一个虚拟器进程,正如我们在前一个步骤所说的在系统引 导的时候启动。Zygote预加载以及初始化核心库类。通常,这些核心类一般是只读的,也是Android SDK或者核心框架的一部分。在Java虚拟机中,每一个实例都有它自己的核心库类文件和堆对象的拷贝。

 
 
 

如上图,Zygote启动以后,初始化了 System.Settings,开始了SystemUI 和 Settings 的进程、监听屏幕旋转机制和传感器管理器。当来自 SystemUI 或者 Settings 对 System.Settings 数据库的设置生效,监听屏幕旋转机制就打开,开始读取来由自底层设备驱动经过HAL经过JNI到传感器管理器的数据,对屏幕进行旋转设置。

 

1.1.Framework 层屏幕旋转原理

最终实现状态栏的快速设置功能是在 SystemUI 上。所以先从 SystemUI 入手。

1.1.1.初识SystemUI

Android 4.4,是由 Google 公司制作和研发的代号为 KitKat 的手机操作系统,于北京时间 2013 年 9 月 4 日凌晨对外公布了该 Android 新版本的名称,为 Android 4.4 (代号 KitKat 奇巧)。

Android 4.4 同时适用于PhoneTablet(TV),因此,对于 Phone 来说 SystemUI 指的是:StatusBar(状态栏)、 NavigationBar(导航栏)。而对于 Tablet 或者是 TV 来说 SystemUI 指的是:CombinedBar(包括了 StatusBar 和 NavigationBar)

 

Android 的 Phone 的信号,蓝牙标志,Wifi 标志等等这些状态显示标志都会在 StatusBar 上显示。当我们的设备开机后,首先需要给用户呈现的就是各种界面同时也包括了我们的 SystemUI,因此对于整个 Android 系统来说,SystemUI 都有举足轻重的作用。

1.1.2.分析 SystemUI 代码

1.1.2.1.AndroidManifest.xml开始

 

在 Android 4.4 中,Google 整合了 Phone 和 Tablet(TV) 的 SystemUI,也就说可以根据设备的类型自动匹配相应的 SystemUI首先从 AndroidManifest.xml 入手。

 

(省略)

<!-- Wifi Display -->

<uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />

<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />

<uses-permission android:name="android.permission.RECORD_AUDIO" />

<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" />

 

<application

android:persistent="true"

android:allowClearUserData="false"

android:allowBackup="false"

android:hardwareAccelerated="true"

android:label="@string/app_label"

android:icon="@*android:drawable/platlogo"

android:process="com.android.systemui"

android:supportsRtl="true">

 

<!-- Broadcast receiver that gets the broadcast at boot time and starts

up everything else.

TODO: Should have an android:permission attribute

-->

<service android:name="SystemUIService"

android:exported="true"

/>

 

<!-- started from PhoneWindowManager

TODO: Should have an android:permission attribute -->

<service android:name=".screenshot.TakeScreenshotService"

android:process=":screenshot"

android:exported="false" />

 

<service android:name=".LoadAverageService"

android:exported="true" />

 

<service android:name=".ImageWallpaper"

android:permission="android.permission.BIND_WALLPAPER"

android:exported="true" />

(省略)

根据以上代码我们可以发现这其中注册了很多 Service,同时也包括了广播。但这里我们只关注 SystemUIService。首先要找到 SystemUIService 是如何启动的。Service 的启动,不外乎 startService(intent) 和 bindService(intent),它们都是以 intent 为对象,由于 intent 的声明也需要 SystemUIService,因此我们可以据此搜索关键词"SystemUIService"

1.1.2.2.SystemUIService分析

经过搜索发现:

frameworks/base/services/java/com/android/server/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);

}

 

这部分是开始了 SystemUI,可以确认下面代码是上面服务的具体实现:

frameworks/base/packages/systemui/src/com/android/systemui/SystemUIService.java 

 

public class SystemUIService extends Service {

    private static final String TAG = "SystemUIService";

 

    /**

     * The classes of the stuff to start.

     */

    private final Class<?>[] SERVICES = new Class[] {

            com.android.systemui.recent.Recents.class,

            com.android.systemui.statusbar.SystemBars.class,

            com.android.systemui.usb.StorageNotification.class,

            com.android.systemui.power.PowerUI.class,

            com.android.systemui.media.RingtonePlayer.class,

            com.android.systemui.settings.SettingsUI.class,

};

 

    /**

     * Hold a reference on the stuff we start.

     */

    private final SystemUI[] mServices = new SystemUI[SERVICES.length];

 

    @Override

    public void onCreate() {

        HashMap<Class<?>, Object> components = 

            new HashMap<Class<?>, Object>();

        final int N = SERVICES.length;

        for (int i=0; i<N; i++) {

            Class<?> cl = SERVICES[i];

            Log.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;

            mServices[i].mComponents = components;

            Log.d(TAG, "running: " + mServices[i]);

            mServices[i].start();

        }

    }

(省略)

 

这里初始化了以下类

Recent(最近打开程序)

com.android.systemui.recent.Recents.class

Statusbar(状态栏)

com.android.systemui.statusbar.SystemBars.class

USBStorageNotificationUSB存储设备通知) com.android.systemui.usb.StorageNotification.class

PowerUI

com.android.systemui.power.PowerUI.class

RingtonePlayer

com.android.systemui.media.RingtonePlayer.class

SettingsUI(设置界面)

com.android.systemui.settings.SettingsUI.class

 

4.0以前版本,这里都是整合在一起的,4.4这里开始分离出来,分一个个模块。以后若是针对某个模块分析,在这里开始了分支。

1.1.2.3.Statusbar分析

接下来重点是 Statusbar(状态栏),这个类构建在:

/frameworks/base/packages/systemui/src/com/android/systemui/statusbar/SystemBars.java 分析得出接下来调用了frameworks/base/packages/systemui/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

// 创建一个快速设置菜单

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值