#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability

目錄:json

1. 跨設備遷移前的準備工做 分佈式

2. 獲取設備列表 ide

3. 根據設備ID調用Page Ability 佈局

 

#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability

  HarmonyOS的核心特性(或稱爲賣點)之一就是軟總線技術,而Page Ability的跨設備遷移是軟總線的一個具體技術實現。所謂跨設備遷移Page Ability,是指設備A中的特定App調用設備B中該App的Page Ability。這有一個前提,就是設備A和設備B都安裝了同一個App。若是B設備沒有安裝App,B設備就會自動從華爲應用商店下載這個App,固然,這一過程是徹底靜默的。下載完後,就會自動啓動相應的Page Ability。這種技術不只能夠啓動另外一個設備上的Page Ability,還能夠向另外一個設備中的Page Ability傳遞數據。post


 這種技術的一個主要應用場景是,能夠將在設備A上完成了一半的工做,遷移到設備B上繼續完成。例如,在家中平板電腦上要回一封EMail,但臨時有急事,須要出門,這時能夠將在平板電腦上寫了一半的EMail遷移到手機上,須要在路上完成剩下的工做。this


1. 跨設備遷移前的準備工做
在進行跨設備遷移以前,須要爲HarmonyOS設備作一下準備:
(1) 打開HarmonyOS設備中的藍牙;
(2)HarmonyOS設備須要連入Wi-Fi,並且多個HarmonyOS須要在同一個網段;
(3)多個HarmonyOS設備須要用同一個華爲開發者帳號登陸,如圖1所示。
#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability
圖1 用同一個華爲開發者帳號登陸url


(4)點擊「設置」>「更多鏈接」>「多設備協同」,進入多設備協同學口,打開多設備協同開關,如圖2所示。spa

#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability

圖2 多設備協同.net


(5)修改HarmonyOS設備名。點擊「設置」>「藍牙」>「設備名稱」,進入設備名稱窗口,輸入一個新的什麼名稱,如圖3所示。儘管這一步不是必須的,但若是擁有多部HarmonyOS設備,可能不少HarmonyOS設備的名稱是相同或相近的。爲了更好區分不一樣的HarmonyOS設備,建議修改HarmonyOS設備名稱。3d


#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability

圖3 修改HarmonyOS設備名稱


2 獲取設備列表


跨設備遷移是經過設備ID來區分不一樣設備的,因此首先要獲取全部可用的設備的ID。獲取設備ID須要調用DeviceManager.getDeviceList方法,該方法返回一個List對象,類型是DeviceInfo,用來描述設備的相關信息,包括設備ID、設備名稱(就是上一節設置的設備名稱)等。實現代碼以下:

List<DeviceInfo> deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);

  • getDeviceList方法有一個參數,是一個int類型的值,表示獲取什麼狀態的設備的信息。能夠指定的值以下:
    (1) DeviceInfo.FLAG_GET_ONLINE_DEVICE:獲取全部在線設備的信息;
    (2) DeviceInfo. FLAG_GET_OFFLINE_DEVICE:獲取全部離線設備的信息;
    (3) DeviceInfo. FLAG_GET_ALL_DEVICE:獲取全部設備的信息;
    一般會使用第1個值,獲取全部在線設備的信息,由於只有設備在線,才能將Page Ability遷移到該設備上。


下面給出一個案例,該案例實現了一個通用的顯示可用設備列表的Page Ability,點擊某一個設備,會返回該設備的ID,


在device_ids.xml佈局文件中放置了一個ListContainer組件,用於顯示獲取的全部可用設備的相關信息。實現代碼以下:

public class DeviceIdsAbility extends Ability {
    // 保存獲取到的全部設備的信息
    private List<DeviceInfo> deviceInfos;
    private ListContainer listContainerDeviceIds;
    // 獲取全部可用的設備的相關信息
    public static List<DeviceInfo> getAvailableDeviceIds() {
        List<DeviceInfo> deviceInfoList =
                DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
        if (deviceInfoList == null) {
            return new ArrayList<>();
        }
        if (deviceInfoList.size() == 0) {
            return new ArrayList<>();
        }
        return deviceInfoList;
    }
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_device_ids);
        deviceInfos = getAvailableDeviceIds();
        listContainerDeviceIds = 、
        (ListContainer)findComponentById(ResourceTable.Id_listcontainer_deviceids);
        if(listContainerDeviceIds != null) {
            // 爲ListContainer組件設置列表項監聽器
            listContainerDeviceIds.setItemClickedListener(new ListContainer.ItemClickedListener() {
                @Override
                public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
                    // 當單擊某個列表項(設備)後,會獲取該設備的ID,並將這個ID做爲Page Ability
                    // 的結果返回
                    String deviceId = deviceInfos.get(i).getDeviceId();
                    Intent intent = new Intent();
                    intent.setParam("deviceId", deviceId);
                    setResult(100,intent);
                    // 關閉當前的Page Ability
                    terminateAbility();
 
                }
            });
            // 爲ListContainer組件設置Provider
            listContainerDeviceIds.setItemProvider(new RecycleItemProvider() {
                @Override
                public int getCount() {
                    return deviceInfos.size();
                }
 
                @Override
                public Object getItem(int i) {
                    return deviceInfos.get(i);
                }
 
                @Override
                public long getItemId(int i) {
                    return i;
                }
 
                @Override
                public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
                    if(component == null) {
                        // 若是component爲null,說明沒有能夠利用的列表項視圖,因此要從佈局文件
                        // 裝載一個新的視圖對象
                        component = (DirectionalLayout)LayoutScatter.getInstance(DeviceIdsAbility.this).parse(ResourceTable.Layout_device_id_item,null,false);
                    }
                    Text textDeviceName = (Text)component.findComponentById(ResourceTable.Id_text_device_name);
                    Text textDeviceId = (Text)component.findComponentById(ResourceTable.Id_text_device_id);
                    if(textDeviceName != null) {
                        // 顯示設備名
                        textDeviceName.setText(deviceInfos.get(i).getDeviceName());
                    }
                    if(textDeviceId != null) {
                        // 顯示設備ID
                        textDeviceId.setText(deviceInfos.get(i).getDeviceId());
                    }
                    return component;
                }
            });
 
        }
 
    }
}


在DeviceIdsAbility類中爲ListContainer組件裝載列表項時,在getComponent方法中利用了第2個參數component,該參數就是列表項的根視圖。若是component爲null,代表並無能夠利用的列表項視圖,因此要建立一個新的列表項視圖。若是不爲null,代表能夠利用其餘的尚未顯示的列表項視圖,只須要替換該視圖的Text組件中顯示的信息便可。
最後在config.json文件中添加一些與分佈式相關的權限。

"reqPermissions": [
      {
        "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
      },
      {
        "name": "com.huawei.permission.ACCESS_DISTRIBUTED_ABILITY_GROUP"
      },
      {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
      }
]


運行程序,會看到如圖4所示的設備列表。


#2020徵文-手機#【鴻蒙基地】鴻蒙跨設備啓動窗口:Page Ability

                                                                                                                          圖4 獲取可用設備的ID

要注意的是,經過DeviceManager.getDeviceList方法只能獲取其餘設備的信息,不能獲取自身的信息,例如,有設備A、設備B和設備C。在設備A中只能獲取設備B和設備C的信息,而不能獲取設備A的信息。在設備B和設備C中的表現也相似。

查看更多章節>>>

做者:李寧

想了解更多內容,請訪問: 51CTO和華爲官方戰略合做共建的鴻蒙技術社區https://harmonyos.51cto.com/

相關文章
相關標籤/搜索