在这里插入图片描述

1 -> 概述

随着企业数字化转型的深入,终端设备在办公场景中的角色日益重要,“一机两用”、“一企多网”的需求在政府、央国企、商业银行等机构中尤为突出——既要使用个人社交娱乐应用,又要安全访问企业办公数据,二者的隔离与协同成为关键痛点。HarmonyOS 6.0 在 Enterprise Space Kit(企业数字空间服务)中正式推出了空间管理服务,提供了一套统一的空间管理能力,让 MDM 应用能够以编程方式对设备上的工作空间进行全生命周期管控。

Enterprise Space Kit 是 HarmonyOS 6.0 新增的高阶 Kit 能力之一,为企业安全管控类 MDM 应用提供高效、智能的数据传输能力,支持空间数据的管理与应用服务。通过严格的跨空间数据传输审核流程,确保数据传输的安全与合规性,实现空间数据的独立管理与隔离。

空间管理服务的核心功能包括:创建工作空间移除工作空间订阅空间事件等。对于 MDM 应用开发者而言,这意味着可以在企业自有设备或 BYOD 设备上,通过一套标准化的 API 来建立和维护独立的办公空间,实现企业数据的隔离管控和空间切换事件的实时感知。以下将从环境准备开始,逐步深入到各功能接口的详细使用方式。

2 -> 开发环境准备与权限配置

2.1 -> 环境要求

使用 Enterprise Space Kit 空间管理服务前,需确保开发环境满足以下条件:

  • HarmonyOS 版本:HarmonyOS 6.0.0 Release 或更高版本
  • DevEco Studio 版本:DevEco Studio 6.0.0 Release 或更高版本
  • HarmonyOS SDK 版本:HarmonyOS 6.0.0 Release SDK 或更高版本

2.2 -> 约束与限制

在进行正式开发前,有几个重要的约束条件需要了解:

  • 支持的国家和地区:当前仅支持在中国境内(香港特别行政区、澳门特别行政区、中国台湾除外)提供服务。
  • 支持的设备类型:当前设备类型仅支持 PC/2in1 设备,具体型号为华为擎云系列。
  • 模拟器支持:Enterprise Space Kit 暂不支持模拟器进行开发和调试。
  • 访问限制:企业数字空间服务使能后,经过空间切换,处于后台的空间,其公共目录数据可能无法访问。
  • 空间数量限制:从 6.1.0(23) 版本开始,最多可创建 2 个工作空间。

2.3 -> 权限申请

使用空间管理服务需要申请相应的权限。在 module.json5 文件中配置以下权限:

"requestPermissions": [
    {
        "name": "ohos.permission.ENTERPRISE_MANAGE_LOCAL_PUBLICSPACES"
    },
    {
        "name": "ohos.permission.QUERY_LOCAL_WORKSPACES"
    },
    {
        "name": "ohos.permission.ENTERPRISE_WORKSPACES_EVENT_SUBSCRIBE"
    }
]

各权限的作用如下:

权限 用途
ohos.permission.ENTERPRISE_MANAGE_LOCAL_PUBLICSPACES 管理工作空间生命周期(创建、移除等)
ohos.permission.QUERY_LOCAL_WORKSPACES 查询工作空间信息
ohos.permission.ENTERPRISE_WORKSPACES_EVENT_SUBSCRIBE 订阅空间事件

除上述权限外,创建工作空间也可使用 ohos.permission.MANAGE_LOCAL_WORKSPACES 权限替代。

2.4 -> 模块导入

在需要使用空间管理服务的 ArkTS 文件中,首先导入 spaceManager 模块:

import { spaceManager } from '@kit.EnterpriseSpaceKit';
import { BusinessError } from '@kit.BasicServicesKit';

3 -> 核心功能详解

3.1 -> 创建工作空间

createWorkspace 接口用于创建一个新的工作空间,是空间管理的起点。该接口从 6.0.0(20) 版本开始提供,采用 Promise 异步回调的方式返回执行结果。

3.1.1 -> API 定义

