android 4.2 多用户

简介: android 4.2 多用户

多用户的概念在早于4.2的源码中,就已经可以初见端倪.

直到4.2,才真真正正地将之扶正.

功能详解见:

http://www.evolife.cn/html/2012/67701.html

喜欢刷版本号的谷歌在今年已经把Android从4.0刷到了4.2,而大部分机器连果冻豆都还没吃上,单核的二儿子已经跪在了4.2门前。好在4.1到4.2只是改动不大的小幅升级,名称还是果冻豆,新加的特色功能包括通知栏控件,锁屏小插件和平板中的多账户。今天我们就来给大家介绍一下Android 4.2的重点功能——能让一家人共享一个Android设备的多用户功能。

image.png

多账户的概念跟Windows电脑上的账户类似,绝对不是什么噱头,不过Android系统的多账户还是有一些独特的地方。

image.png

首先,第一个使用平板的用户默认为平板管理员,可以在平板设置选项的用户区添加或删除帐号。网络设置和安装应用程序的权限在平板所有用户中通用和共享,但墙纸、主屏幕、锁屏布局、PIN码、屏幕明亮度、单个应用设置等则各不相同。新用户注册后大约会占用十几MB空间(Nexus 7初始账户大小在12.78MB左右),不过随着下载应用数量的增加,占用的空间也会越来越大。

image.png

image.png

跟Windows操作系统的不同之处在于,4.2系统的其他用户帐户中正在运行的后台程序也会占用一定的RAM空间。而最明显的区别是用户之间的应用程序无法共享,这样一来想要用没付费的帐户在同一台机器下载其他账户已经付费的内容时,需要在商店用已付费的帐户密码重新登录,如果想要保护隐私的话就没办法跟其他用户共享付费软件,希望谷歌在后续版本中能解决这个问题。(好在多个账户重复下载同一应用时不会真的在存储空间里出现相同的两个应用,而是进行虚拟下载和安装,不用担心占用空间。)

image.png


此外,用户之间不能直接共享数据,即使将平板和电脑相连,也只能浏览当前用户的文件,切换帐号需要重新装载,虽说有些麻烦但是安全性得到了充分保证。

image.png

除了多账户,4.2新增的通知栏控件也非常实用,一直以来靠第三方ROM实现的这项功能终于在原生系统上出现。另外锁屏界面也变得更丰富,滑屏到左边可以预览相机程序(此时再往上滑才能解锁,不用担心误触),右边显示可选的小插件界面(不能添加第三方插件),显然自带的这些小插件是不能满足需求的,且一个锁屏界面只能放一个插件,切换必须一屏一屏滑,目测第三方ROM中,第三方插件和多插件自定义功能会很快出现。

image.png

image.png


添加桌面插件时原本的图标会自动让位

Android 4.2在细节上吸收了不少第三方厂商或者ROM的人性化功能。只是如果没有特殊需求,4.2相比4.1来说改动不大,普通用户没有必须升级的必要。当然作为特色的多账户功能出现在手机上也是迟早的事,这样一来通过账户切换,同学们再也不用担心手机藏不住小秘密。

从最初拿到手的源码, 本以为可以很兴奋地看到这个新功能, 实际上却大失所望.

直到前不久, 才有客户提出此功能的需求, 查一查还真查到多用户支持的一些补丁.

直接从上层设置入手:

packages/apps/Settings/res/xml/settings_headers.xml
    <!-- Manage users -->
    <header
        android:fragment="com.android.settings.users.UserSettings"
        android:icon="@drawable/ic_settings_multiuser"
        android:title="@string/user_settings_title"
        android:id="@+id/user_settings" />
 显示或隐藏由JAVA源码控制:
packages/apps/Settings/src/com/android/settings/Settings.java
 private void updateHeaderList(List<Header> target) {
        final boolean showDev = true;/*mDevelopmentPreferences.getBoolean(
                DevelopmentSettings.PREF_SHOW,
                android.os.Build.TYPE.equals("eng"));*/
        int i = 0;
        mHeaderIndexMap.clear();
        while (i < target.size()) {
            Header header = target.get(i);
            // Ids are integers, so downcasting
            int id = (int) header.id;
            if (id == R.id.operator_settings || id == R.id.manufacturer_settings) {
                Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
            } else if (id == R.id.wifi_settings) {
                // Remove WiFi Settings if WiFi service is not available.
                if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
                    target.remove(i);
                }
            } else if (id == R.id.bluetooth_settings) {
                // Remove Bluetooth Settings if Bluetooth service is not available.
                //if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
                if (SystemProperties.get("ro.rk.bt_enable", "true").equals("false")) {
                    target.remove(header);
                }
            } else if (id == R.id.hdmi_settings) {
    if("true".equals(SystemProperties.get("ro.zed.noHdmi"))){
    target.remove(header);
    }
            }else if (id == R.id.data_usage_settings) {
                // Remove data usage when kernel module not enabled
                final INetworkManagementService netManager = INetworkManagementService.Stub
                        .asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
                try {
                    if (!netManager.isBandwidthControlEnabled()) {
                        target.remove(i);
                    }
                } catch (RemoteException e) {
                    // ignored
                }
            } else if (id == R.id.account_settings) {
                int headerIndex = i + 1;
                i = insertAccountsHeaders(target, headerIndex);
            }/** 重点看下这个地方 *****/
 else if (id == R.id.user_settings) {
                if (!UserHandle.MU_ENABLED
                        || !UserManager.supportsMultipleUsers()
                        || Utils.isMonkeyRunning()) {
                    target.remove(i);
                }
            } else if (id == R.id.development_settings) {
                if (!showDev) {
                    target.remove(i);
                }
            } else if(id == R.id.hdmi_settings){
                if(!hasHdmiFeature()){
                       target.remove(header);
                }
            }
            if (target.get(i) == header
                    && UserHandle.MU_ENABLED && UserHandle.myUserId() != 0
                    && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
                target.remove(i);
            }
            // Increment if the current one wasn't removed by the Utils code.
            if (target.get(i) == header) {
                // Hold on to the first header, when we need to reset to the top-level
                if (mFirstHeader == null &&
                        HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {
                    mFirstHeader = header;
                }
                mHeaderIndexMap.put(id, i);
                i++;
            }
        }
    }

分别来看看三个条件的情况:

!UserHandle.MU_ENABLED:
public static final boolean MU_ENABLED = true;
!UserManager.supportsMultipleUsers()
 /**
     * Returns whether the system supports multiple users.
     * @return true if multiple users can be created, false if it is a single user device.
     * @hide
     */
    public static boolean supportsMultipleUsers() {
        return getMaxSupportedUsers() > 1;
    }
    /**
     * Returns the maximum number of users that can be created on this device. A return value
     * of 1 means that it is a single user device.
     * @hide
     * @return a value greater than or equal to 1 
     */
    public static int getMaxSupportedUsers() {
        // Don't allow multiple users on certain builds
        if (android.os.Build.ID.startsWith("JVP")) return 1;
        return SystemProperties.getInt("fw.max_users",
                Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));
    }

Utils.isMonkeyRunning()这个条件一般不成立

所以, 一般比较可控的地方就在于:

if (android.os.Build.ID.startsWith("JVP")) return 1;
return SystemProperties.getInt("fw.max_users",
                Resources.getSystem().getInteger(R.integer.config_multiuserMaximumUsers));

可以考虑在build.prop中添加属性:

fw.max_users=x  x >1

如果上面属性没有添加, 那另一部分就是修改

config_multiuserMaximumUsers的值.

frameworks/base/core/res/res/values/config.xml

<!--  Maximum number of supported users -->

   <integer name="config_multiuserMaximumUsers">8</integer>

修改上面的值,请留意是否有overlay.

