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.

相关文章
|
10月前
|
存储 XML 搜索推荐
【车载Android】多用户(一) - Linux用户与Android多用户
Android是一个基于Linux内核的操作系统,它支持多用户模式,即可以在同一台设备上创建多个用户账户,每个用户都有自己的应用、数据和设置。这样可以保护用户的隐私,也可以方便不同的使用场景。但是,Android的多用户机制并不完全等同于Linux的用户组机制,它们之间依然有较大的差异。
412 0
|
6天前
|
设计模式 算法 前端开发
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
Android面经分享,失业两个月,五一节前拿到Offer,设计思想与代码质量优化+程序性能优化+开发效率优化
|
4天前
|
编解码 数据库 Android开发
安卓应用开发:打造高效用户界面的五大技巧
【5月更文挑战第18天】在竞争激烈的应用市场中,一个流畅且直观的用户界面(UI)对于安卓应用的成功至关重要。本文将探讨五种提升安卓应用用户界面性能的技巧,包括合理布局设计、优化资源使用、利用硬件加速、内存管理以及响应式编程。通过这些方法,开发者可以创建出既美观又高效的应用体验,从而吸引和保留用户。
|
6天前
|
XML Android开发 数据格式
ConstraintLayout 2,Android高级开发面试
ConstraintLayout 2,Android高级开发面试
|
2天前
|
搜索推荐 API Android开发
安卓应用开发:打造高效通知管理系统
【5月更文挑战第20天】在移动设备中,通知管理是用户体验的关键部分。一个高效的通知系统不仅能够及时传达重要信息,还能避免用户感到不必要的干扰。本文将深入探讨如何在安卓平台上开发一个高效的通知管理系统,包括通知的设计、发送策略以及用户的个性化设置。通过分析安卓系统的通知机制和最新的API特性,我们将提供一个实用的开发指南,帮助开发者创建更加智能和用户友好的通知体验。
|
5天前
|
JSON Android开发 数据格式
Android框架-Google官方Gson解析,android开发实验报告总结
Android框架-Google官方Gson解析,android开发实验报告总结
|
5天前
|
前端开发 Android开发
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
Android架构组件JetPack之DataBinding玩转MVVM开发实战(四)
|
5天前
|
安全 Linux Android开发
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework
Android最强保活黑科技的最强技术实现,2024年最新阿里资深Android开发带你搞懂Framework