createWorkspace(localName: string, workspaceType: WorkspaceType, params?: CreateWorkspaceParams): Promise<WorkspaceInfo>

3.1.2 -> 参数说明

参数名 类型 必填 说明
localName string 工作空间的本地名称
workspaceType WorkspaceType 工作空间类型,可选 ADMIN(管理员工作空间)或 NORMAL(普通工作空间)
params CreateWorkspaceParams 创建工作空间的额外配置参数

WorkspaceType 枚举定义:

名称 说明
ADMIN 0 管理员工作空间,具有管理其他工作空间的权限
NORMAL 1 普通工作空间

CreateWorkspaceParams 接口定义:

名称 类型 必填 说明
shortName string 工作空间的本地简称,其值与 localName 一致

3.1.3 -> 版本说明

从 6.1.0(23) 版本开始,创建工作空间时增加了如下校验:

  • 最多可创建 2 个工作空间
  • 企业管理员设置禁止添加账号或关闭全盘解密后,无法创建工作空间

3.1.4 -> 返回值

返回 Promise<WorkspaceInfo> 对象,包含新创建工作空间的详细信息。

WorkspaceInfo 中的关键字段:

名称 类型 说明
workspaceId number 工作空间 ID,首个空间 ID 为 100,后续创建的工作空间 ID 逐一递增(如 101、102)
localName string 工作空间的本地账号名称
shortName string 工作空间的本地简称,与 localName 一致
isUnlocked boolean 工作空间是否处于解锁状态(true:解锁,false:锁屏)
photo string 工作空间的资料照片,由本地照片的 Base64 格式拼接成的 JSON 字符串
createTime number 工作空间创建时间

3.1.5 -> 完整代码示例

import { spaceManager } from '@kit.EnterpriseSpaceKit';
import { BusinessError } from '@kit.BasicServicesKit';

async function createNewWorkspace(): Promise<void> {
    // 设置工作空间名称
    const localName: string = 'EnterpriseWorkspace';
    // 指定工作空间类型为管理员空间
    const workspaceType: spaceManager.WorkspaceType = spaceManager.WorkspaceType.ADMIN;
    // 配置额外参数
    const params: spaceManager.CreateWorkspaceParams = {
        shortName: 'Ent'
    };

    try {
        const workspaceInfo: spaceManager.WorkspaceInfo = await spaceManager.createWorkspace(
            localName, 
            workspaceType, 
            params
        );
        console.info(`Succeeded in creating workspace:`);
        console.info(`  workspaceId: ${workspaceInfo.workspaceId}`);
        console.info(`  localName: ${workspaceInfo.localName}`);
        console.info(`  createTime: ${workspaceInfo.createTime}`);
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to create workspace. Code: ${error.code}, message: ${error.message}`);
    }
}

3.1.6 -> 常见错误码

错误码 错误信息 说明
201 Permission denied 应用缺少所需权限
1020400001 System service exception 系统服务异常
1020400002 Parameter error 参数无效
1020400003 Invalid workspace 工作空间无效(如数量已达上限)
1020400007 Enterprise workspace not enabled 企业空间未开启
1020400011 Account creation is not permitted 企业管理员禁止添加账号
1020400012 Full disk encryption is not enabled 全盘解密未开启

3.2 -> 移除工作空间

removeWorkspace 接口用于移除已创建的工作空间,从 6.0.0(20) 版本开始提供。移除工作空间是一项不可逆的操作,执行前应确认目标空间的使用状态。

3.2.1 -> API 定义

removeWorkspace(workspaceId: number): Promise<void>

3.2.2 -> 参数说明

参数名 类型 必填 说明
workspaceId number 要移除的工作空间 ID,首个空间 ID 为 100,后续空间 ID 逐一递增

3.2.3 -> 返回值

返回 Promise<void>,无返回结果的 Promise 对象。

3.2.4 -> 权限要求

需要 ohos.permission.ENTERPRISE_MANAGE_LOCAL_PUBLICSPACESohos.permission.MANAGE_LOCAL_WORKSPACES 权限。

3.2.5 -> 完整代码示例

import { spaceManager } from '@kit.EnterpriseSpaceKit';
import { BusinessError } from '@kit.BasicServicesKit';

async function removeWorkspace(workspaceId: number): Promise<void> {
    try {
        await spaceManager.removeWorkspace(workspaceId);
        console.info(`Succeeded in removing workspace, id: ${workspaceId}`);
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to remove workspace. Code: ${error.code}, message: ${error.message}`);
    }
}

