Android Work Profile

本文基于 https://developer.android.google.cn/work/managed-profiles 翻译而成

 

Work Profile(工作面)或称为managed profile(被管理面)。

一个work profile由IT admin控制

一个work profile的可用功能基于用户的primary profile分别设置

Work profile功能允许组织控制公司特制应用和数据在用户设备上的运行环境,同时仍允许用户使用其个人的应用和profiles

概述

用户经常使用其个人设备处理公司事务(Users often want to use their personal devices in an enterprise setting.)。该情形可能使公司面临一种困境,即由于个人设备不受控制,公司不得不担心机密信息通过用户个人设备被泄露出去。

  如果设备有了work profile,则存在以下可能的影响。

默认大部分intent是无法跨越profile的。如果一个应用(app)发出的intent在其所在的profile中不存在,且不被允许跨越profile调用,则该应用(app)会因为请求intent失败而异常终止。

IT admin也能限制work profile中哪些应用(app)是有效的,这种限制也会造成work profile中的应用(app)无法处理常用intent请求

由于工作profile和个人profile使用独立的存储空间,所以一个profile的文件URI在另一个profile中往往是无效的,所以附带文件URI参数的intent请求是不安全的。

防止intent失败

(第一段赘述前文,略)

Profile admin可控制哪些intent可跨越profile。用户无法预知这些设定,且IT admin可随时改变这些策略。

在应用(app)启动一个activity前,应该调用Intent.resolveActivity()来验证是否intent可被接受。如果不能接受,则该调用返回空(null),如果返回非空,则说明该profile内存在至少一个有效activity来处理该intent请求,或是该intent被允许跨越profile被处理

例如,如果要设置时钟,需要先验证是否能处理ACTION_SET_TIMER。如果不能,应该给予适当的处理,如显示错误消息。

Kotlin

fun startTimer(message: String, seconds: Int) {

    // Build the "set timer" intent
    val timerIntent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(packageManager) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent)

    }
}

Java

public void startTimer(String message, int seconds) {

    // Build the "set timer" intent
    Intent timerIntent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(getPackageManager()) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent);

    }
}

跨越profile共享文件

有时一个应用(app)需要给予其他应用(app)对自身文件的访问权限,例如。一个图库app向图片编辑app共享其文件。一般采用两种实现方式:file URI和content URI。

“file URI”是一个以”file:”为前缀,后接文件绝对路径的字符串。但不同profile使用独立的存储空间,所以一个profile的 “file URI”在另一个profile中往往是无效的,将导致无法访问。

为解决该问题,你应该使用content URI,它以更安全的方式实现文件共享。它不仅含有文件路径,还有content ID。你可以用FileProvider来生成这个ID。通过共享content ID,其他app即使不在相同的profile,也可以访问到实际的文件。以下是例子。

Kotlin

// Open File object from its file URI
val fileToShare = File(fileUriToShare)

val contentUriToShare: Uri = FileProvider.getUriForFile(
        context,
        "com.example.myapp.fileprovider",
        fileToShare
)

Java

// Open File object from its file URI
File fileToShare = new File(fileUriToShare);

Uri contentUriToShare = FileProvider.getUriForFile(getContext(),
        "com.example.myapp.fileprovider", fileToShare);

当你调用 getUriForFile() 方法,你必须包含文件提供者的authority,上面的例子中是com.example.myapp.fileprovider。详情请参考Sharing Files

监听通知

  一个应用(app)往往提供NotificationListenerService 子类来接受系统的回调。含work profile的设备可能影响该工作机制。

在work profile中

你无法使用NotificationListenerService服务,系统会忽略work profile中应用的NotificationListenerService

在personal profile中

运行在personal profile的应用无法收到work profile的应用发出的通知,除非IT admin将其列入白名单。

从Android8.0(API level 26)起,DPC(device policy Controller)管理work profile,它提供DevicePolicyManager方法setPermittedCrossProfileNotificationListeners()阻止你的应用(app)监听来自work profile的通知。

测试应用(app)对work profile的兼容性

Google提供例程BasicManagedProfile,你能用它在Android5.0(API level 21)及更高版本设备上设置一个work profile。它提供简单的方法测试你的app在work profile环境中的表现。你也能用它来配置work profile

  • 在被管理的profile中指定有效的缺省app
  • 指定可以跨越work profile的intent

如果你通过usb连接手动安装一个应用(app),则该应用(app)即安装在personal profile,也安装在work profile。安装完成后,你能在以下条件下测试它。

  • 如果缺省app原本会处理某个intent,则在work profile中禁用那个缺省app,然后验证能正常处理该intent的app。(意思比较模糊)
  • 如果你发出一个intent并期望它被其他app处理,那就使能和禁用intent的权限来使其跨越profile。如果不允许某个intent跨越profile,则也在两种情况下测试。例如,如果你的app发出一个地图类intent,则在以下场景下测试。
    • 设备允许地图intent跨越profile,且另一侧profile中有合适的app。
    • 设备不允许地图intent跨越profile,app所在profile中有合适的app。
    • 设备不允许地图intent跨越profile, app所在profile中没有合适的app。
  • Intent中附带content URI,检查在可跨越profile及相反情形下是否可以访问。

有关测试的小技巧

在测试中使用以下小技巧可能对你有所帮助。

  • 如前所述,app会同时安装在两个profile中,你能删除任何一侧的app而保留另一侧。
  • Android Debug Bridge (adb)的很多activity manager命令支持--user选项,它用于让你以指定用户执行,你可以选择unmanaged primary user 或 work profile,详情参见ADB Shell Commands
  • 为了用“list users”命令找出设备上所有活跃用户,输出字符串中第一个数字式用户ID,你可以用这个ID作为--user选项的参数

例如,先运行以下指令列出设备上所有用户:

$ adb shell pm list users

UserInfo{0:Drew:13} running

UserInfo{10:Work profile:30} running

本例中主用户("Drew")的用户ID是0, work profile 的用户ID是10。 要在work profile中执行app,你应按照如下方式调用命令:

$ adb shell am start --user 10 \

-n "com.example.myapp/com.example.myapp.testactivity" \

-a android.intent.action.MAIN -c android.intent.category.LAUNCHER

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值