自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

【鴻蒙基地】鴻蒙跨設(shè)備啟動(dòng)窗口:Page Ability

開發(fā)
文章由鴻蒙社區(qū)產(chǎn)出,想要了解更多內(nèi)容請前往:51CTO和華為官方戰(zhàn)略合作共建的鴻蒙技術(shù)社區(qū)https://harmonyos.51cto.com/#zz

 [[374061]]

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz

HarmonyOS的核心特性(或稱為賣點(diǎn))之一就是軟總線技術(shù),而Page Ability的跨設(shè)備遷移是軟總線的一個(gè)具體技術(shù)實(shí)現(xiàn)。所謂跨設(shè)備遷移Page Ability,是指設(shè)備A中的特定App調(diào)用設(shè)備B中該App的Page Ability。這有一個(gè)前提,就是設(shè)備A和設(shè)備B都安裝了同一個(gè)App。如果B設(shè)備沒有安裝App,B設(shè)備就會(huì)自動(dòng)從華為應(yīng)用商店下載這個(gè)App,當(dāng)然,這一過程是完全靜默的。下載完后,就會(huì)自動(dòng)啟動(dòng)相應(yīng)的Page Ability。這種技術(shù)不僅可以啟動(dòng)另一個(gè)設(shè)備上的Page Ability,還可以向另一個(gè)設(shè)備中的Page Ability傳遞數(shù)據(jù)。

這種技術(shù)的一個(gè)主要應(yīng)用場景是,可以將在設(shè)備A上完成了一半的工作,遷移到設(shè)備B上繼續(xù)完成。例如,在家中平板電腦上要回一封EMail,但臨時(shí)有急事,需要出門,這時(shí)可以將在平板電腦上寫了一半的EMail遷移到手機(jī)上,需要在路上完成剩下的工作。

1. 跨設(shè)備遷移前的準(zhǔn)備工作

在進(jìn)行跨設(shè)備遷移之前,需要為HarmonyOS設(shè)備做一下準(zhǔn)備:

(1) 打開HarmonyOS設(shè)備中的藍(lán)牙;

(2)HarmonyOS設(shè)備需要連入Wi-Fi,而且多個(gè)HarmonyOS需要在同一個(gè)網(wǎng)段;

(3)多個(gè)HarmonyOS設(shè)備需要用同一個(gè)華為開發(fā)者賬號(hào)登錄,如圖1所示。


圖1 用同一個(gè)華為開發(fā)者賬號(hào)登錄

(4)點(diǎn)擊“設(shè)置”>“更多連接”>“多設(shè)備協(xié)同”,進(jìn)入多設(shè)備協(xié)同窗口,打開多設(shè)備協(xié)同開關(guān),如圖2所示。

圖2 多設(shè)備協(xié)同

(5)修改HarmonyOS設(shè)備名。點(diǎn)擊“設(shè)置”>“藍(lán)牙”>“設(shè)備名稱”,進(jìn)入設(shè)備名稱窗口,輸入一個(gè)新的什么名稱,如圖3所示。盡管這一步不是必須的,但如果擁有多部HarmonyOS設(shè)備,可能很多HarmonyOS設(shè)備的名稱是相同或相近的。為了更好區(qū)分不同的HarmonyOS設(shè)備,建議修改HarmonyOS設(shè)備名稱。

圖3 修改HarmonyOS設(shè)備名稱

2 獲取設(shè)備列表

跨設(shè)備遷移是通過設(shè)備ID來區(qū)分不同設(shè)備的,所以首先要獲取所有可用的設(shè)備的ID。獲取設(shè)備ID需要調(diào)用DeviceManager.getDeviceList方法,該方法返回一個(gè)List對(duì)象,類型是DeviceInfo,用來描述設(shè)備的相關(guān)信息,包括設(shè)備ID、設(shè)備名稱(就是上一節(jié)設(shè)置的設(shè)備名稱)等。實(shí)現(xiàn)代碼如下:

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

getDeviceList方法有一個(gè)參數(shù),是一個(gè)int類型的值,表示獲取什么狀態(tài)的設(shè)備的信息??梢灾付ǖ闹等缦拢?/p>

(1) DeviceInfo.FLAG_GET_ONLINE_DEVICE:獲取所有在線設(shè)備的信息;

(2) DeviceInfo. FLAG_GET_OFFLINE_DEVICE:獲取所有離線設(shè)備的信息;

(3) DeviceInfo. FLAG_GET_ALL_DEVICE:獲取所有設(shè)備的信息;