3.2.6 -> 实际使用建议

在实际业务场景中,移除工作空间前通常建议先确认该空间是否存在以及是否正在使用中:

import { spaceManager } from '@kit.EnterpriseSpaceKit';

async function queryAndRemoveWorkspace(targetId: number): Promise<boolean> {
    try {
        // 先查询所有工作空间
        const spaces: spaceManager.WorkspaceInfo[] = await spaceManager.queryWorkspace(
            spaceManager.QueryType.ALL
        );
        
        // 确认目标空间是否存在
        const targetSpace = spaces.find(space => space.workspaceId === targetId);
        if (!targetSpace) {
            console.error(`Workspace ${targetId} not found`);
            return false;
        }
        
        // 确认后再移除
        await spaceManager.removeWorkspace(targetId);
        console.info(`Workspace ${targetId} removed successfully`);
        return true;
    } catch (err) {
        console.error(`Failed: ${err.message}`);
        return false;
    }
}

3.2.7 -> 常见错误码

错误码 错误信息 说明
1020400003 Invalid workspace 工作空间不存在或类型不支持
1020400007 Enterprise workspace not enabled 企业空间未开启
1020400001 System service exception 系统服务异常

3.2.8 -> 注意事项

  • 工作空间移除后,该空间内的所有数据将一同被移除,无法恢复
  • 首个空间 ID 为 100,移除该空间时需特别谨慎
  • 若企业管理员关闭了企业空间功能,移除操作将返回 1020400007 错误

3.3 -> 订阅空间事件

subscribeEvent 接口用于订阅工作空间相关的事件,以便在事件发生时及时获知并执行相应的业务逻辑。该接口从 6.0.0(20) 版本开始提供。

3.3.1 -> API 定义

subscribeEvent(eventId: EventType[], callback: AsyncCallback<EventData>): number

3.3.2 -> 参数说明

参数名 类型 必填 说明
eventId EventType[] 订阅的空间事件类型列表
callback AsyncCallback<EventData> 事件触发时的回调函数,返回与空间事件相关的详细信息

EventType 枚举

名称 说明
EVENT_WORKSPACE_SWITCHED 0 工作空间切换事件

EventData 数据结构

名称 类型 说明
event EventType 触发的事件类型
currentWorkspaceId number 当前工作空间 ID

3.3.3 -> 返回值

返回 number 类型的订阅 ID(subscribeId),用于后续取消订阅。

3.3.4 -> 权限要求

需要 ohos.permission.ENTERPRISE_WORKSPACES_EVENT_SUBSCRIBE 权限。

3.3.5 -> 完整代码示例

import { spaceManager } from '@kit.EnterpriseSpaceKit';
import { BusinessError } from '@kit.BasicServicesKit';

