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.

相关文章
|
存储 XML 搜索推荐
【车载Android】多用户(一) - Linux用户与Android多用户
Android是一个基于Linux内核的操作系统,它支持多用户模式,即可以在同一台设备上创建多个用户账户,每个用户都有自己的应用、数据和设置。这样可以保护用户的隐私,也可以方便不同的使用场景。但是,Android的多用户机制并不完全等同于Linux的用户组机制,它们之间依然有较大的差异。
762 0
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
2月前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
43 1
|
4天前
|
Dart 前端开发 Android开发
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【02】写一个注册页面以及配置打包选项打包安卓apk测试—开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
1月前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
65 19
|
2月前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
1月前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
70 14
|
1月前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。

热门文章

最新文章