通常會(huì)使用第1個(gè)值,獲取所有在線設(shè)備的信息,因?yàn)橹挥性O(shè)備在線,才能將Page Ability遷移到該設(shè)備上。

下面給出一個(gè)案例,該案例實(shí)現(xiàn)了一個(gè)通用的顯示可用設(shè)備列表的Page Ability,點(diǎn)擊某一個(gè)設(shè)備,會(huì)返回該設(shè)備的ID,

在device_ids.xml布局文件中放置了一個(gè)ListContainer組件,用于顯示獲取的所有可用設(shè)備的相關(guān)信息。實(shí)現(xiàn)代碼如下:

  1. public class DeviceIdsAbility extends Ability { 
  2.     // 保存獲取到的所有設(shè)備的信息 
  3.     private List<DeviceInfo> deviceInfos; 
  4.     private ListContainer listContainerDeviceIds; 
  5.     // 獲取所有可用的設(shè)備的相關(guān)信息 
  6.     public static List<DeviceInfo> getAvailableDeviceIds() { 
  7.         List<DeviceInfo> deviceInfoList = 
  8.                 DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  9.         if (deviceInfoList == null) { 
  10.             return new ArrayList<>(); 
  11.         } 
  12.         if (deviceInfoList.size() == 0) { 
  13.             return new ArrayList<>(); 
  14.         } 
  15.         return deviceInfoList; 
  16.     } 
  17.     @Override 
  18.     public void onStart(Intent intent) { 
  19.         super.onStart(intent); 
  20.         super.setUIContent(ResourceTable.Layout_device_ids); 
  21.         deviceInfos = getAvailableDeviceIds(); 
  22.         listContainerDeviceIds = 、 
  23.         (ListContainer)findComponentById(ResourceTable.Id_listcontainer_deviceids); 
  24.         if(listContainerDeviceIds != null) { 
  25.             // 為ListContainer組件設(shè)置列表項(xiàng)監(jiān)聽器 
  26.             listContainerDeviceIds.setItemClickedListener(new ListContainer.ItemClickedListener() { 
  27.                 @Override 
  28.                 public void onItemClicked(ListContainer listContainer, Component component, int i, long l) { 
  29.                     // 當(dāng)單擊某個(gè)列表項(xiàng)(設(shè)備)后,會(huì)獲取該設(shè)備的ID,并將這個(gè)ID作為Page Ability 
  30.                     // 的結(jié)果返回 
  31.                     String deviceId = deviceInfos.get(i).getDeviceId(); 
  32.                     Intent intent = new Intent(); 
  33.                     intent.setParam("deviceId", deviceId); 
  34.                     setResult(100,intent); 
  35.                     // 關(guān)閉當(dāng)前的Page Ability 
  36.                     terminateAbility(); 
  37.   
  38.                 } 
  39.             }); 
  40.             // 為ListContainer組件設(shè)置Provider 
  41.             listContainerDeviceIds.setItemProvider(new RecycleItemProvider() { 
  42.                 @Override 
  43.                 public int getCount() { 
  44.                     return deviceInfos.size(); 
  45.                 } 
  46.   
  47.                 @Override 
  48.                 public Object getItem(int i) { 
  49.                     return deviceInfos.get(i); 
  50.                 } 
  51.   
  52.                 @Override 
  53.                 public long getItemId(int i) { 
  54.                     return i; 
  55.                 } 
  56.   
  57.                 @Override 
  58.                 public Component getComponent(int i, Component component, ComponentContainer componentContainer) { 
  59.                     if(component == null) { 
  60.                         // 如果component為null,說明沒有可以利用的列表項(xiàng)視圖,所以要從布局文件 
  61.                         // 裝載一個(gè)新的視圖對(duì)象 
  62.                         component = (DirectionalLayout)LayoutScatter.getInstance(DeviceIdsAbility.this).parse(ResourceTable.Layout_device_id_item,null,false); 
  63.                     } 
  64.                     Text textDeviceName = (Text)component.findComponentById(ResourceTable.Id_text_device_name); 
  65.                     Text textDeviceId = (Text)component.findComponentById(ResourceTable.Id_text_device_id); 
  66.                     if(textDeviceName != null) { 
  67.                         // 顯示設(shè)備名 
  68.                         textDeviceName.setText(deviceInfos.get(i).getDeviceName()); 
  69.                     } 
  70.                     if(textDeviceId != null) { 
  71.                         // 顯示設(shè)備ID 
  72.                         textDeviceId.setText(deviceInfos.get(i).getDeviceId()); 
  73.                     } 
  74.                     return component; 
  75.                 } 
  76.             }); 
  77.   
  78.         } 
  79.   
  80.     } 

 在DeviceIdsAbility類中為ListContainer組件裝載列表項(xiàng)時(shí),在getComponent方法中利用了第2個(gè)參數(shù)component,該參數(shù)就是列表項(xiàng)的根視圖。如果component為null,表明并沒有可以利用的列表項(xiàng)視圖,所以要?jiǎng)?chuàng)建一個(gè)新的列表項(xiàng)視圖。如果不為null,表明可以利用其他的還沒有顯示的列表項(xiàng)視圖,只需要替換該視圖的Text組件中顯示的信息即可。

