# 可信设备群组管理开发指导<a name="ZH-CN_TOPIC_0000001059937740"></a>

-   [场景介绍](#section18502174174019)
-   [接口说明](#section1633115419401)
-   [开发步骤](#section17516229192313)
-   [调测验证](#section427316292411)

## 场景介绍<a name="section18502174174019"></a>

当分布式业务需要利用软总线提供的设备间安全会话通信时，可以使用可信设备群组管理服务在设备间创建可信群组。在OpenHarmony下提供异账号下基于PIN、二维码、碰一碰等设备认证能力和同华为账号群组下的设备认证能力，分布式应用可基于该能力建立和使用设备间的安全可信关系。对于未登录华为账号的设备，可以通过PIN码输入、二维码扫描后获取的设备连接信息和PIN码信息，再通过可信设备群组管理提供的群组创建，群组成员添加，主动建立设备间可信关系；在有其它业务应用已经创建并分享了设备可信群组的情况下或者登录了相同的华为账号后，也可以通过可信设备群组管理提供的查询能力，复用这些可信群组。

## 接口说明<a name="section1633115419401"></a>

可信群组管理组件当前提供innerkits接口，仅供系统应用调用，相关接口及功能描述如下：

**表 1**  群组管理器提供的JAVA API接口功能介绍

<a name="table1731550155318"></a>
<table><thead align="left"><tr id="row4419501537"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p54150165315"><a name="p54150165315"></a><a name="p54150165315"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p941150145313"><a name="p941150145313"></a><a name="p941150145313"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row34145016535"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p188293163217"><a name="p188293163217"></a><a name="p188293163217"></a>public static DeviceGroupManager getInstance(Abilityability, StringappID, IHichainGroupCallbackcallbackHandler)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p13562171015712"><a name="p13562171015712"></a><a name="p13562171015712"></a>获取群组管理的实例，并注册一个请求的listen回调。</p>
</td>
</tr>
<tr id="row1746172917474"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p2131144717619"><a name="p2131144717619"></a><a name="p2131144717619"></a>int createGroup(String appId, String groupName, int groupType, String groupInfo)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p2431455765"><a name="p2431455765"></a><a name="p2431455765"></a>创建一个可信群组。</p>
</td>
</tr>
<tr id="row10992232154714"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p685215538611"><a name="p685215538611"></a><a name="p685215538611"></a>public int deleteGroup(String gourpId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p126575774517"><a name="p126575774517"></a><a name="p126575774517"></a>删除一个可信群组。</p>
</td>
</tr>
<tr id="row67932413301"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p98022416308"><a name="p98022416308"></a><a name="p98022416308"></a>public String getLocalConnectInfo()</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p4801624183014"><a name="p4801624183014"></a><a name="p4801624183014"></a>获取本地设备的网络连接信息。</p>
</td>
</tr>
<tr id="row1440154863415"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1040284812348"><a name="p1040284812348"></a><a name="p1040284812348"></a>int addMemberToGroup(String appId, long requestId, String addParams, String connectParams, int groupType)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p240224817343"><a name="p240224817343"></a><a name="p240224817343"></a>添加成员到指定群组ID的可信群组。</p>
</td>
</tr>
<tr id="row495164812345"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1795174853413"><a name="p1795174853413"></a><a name="p1795174853413"></a>int deleteMemberFromGroup(String appId, long requestId, String deleteParams, String connectParams)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1995144893411"><a name="p1995144893411"></a><a name="p1995144893411"></a>从指定群组里删除可信成员。</p>
</td>
</tr>
<tr id="row4107114933418"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p3107194923412"><a name="p3107194923412"></a><a name="p3107194923412"></a>int cancelRequest(long requestId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p11107849113418"><a name="p11107849113418"></a><a name="p11107849113418"></a>取消正在进行的请求，如添加成员，删除成员。</p>
</td>
</tr>
<tr id="row3270349193419"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p72707495346"><a name="p72707495346"></a><a name="p72707495346"></a>List&lt;String&gt; listJoinedGroups(int groupType)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p12701049183411"><a name="p12701049183411"></a><a name="p12701049183411"></a>查询指定群组类型下本设备加入的群组信息列表。</p>
</td>
</tr>
<tr id="row84091549103413"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p440914915343"><a name="p440914915343"></a><a name="p440914915343"></a>List&lt;String&gt; listTrustedDevices(String groupId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p104091749163412"><a name="p104091749163412"></a><a name="p104091749163412"></a>查询指定群组里可信设备的信息列表。</p>
</td>
</tr>
<tr id="row76661118163810"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p566691863810"><a name="p566691863810"></a><a name="p566691863810"></a>boolean isDeviceInGroup(String groupId, String deviceId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p17666618193818"><a name="p17666618193818"></a><a name="p17666618193818"></a>查询指定设备ID的设备是否加入了指定ID的群组。</p>
</td>
</tr>
<tr id="row8648246163810"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p564914683820"><a name="p564914683820"></a><a name="p564914683820"></a>List&lt;String&gt; getGroupInfo(String queryParams)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p96491546173820"><a name="p96491546173820"></a><a name="p96491546173820"></a>根据输入参数，查询符合条件的群组的信息列表。</p>
</td>
</tr>
<tr id="row6118113464013"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p41191334164018"><a name="p41191334164018"></a><a name="p41191334164018"></a>int setFriendsList(String groupId, List&lt;String&gt; friendsList)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1511919343403"><a name="p1511919343403"></a><a name="p1511919343403"></a>向指定ID的群组，添加群组访问的友元名单</p>
</td>
</tr>
<tr id="row214411864111"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p3145131814120"><a name="p3145131814120"></a><a name="p3145131814120"></a>List&lt;String&gt; getFriendsList(String groupId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p201450182414"><a name="p201450182414"></a><a name="p201450182414"></a>获取指定群组里的友元名单</p>
</td>
</tr>
<tr id="row15812171974119"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p208122190416"><a name="p208122190416"></a><a name="p208122190416"></a>int registerGroupNotice(String groupId, IHichainGroupChangeListener groupChangeListener)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p581281912419"><a name="p581281912419"></a><a name="p581281912419"></a>注册指定群组发生变化的回调listen</p>
</td>
</tr>
<tr id="row14944183024217"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p79441930184212"><a name="p79441930184212"></a><a name="p79441930184212"></a>int revokeGroupNotice(String groupId)</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p159441630134217"><a name="p159441630134217"></a><a name="p159441630134217"></a>取消对指定群组变化的listen</p>
</td>
</tr>
</tbody>
</table>

**表 2**  群组管理器提供的C++ API，供内部系统应用通过SA查询群组信息；

<a name="table16387194455318"></a>
<table><thead align="left"><tr id="row4387544135313"><th class="cellrowborder" valign="top" width="57.38999999999999%" id="mcps1.2.3.1.1"><p id="p1838719449537"><a name="p1838719449537"></a><a name="p1838719449537"></a>接口名</p>
</th>
<th class="cellrowborder" valign="top" width="42.61%" id="mcps1.2.3.1.2"><p id="p113872044195317"><a name="p113872044195317"></a><a name="p113872044195317"></a>描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row83871844115314"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p0387174425316"><a name="p0387174425316"></a><a name="p0387174425316"></a>DeviceAuthProxy()</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p143877448539"><a name="p143877448539"></a><a name="p143877448539"></a>获取一个可信群组管理代理的实例。</p>
</td>
</tr>
<tr id="row93871544185318"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p19387144105311"><a name="p19387144105311"></a><a name="p19387144105311"></a>~DeviceAuthProxy()</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p9387944115313"><a name="p9387944115313"></a><a name="p9387944115313"></a>可信群组管理代理的实例的析构函数。</p>
</td>
</tr>
<tr id="row16387144175313"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p6553322195518"><a name="p6553322195518"></a><a name="p6553322195518"></a>static int CheckAccessToGroup(const std::string &amp;groupId, const std::string &amp;pkgName);</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p9387174414536"><a name="p9387174414536"></a><a name="p9387174414536"></a>判断指定包名的应用，是否对指定群组具有访问权限。</p>
</td>
</tr>
<tr id="row12387194418531"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p1338714416537"><a name="p1338714416537"></a><a name="p1338714416537"></a>static int CheckAccessToDevice(const std::string &amp;connDeviceId, const std::string &amp;pkgName);</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p938794418538"><a name="p938794418538"></a><a name="p938794418538"></a>判断指定包名的应用，对指定的设备所加入的群组，是否具有访问权限。</p>
</td>
</tr>
<tr id="row1238744411534"><td class="cellrowborder" valign="top" width="57.38999999999999%" headers="mcps1.2.3.1.1 "><p id="p9218125135811"><a name="p9218125135811"></a><a name="p9218125135811"></a>static std::vector&lt;std::string&gt; GetRelatedGroupInfo(const std::string &amp;connDeviceId);</p>
</td>
<td class="cellrowborder" valign="top" width="42.61%" headers="mcps1.2.3.1.2 "><p id="p1388124411537"><a name="p1388124411537"></a><a name="p1388124411537"></a>获取指定ID的设备与本地设备存在可信管理的所有群组的基本信息。</p>
</td>
</tr>
</tbody>
</table>

## 开发步骤<a name="section17516229192313"></a>

群组管理的开发步骤比较简单，大体的流程就是先获取一个实例，获取实例的同时就注册了群组操作结果的通知回调，获取到实例后就可以对群组进行成员的添加、删除和群组的友元设置以及群组的相关的查询操作。

**场景一**  创建群组，下面首先以创建群组为例，说明群组管理类的创建以及接口使用方法：

```
private HwDeviceGroupManager hwDeviceGroupManager;
...
private HichainGroupCallback groupCallbackByA = new HichainGroupCallback() {
    @Override public void onFinish(long requestId, GroupOperation operationCode, String returnData) {

    }    
    @Override public void onError(long requestId, GroupOperation operationCode, int errorCode, String errorReturn) { 

    }    
    @Override public String onRequest(long requestId, GroupOperation operationCode, String reqParams) {
        JSONObject onRequestJson = generateConfirmation(REQUEST_ACCEPTED);       
        return onRequestJson.toString();
    }
};
...
Optional<Context> context = convertAbilityToContext(mAbility);
Context ctxt = context.get();
hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA);
int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO);
```

1.  在类成员里申明群组管理实例的私有成员变量

    ```
    private HwDeviceGroupManager hwDeviceGroupManager;
    ```

2.  创建一个群组管理操作回调；

    ```
    private HichainGroupCallback groupCallbackByA = new HichainGroupCallback();
    ```

3.  在构造函数里创建一个群组管理的实例, 在分布式场景中，位于不同设备的同业务应用，应该设置相同的APP\_ID；

    ```
    hwDeviceGroupManager = HwDeviceGroupManager.getInstance(ctxt, APP_ID, groupCallbackByA);
    ```

4.  调用createGroup创建一个群组，当函数返回为0，在表明创建群组的请求已正确提交；

    ```
    int ret = hwDeviceGroupManager.createGroup(APP_ID, GROUP_NAME, GROUP_TYPE, GROUP_INFO);
    ```

5.  群组创建成功，会收到一个onFinish的回调，回调函数中operationCode参数为OperationCode.CREATE, 表明是创建群组操作，returnData为Json格式数据，会包含一个“groupId”的字段，返回创建的群组的Id值。

**场景二**  添加成员，在创建群组后，我们希望把目标设备经过设备认证加入到群组中，后续就可以通过软总线向目标设备发起可信的加密通信；

```
deviceGroupManager = DeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback);
private static final String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}";
private static final String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}";
private static final int GROUP_TYPE = 256;
int result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE);
```

1.  获取群组管理的实例；

    ```
    deviceGroupManager = HwDeviceGroupManager.getInstance(mAbility, APP_ID, hichainGroupCallback);
    ```

2.  设置添加成员的网络连接参数，为JSON格式，为软总线支持的网络参数字段，包括WIFI\_IP，WIFI\_PORT，BLR\_MAC，DEVICE\_ID等，具体连接参数要求参见软总线；

    ```
    String CONN_PARAM ="{\"DEVICE_ID\":\"11111111\",\"WIFI_IP\":\"192.168.43.149\",\"WIFI_PORT\":\"30000\",\"BLE_MAC\":\"\"}";
    ```

3.  设置添加成员的成员信息参数，为JSON格式，包括欲添加的群组ID，群组名，是否是管理员，若是主动邀请对方加入，则isAdmin字段为true，若是主动加入对方群组，则isAdmin为false

    ```
    String ADD_PARAM ="{\"groupId\":\"344C1C8B149\",\"groupName\":\"myGroup\",\"addId\":\"11111111\",\"isAdmin\":\"false\"}";
    ```

4.  设置欲添加的群组的群组类型为256，即点对点群组；

    ```
    private static final int GROUP_TYPE = 256;
    ```

5.  在HichainGroupCallback 的onRequest函数，参见场景一列出的generateConfirmation传入指定的参数，其中PIN\_CODE为为PIN码，由上层业务提供界面给用户输入，确保分布式场景两端设置的PIN码一致，后续步骤才能成功；

    ```
    private JSONObject generateConfirmation(int confirmation) {    
        JSONObject jsonObject = new JSONObject();    
        try {    jsonObject.put("pinCode", PIN_CODE);
                 jsonObject.put("confirmation", confirmation);    
        } catch (JSONException e) {
            LogUtil.error(TAG, "" + e.getMessage());    
        }
        return jsonObject;
    }
    ```

6.  调用群组管理的添加成员接口

    ```
    result = deviceGroupManager.addMemberToGroup(APP_ID, reqId, ADD_PARAM, CONN_PARAM, GROUP_TYPE);
    ```

7.  若添加成功，将会收到HichainGroupCallback.onFinish的回调，其中operationCode参数为OperationCode.JOIN
8.  添加成员成功后，业务可以调用软总线请求创建设备间安全会话。

## 调测验证<a name="section427316292411"></a>

1 在OpenHarmony上开发应用App。

2 根据开发指导开发，开发应用App。

3 执行创建群组操作，如果收到onFinish回调，代表创建群组成功。

4 在分布式组网的节点部署相同的App，假设当前部署的有节点A和节点B；

5 通过上层将节点B的连接参数，通过扫码的方式，传递到节点A，

6 节点A上App创建一个群组group1，节点A上App调用添加成员接口，将B加入到group1中，若收到HichainGroupCallback.onFinish，表明加入群组成功；