function subscribeWorkspaceEvents(): number {
    try {
        const subscribeId: number = spaceManager.subscribeEvent(
            [spaceManager.EventType.EVENT_WORKSPACE_SWITCHED],
            (error: BusinessError | null, data: spaceManager.EventData) => {
                if (error) {
                    console.error(`Subscribe callback error: code=${error.code}, message=${error.message}`);
                } else {
                    console.info(`Event triggered: ${data.event}`);
                    console.info(`Current workspace ID: ${data.currentWorkspaceId}`);
                    
                    // 在此处添加业务处理逻辑
                    // 例如:刷新UI、同步数据、记录审计日志等
                    handleWorkspaceSwitch(data.currentWorkspaceId);
                }
            }
        );
        console.info(`Succeeded in subscribing event. subscribeId: ${subscribeId}`);
        return subscribeId;
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to subscribe event. Code: ${error.code}, message: ${error.message}`);
        return -1;
    }
}

function handleWorkspaceSwitch(workspaceId: number): void {
    // 根据工作空间ID执行相应的业务逻辑
    console.info(`Workspace switched to: ${workspaceId}`);
    // 例如:更新当前空间的应用配置、刷新数据展示等
}

3.3.6 -> 实际使用场景

空间事件订阅在 MDM 应用中有着广泛的应用场景:

  1. 日志审计:记录工作空间切换的完整时间线和操作轨迹
  2. 配置同步:根据当前工作空间动态切换应用配置(如网络代理、服务器地址等)
  3. 数据隔离:在空间切换时自动清理或同步本地缓存数据
  4. 权限控制:根据当前活跃空间调整应用的可用功能模块
  5. 状态同步:将空间切换状态上报至企业管理后台

3.4 -> 取消订阅空间事件

unsubscribeEvent 接口用于取消对空间事件的订阅。当应用关闭或特定功能模块不再使用时,应主动调用此 API 释放资源。

3.4.1 -> API 定义

unsubscribeEvent(subscribeId: number): void

3.4.2 -> 参数说明

参数名 类型 必填 说明
subscribeId number subscribeEvent 返回的订阅 ID

3.4.3 -> 完整代码示例

import { spaceManager } from '@kit.EnterpriseSpaceKit';
import { BusinessError } from '@kit.BasicServicesKit';

function unsubscribeWorkspaceEvents(subscribeId: number): void {
    try {
        spaceManager.unsubscribeEvent(subscribeId);
        console.info(`Succeeded in unsubscribing event, id: ${subscribeId}`);
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to unsubscribe event. Code: ${error.code}, message: ${error.message}`);
    }
}

4 -> 额外关键 API 介绍

除了前述三大核心功能外,空间管理服务还提供了一系列辅助接口,便于应用更精细地管理工作空间。

4.1 -> 查询工作空间(queryWorkspace)

queryWorkspace 接口用于查询设备上的工作空间列表,支持按类型筛选,从 6.0.0(20) 版本开始提供。

async function queryAllWorkspaces(): Promise<void> {
    try {
        const spaces: spaceManager.WorkspaceInfo[] = await spaceManager.queryWorkspace(
            spaceManager.QueryType.ALL
        );
        console.info(`Found ${spaces.length} workspace(s):`);
        spaces.forEach(space => {
            console.info(`  - ID: ${space.workspaceId}, Name: ${space.localName}, Unlocked: ${space.isUnlocked}`);
        });
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to query workspace. Code: ${error.code}, message: ${error.message}`);
    }
}

4.2 -> 设置工作空间域信息(setWorkspaceInfo)

setWorkspaceInfo 接口用于设置工作空间的企业域相关信息,该接口从 6.0.0(20) 版本开始提供。

async function setWorkspaceDomainInfo(workspaceId: number): Promise<void> {
    const domainInfo: spaceManager.WorkspaceDomainInfo = {
        domain: 'example.com',
        workspaceName: 'EnterpriseSpace',
        accountId: 'user001',
        isAuthenticated: true,
        serverConfigId: 'config:example.com',
        enterpriseWorkspaceName: '企业空间'
    };
    
    try {
        await spaceManager.setWorkspaceInfo(workspaceId, domainInfo);
        console.info(`Succeeded in setting workspace info for ${workspaceId}`);
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to set workspace info. Code: ${error.code}, message: ${error.message}`);
    }
}

4.3 -> 设置工作空间资料照片(setWorkspaceProfilePhoto)

setWorkspaceProfilePhoto 接口用于为工作空间设置头像照片。

async function setWorkspacePhoto(workspaceId: number, base64Photo: string): Promise<void> {
    const photo: string = `{"type":0,"defaultImg":"${base64Photo}"}`;
    
    try {
        await spaceManager.setWorkspaceProfilePhoto(workspaceId, photo);
        console.info(`Succeeded in setting workspace profile photo for ${workspaceId}`);
    } catch (err) {
        const error = err as BusinessError;
        console.error(`Failed to set photo. Code: ${error.code}, message: ${error.message}`);
    }
}