最后在config.json文件中添加一些與分布式相關(guān)的權(quán)限。

  1.  "reqPermissions": [ 
  2.       { 
  3.         "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" 
  4.       }, 
  5.       { 
  6.         "name""com.huawei.permission.ACCESS_DISTRIBUTED_ABILITY_GROUP" 
  7.       }, 
  8.       { 
  9.         "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  10.       } 

 運(yùn)行程序,會(huì)看到如圖4所示的設(shè)備列表。


圖4 獲取可用設(shè)備的ID

要注意的是,通過DeviceManager.getDeviceList方法只能獲取其他設(shè)備的信息,不能獲取自身的信息,例如,有設(shè)備A、設(shè)備B和設(shè)備C。在設(shè)備A中只能獲取設(shè)備B和設(shè)備C的信息,而不能獲取設(shè)備A的信息。在設(shè)備B和設(shè)備C中的表現(xiàn)也類似。

3 根據(jù)設(shè)備ID調(diào)用Page Ability

一個(gè)Page Ability要想跨設(shè)備訪問,必須實(shí)現(xiàn)IAbilityContinuation接口,否則會(huì)拋出異常。該接口必須實(shí)現(xiàn)的有4個(gè)方法,他們的含義如下:

  1. public interface IAbilityContinuation { 
  2.     // 開始遷移,如果返回true,表示可以開始遷移 
  3.     boolean onStartContinuation(); 
  4.     // 開始傳遞數(shù)據(jù),如果返回true,表示成功傳遞數(shù)據(jù) 
  5.     boolean onSaveData(IntentParams var1); 
  6.     // 開始恢復(fù)數(shù)據(jù),如果返回true,表示成功恢復(fù)數(shù)據(jù) 
  7.     boolean onRestoreData(IntentParams var1); 
  8.     // 已經(jīng)完成Page Ability遷移 
  9.     void onCompleteContinuation(int var1);  

 假設(shè)在設(shè)備A上將Page Ability遷移到設(shè)備B。onStartContinuation方法和onSaveData方法是在設(shè)備A上被調(diào)用的,而onRestoreData方法和onCompleteContinuation方法是在設(shè)備B上被調(diào)用的。為了遷移Page Ability,需要在設(shè)備A上執(zhí)行下面的代碼:

  1. continueAbility(deviceId); 

其中deviceID是設(shè)備ID。當(dāng)調(diào)用該方法后,在設(shè)備A上就會(huì)依次調(diào)用onStartContinuation方法和onSaveData方法,在設(shè)備B上會(huì)依次調(diào)用onRestoreData方法和onCompleteContinuation方法。其中onSaveData方法和onRestoreData方法都有一個(gè)IntentParams類型的參數(shù),通過該參數(shù)可以在設(shè)備A和設(shè)備B之間通過Page Ability傳遞數(shù)據(jù)(使用方式與Intent類似)。通常在onRestoreData方法中恢復(fù)Page Ability從設(shè)備A上遷移到設(shè)備B上時(shí)的數(shù)據(jù)。

下面給出一個(gè)實(shí)際的案例,在Page Ability上放置了一個(gè)TextField組件,并在該組件中輸入了一些文本,然后點(diǎn)擊按鈕,將該P(yáng)age Ability遷移到另一部HarmonyOS手機(jī)上,并恢復(fù)遷移時(shí)的數(shù)據(jù)。

實(shí)現(xiàn)代碼如下:

  1. public class CrossDevicePageAbility extends Ability implements IAbilityContinuation { 
  2.     private List<DeviceInfo> deviceInfos; 
  3.     private ListContainer listContainerDeviceIds; 
  4.     private TextField textFieldContent; 
  5.     private String content; 
  6.     // 授權(quán)方法 
  7.     private void requestPermission() { 
  8.         // 實(shí)現(xiàn)Page Ability跨設(shè)備遷移,必須用Java代碼申請下面的權(quán)限 
  9.         // 否則不會(huì)有任何反應(yīng) 
  10.         String[] permission = { 
  11.                 "ohos.permission.DISTRIBUTED_DATASYNC"}; 
  12.         List<String> applyPermissions = new ArrayList<>(); 
  13.         for (String element : permission) { 
  14.             // 驗(yàn)證自身是否已經(jīng)獲得了該權(quán)限 
  15.             if (verifySelfPermission(element) != 0) { 
  16.                 if (canRequestPermission(element)) { 
  17.                     // 如果未獲得權(quán)限,將該權(quán)限添加到權(quán)限列表 
  18.                     applyPermissions.add(element); 
  19.                 } else { 
  20.                 } 
  21.             } else { 
  22.             } 
  23.         } 
  24.         // 申請相應(yīng)權(quán)限 
  25.         requestPermissionsFromUser(applyPermissions.toArray(new String[0]), 0); 
  26.     } 
  27.     // 要想成功跨設(shè)備遷移Page Ability,該方法必須返回true 
  28.     @Override 
  29.     public boolean onStartContinuation() { 
  30.         return true
  31.     }     
  32.     @Override 
  33.     public boolean onSaveData(IntentParams intentParams) { 
  34.         // 保存要傳遞的數(shù)據(jù) 
  35.         intentParams.setParam("content",textFieldContent.getText()); 
  36.         return true
  37.     } 
  38.     @Override 
  39.     public boolean onRestoreData(IntentParams intentParams) { 
  40.         // 獲取傳遞過來的數(shù)據(jù) 
  41.         content = String.valueOf(intentParams.getParam("content")); 
  42.         return true
  43.     } 
  44.     @Override 
  45.     public void onCompleteContinuation(int i) { 
  46.   
  47.     } 
  48.     @Override 
  49.     protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) { 
  50.         // 當(dāng)選擇設(shè)備后,利用返回的設(shè)備ID遷移Page Ability 
  51.         if(resultCode == 100 && requestCode == 99) { 
  52.             // 獲取設(shè)備ID 
  53.             String deviceId = resultData.getStringParam("deviceId"); 
  54.             Tools.showTip(this, deviceId); 
  55.             // 跨設(shè)備遷移Page Ability 
  56.             continueAbility(deviceId); 
  57.         } 
  58.     } 
  59.   
  60.     @Override 
  61.     public void onStart(Intent intent) { 
  62.         super.onStart(intent); 
  63.         super.setUIContent(ResourceTable.Layout_cross_device_page_ability); 
  64.         // 申請權(quán)限 
  65.         requestPermission(); 
  66.         Button button = 
  67.           (Button)findComponentById(ResourceTable.Id_button_cross_device_page_ability); 
  68.         if(button != null) { 
  69.             button.setClickedListener(new Component.ClickedListener() { 
  70.                 @Override 
  71.                 public void onClick(Component component) { 
  72.                     // 顯示列表列表窗口 
  73.                     Intent intentPageAbility = new Intent(); 
  74.                     Operation operation = new Intent.OperationBuilder() 
  75.                             .withBundleName("com.unitymarvel.demo"
  76.                             .withAbilityName("com.unitymarvel.demo.ability.DeviceIdsAbility"
  77.                             .build(); 
  78.                     intentPageAbility.setOperation(operation); 
  79.                     startAbilityForResult(intentPageAbility,99); 
  80.                 } 
  81.             }); 
  82.         } 
  83.   
  84.         textFieldContent = (TextField)findComponentById(ResourceTable.Id_textfield_content); 
  85.         if(textFieldContent != null) { 
  86.             // 恢復(fù)TextField組件中的數(shù)據(jù) 
  87.             textFieldContent.setText(content); 
  88.         } 
  89.     } 

 閱讀這段代碼,需要了解下面幾點(diǎn):

(1)要想成功遷移Page Ability,并成功傳遞數(shù)據(jù)。onStartContinuation方法、onSaveData方法和onRestoreData方法都必須返回true,如果讀者使用IDE的自動(dòng)生成代碼功能,默認(rèn)這幾個(gè)方法都會(huì)返回false,請將他們的返回值改成true;

(2)在HarmonyOS中有一些權(quán)限,并不是在config.json中聲明就可以了,還需要使用Java代碼申請,例如,Page Ability跨設(shè)備遷移就需要使用Java代碼申請ohos.permission.DISTRIBUTED_DATASYNC權(quán)限。如果是第一次申請,會(huì)彈出如圖5的授權(quán)對(duì)話框,點(diǎn)擊“始終允許”按鈕關(guān)閉該對(duì)話框,第2次申請權(quán)限,就不會(huì)彈出該對(duì)話框了;

(3)由于onRestoreData方法在onStart方法之前調(diào)用,所以不能直接在onRestoreData方法中使用組件對(duì)象,因?yàn)榻M件對(duì)象通常都是在onStart方法中創(chuàng)建的。所以在onRestoreData方法被調(diào)用時(shí),這些組件對(duì)象還都是空。正確的做法是在onRestoreData方法中將要恢復(fù)的數(shù)據(jù)保存到成員變量中,然后在onStart方法中創(chuàng)建完組件對(duì)象后,用這些變量恢復(fù)組件中的數(shù)據(jù)。

(4)本例考慮了多部HarmonyOS設(shè)備遷移的問題,所以使用了上一節(jié)編寫的設(shè)備列表窗口。在開始跨設(shè)備遷移Page Ability之前,會(huì)先彈出一個(gè)設(shè)備列表窗口,當(dāng)用戶選擇一個(gè)設(shè)備后,會(huì)返回該設(shè)備的ID,然后在onAbilityResult方法中獲取這個(gè)返回的設(shè)備ID,最后使用continueAbility方法遷移Page Ability;

圖5 授權(quán)對(duì)話框

現(xiàn)在運(yùn)行程序,關(guān)閉授權(quán)對(duì)話框,并在TextField組件中輸入一些內(nèi)容,最后點(diǎn)擊“跨設(shè)備遷移Page Ability”按鈕,會(huì)彈出一個(gè)設(shè)備列表窗口,選擇相應(yīng)的設(shè)備后,會(huì)在選中的設(shè)備中彈出同樣的Page Ability,并且TextField組件的數(shù)據(jù)與原設(shè)備上的完全相同,如圖6所示。注意,只要被調(diào)用方安裝了App,不管設(shè)備是否已經(jīng)啟動(dòng)了App,否會(huì)自動(dòng)彈出這個(gè)被遷移的Page Ability。

圖6 跨設(shè)備遷移Page Ability的效果

歡迎訪問李寧老師的【鴻蒙基地】專欄:https://harmonyos.51cto.com/column/17

李寧老師的課程主頁:https://edu.51cto.com/lecturer/974126.html

[[374064]]

©著作權(quán)歸作者和HarmonyOS技術(shù)社區(qū)共同所有,如需轉(zhuǎn)載,請注明出處,否則將追究法律責(zé)任

想了解更多內(nèi)容,請?jiān)L問:

51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)

https://harmonyos.51cto.com/#zz

 

責(zé)任編輯:jianghua 來源: 鴻蒙社區(qū)
相關(guān)推薦

2021-01-12 09:42:05

鴻蒙HarmonyOSPage Abilit

2020-12-28 11:19:06

鴻蒙HarmonyOSPage Abilit

2020-11-05 10:05:25

App

2021-07-01 09:19:56

鴻蒙HarmonyOS應(yīng)用

2021-06-16 15:18:03

鴻蒙HarmonyOS應(yīng)用

2021-06-28 14:41:36

鴻蒙HarmonyOS應(yīng)用

2021-06-23 15:48:08

鴻蒙HarmonyOS應(yīng)用

2021-07-08 09:42:04

鴻蒙HarmonyOS應(yīng)用

2021-01-06 11:21:56

鴻蒙HarmonyOS應(yīng)用開發(fā)

2022-07-27 22:03:53

HarmonyOS鴻蒙

2022-09-07 15:28:02

Stage模型Ability

2021-10-28 14:48:46

鴻蒙HarmonyOS應(yīng)用

2021-03-23 09:52:39

鴻蒙HarmonyOS應(yīng)用開發(fā)

2021-03-29 09:59:09

鴻蒙HarmonyOS應(yīng)用開發(fā)

2012-08-16 13:34:09

云基地

2020-12-29 11:51:16

鴻蒙HarmonyOS華為手機(jī)

2020-11-09 11:56:49

HarmonyOS

2021-06-18 14:55:57

鴻蒙HarmonyOS應(yīng)用

2017-03-03 16:28:25

網(wǎng)易云

2023-03-24 14:52:27

AbilityPage應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)