相关文章
|
11月前
|
存储 XML 搜索推荐
【车载Android】多用户(一) - Linux用户与Android多用户
Android是一个基于Linux内核的操作系统,它支持多用户模式,即可以在同一台设备上创建多个用户账户,每个用户都有自己的应用、数据和设置。这样可以保护用户的隐私,也可以方便不同的使用场景。但是,Android的多用户机制并不完全等同于Linux的用户组机制,它们之间依然有较大的差异。
453 0
|
1天前
|
安全 Android开发 iOS开发
探索Android与iOS开发的差异:平台特性与用户体验的对比分析
在移动应用开发的广阔天地中,Android和iOS两大阵营各据一方。本文将深入探讨这两个操作系统在开发环境、编程语言、用户界面设计及市场分布等方面的主要区别。通过比较分析,我们将揭示各自平台的特有优势,并讨论如何根据目标受众和业务需求选择适合的开发平台。
|
1天前
|
前端开发 JavaScript Android开发
手机APP开发|基于安卓APP实现掌上党支部——党员app
手机APP开发|基于安卓APP实现掌上党支部——党员app
|
2天前
|
安全 Java Android开发
探索Android与iOS开发的差异与挑战
在移动应用开发的广阔天地里,Android和iOS两大平台各自占据半壁江山。本文将深入探讨这两个平台的开发环境、工具、语言以及设计理念的差异,并分析这些差异给开发者带来的挑战。我们将从多个角度出发,包括用户界面设计、性能优化、安全性考量、以及市场分布等方面,为读者提供一个全面的视角,以理解在这两个平台上进行开发时需要考虑的关键因素。
|
3天前
|
存储 Android开发 Kotlin
Kotlin开发安卓app,在使用 MediaPlayer 播放 res/raw 中的音乐时遇到突然中断的问题,而 onErrorListener 没有接收到任何报错
在使用 Android MediaPlayer 播放 res/raw 中的音乐时遇到中断问题,可能的原因包括资源问题、媒体文件编码格式、生命周期管理和设备资源配置。要排查问题,检查音频文件是否正确包含,格式编码是否支持,MediaPlayer 是否正确管理及释放,以及设备是否有足够存储和配置。通过设置 onErrorListener 日志和确保在 onDestroy 中释放资源来调试。如果文件过大,考虑使用 AssetManager。遵循这些步骤可帮助诊断并解决播放中断的问题。
|
3天前
|
Android开发 Kotlin
kotlin开发安卓应用 如何修改app安装后的名称
在 Android 应用中,要修改安装后的显示名称,需更新 AndroidManifest.xml 文件中 application 标签的 android:label 属性。可直接在该属性内设置新名称,或在 res/values/strings.xml 文件中修改 app_name 并在 manifest 中引用。推荐使用 strings.xml 方式,以便支持多语言和集中管理。
|
4天前
|
缓存 Android开发 Kotlin
【安卓app开发】kotlin Jetpack Compose框架 | 先用OKhttp下载远程音频文件再使用ExoPlayer播放
使用 Kotlin 的 Jetpack Compose 开发安卓应用时,可以结合 OkHttp 下载远程音频文件和 ExoPlayer 进行播放。在 `build.gradle` 添加相关依赖后,示例代码展示了如何下载音频并用 ExoPlayer 播放。代码包括添加依赖、下载文件、播放文件及简单的 Compose UI。注意,示例未包含完整错误处理和资源释放,实际应用需补充这些内容。
|
4天前
|
移动开发 安全 Android开发
探索安卓应用开发的新趋势:Kotlin与Jetpack Compose的融合
在移动开发领域,Android系统持续创新,为开发者提供更高效的工具和框架。近年来,Kotlin语言因其简洁性和现代化特性成为Android开发的首选语言。与此同时,Jetpack Compose作为一种新的UI工具集,正改变着Android界面的开发方式。本文将深入探讨Kotlin与Jetpack Compose的结合使用,分析它们如何共同推动Android应用开发进入一个更加高效、可维护和响应式的新时代。