5 -> 异常处理与最佳实践

5.1 -> 错误码速查表

错误码 描述 常见触发场景
201 权限不足 未在 module.json5 中声明所需权限
1020400001 系统服务异常 系统服务繁忙、空间 ID 无效或文件处理类型未知
1020400002 请求参数无效 必填参数为空或参数类型错误
1020400003 工作空间无效 工作空间不存在、已存在、类型不支持或数量已达上限
1020400005 配置信息未设置 查询配置信息时,配置信息尚未设置
1020400006 SA 进程异常退出 服务进程异常退出,需重新订阅空间事件
1020400007 企业空间未开启 企业管理员未使能企业空间功能

5.2 -> 最佳实践建议

1. 合理管理订阅生命周期

空间事件订阅的订阅者对象生命周期需要接入方管理,不再使用时需主动销毁释放,避免内存泄漏。建议在应用启动时进行订阅,在应用退出或功能模块卸载时取消订阅:

// 应用启动时
onCreate(): void {
    this.subscribeId = subscribeWorkspaceEvents();
}

// 应用退出或页面销毁时
onDestroy(): void {
    if (this.subscribeId !== undefined) {
        spaceManager.unsubscribeEvent(this.subscribeId);
    }
}

2. 创建空间前的状态检查

在调用 createWorkspace 前,应先查询当前工作空间数量,避免因超过限制而导致操作失败(从 6.1.0 起最多可创建 2 个)。同时确认企业空间功能已由管理员开启。

3. 异步操作的错误处理

所有空间管理 API 均为异步操作,建议统一封装 try-catch 进行错误处理,并根据错误码类型决定是重试还是降级处理。

4. 空间 ID 的有效性验证

工作空间 ID 从 100 开始递增,在执行 removeWorkspace 等需要 ID 的操作前,建议先通过 queryWorkspace 确认 ID 有效性,避免操作无效空间。

5. 充分利用生命周期回调

在应用被切换到后台时,主动取消不必要的空间事件订阅,减少系统资源消耗;返回前台时重新订阅,确保事件感知的连续性。

6 -> 总结

HarmonyOS 6.0 Enterprise Space Kit 的空间管理服务为 MDM 应用开发者提供了一套完整、标准化的空间生命周期管理能力。从 API 设计来看,其显著特点包括:

  • 接口精简且语义清晰:创建、查询、移除、订阅四个核心 API 覆盖了空间管理的全部闭环,开发者无需在多处拼凑逻辑即可完成完整的功能开发。
  • 企业级场景适配完整:不仅提供了基础的空间创建与移除,还通过事件订阅机制让 MDM 应用能够实时感知空间切换,从而联动执行审计、配置变更等企业管控策略。域账号信息(WorkspaceDomainInfo)的引入则为对接企业现有身份认证体系预留了标准化接口。
  • 安全隔离与管控并重:所有操作均需特定权限才能调用,结合企业管理员侧的开关控制,在确保数据安全隔离的同时赋予企业充分的管控灵活性。

在实际应用中,空间管理服务与 Enterprise Space Kit 的跨空间数据传输能力相互配合,形成了一套完整的企业数字空间解决方案。通过严格的空间数据传输审核流程,可以实现空间数据的独立管理与安全隔离。当前该服务已广泛应用于政府机构、大型科技企业、央国企、商业银行等“一机两用”、“一企多网”场景,为企业数据安全隔离和员工高效办公提供了可靠的底层技术支撑。

对于 MDM 应用开发者而言,合理利用空间管理服务的各项能力,可以显著提升应用的企业管控效率和数据隔离水平。建议开发者从创建工作空间起步,结合空间事件订阅实现全链路空间感知,最终与跨空间数据传输能力联动,构建完整的企业移动办公解决方案。


感谢各位大佬支持!!!

互三啦!!!
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