用鴻蒙的分布式助力七夕
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
在情人節(jié)后,為之前的B站卡片項目增加一個隱藏功能。如果升級了最新的B站服務(wù)卡片,那么當(dāng)桌面上添加頭像卡片時,只要點擊頭像,就會看到下圖的效果。一個應(yīng)用鴻蒙分布式能力的小功能。
視頻預(yù)覽地址:https://harmonyos.51cto.com/show/7762
完整項目地址:https://gitee.com/liangzili/bilibili-cards
1.添加一個播放頁
比如PlayerSlice,這個頁面用來實現(xiàn)視頻的播放。

2.為頭像卡片添加點擊事件
當(dāng)點擊卡片上的頭像時實現(xiàn)頁面跳轉(zhuǎn),代碼如下
src/main/js/fans/pages/index/index.hml
- <div class="card_root_layout" else>
- <div class="div_left_container">
- <stack class="stack-parent" onclick="sendRouterEvent">
- <image src="{{src}}" class="image_src"></image>
- <image src="{{vip}}" class="image_vip"></image>
- </stack>
- </div>
- <text class="item_title">{{follower}}</text>
- </div>
actions中設(shè)置跳轉(zhuǎn)到剛才新建的播放頁面。
src/main/js/fans/pages/index/index.json
- "actions": {
- "sendRouterEvent": {
- "action": "router",
- "abilityName": "com.liangzili.demos.Player",
- "params": true
- }
- }
3.在播放頁判斷拉起方式
從intent中提取參數(shù)params,如果播放頁是服務(wù)卡片拉起的,得到true。如果是分布式拉起的得到false。
- params = intent.getStringParam("params");//從intent中獲取 跳轉(zhuǎn)事件定義的params字段的值
- if(params.equals("true")){
- Intent intent0 = new Intent();
- Operation op = new Intent.OperationBuilder()
- .withDeviceId(DistributedUtils.getDeviceId())//參數(shù)1.是否跨設(shè)備,空,不跨設(shè)備
- .withBundleName("com.liangzili.demos")//參數(shù)2.在config.json中的bundleName
- .withAbilityName("com.liangzili.demos.Player")//參數(shù)3.要跳轉(zhuǎn)的ability名
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- intent0.setOperation(op);
- intent0.setParam("params","false");
- startAbility(intent0);
- videoSource = "resources/base/media/right.mp4";
- }else{
- videoSource = "resources/base/media/left.mp4";
- }
4.申請分布式拉起頁面權(quán)限
如果params就調(diào)用分布式拉起頁面,得提前為應(yīng)用獲取權(quán)限。
在app首次啟動時提醒用戶獲取分布式權(quán)限。
src/main/java/com/liangzili/demos/MainAbility.java
- requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);
5.獲取遠(yuǎn)端設(shè)備ID
要拉起遠(yuǎn)端設(shè)備上的頁面,得先獲取設(shè)備的ID。
- public class DistributedUtils {
- public static String getDeviceId(){
- //獲取在線設(shè)備列表,getDeviceList拿到的設(shè)備不包含本機。
- List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
- if(deviceList.isEmpty()){
- return null;
- }
- int deviceNum = deviceList.size();
- List<String> deviceIds = new ArrayList<>(deviceNum); //提取設(shè)備Id
- List<String> deviceNames = new ArrayList<>(deviceNum); //提取設(shè)備名
- deviceList.forEach((device)->{
- deviceIds.add(device.getDeviceId());
- deviceNames.add(device.getDeviceName());
- });
- String devcieIdStr = deviceIds.get(0);
- return devcieIdStr;
- }
- }
6.獲取資源地址播放視頻
視頻播放參考的是軟通動力HarmonyOS學(xué)院的拜年視頻代碼,官方的demo和CadeLabs還沒跑通,時間有點來不及了,原諒我大段復(fù)制。
- //設(shè)置沉浸式狀態(tài)欄
- getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
- initPlayer();
- //需要重寫兩個回調(diào):VideoSurfaceCallback 、VideoPlayerCallback
- private void initPlayer() {
- sfProvider=(SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
- // image=(Image) findComponentById(ResourceTable.Id_img);
- sfProvider.getSurfaceOps().get().addCallback(new VideoSurfaceCallback());
- // sfProvider.pinToZTop(boolean)--如果設(shè)置為true, 視頻控件會在最上層展示,但是設(shè)置為false時,雖然不在最上層展示,卻出現(xiàn)黑屏,
- // 需加上一行代碼:WindowManager.getInstance().getTopWindow().get().setTransparent(true);
- sfProvider.pinToZTop(true);
- //WindowManager.getInstance().getTopWindow().get().setTransparent(true);
- player=new Player(getContext());
- //sfProvider添加監(jiān)聽事件
- sfProvider.setClickedListener(new Component.ClickedListener() {
- @Override
- public void onClick(Component component) {
- if(player.isNowPlaying()){
- //如果正在播放,就暫停
- player.pause();
- //播放按鈕可見
- image.setVisibility(Component.VISIBLE);
- }else {
- //如果暫停,點擊繼續(xù)播放
- player.play();
- //播放按鈕隱藏
- image.setVisibility(Component.HIDE);
- }
- }
- });
- }
- private class VideoSurfaceCallback implements SurfaceOps.Callback {
- @Override
- public void surfaceCreated(SurfaceOps surfaceOps) {
- HiLog.info(logLabel,"surfaceCreated() called.");
- if (sfProvider.getSurfaceOps().isPresent()) {
- Surface surface = sfProvider.getSurfaceOps().get().getSurface();
- playLocalFile(surface);
- }
- }
- @Override
- public void surfaceChanged(SurfaceOps surfaceOps, int i, int i1, int i2) {
- HiLog.info(logLabel,"surfaceChanged() called.");
- }
- @Override
- public void surfaceDestroyed(SurfaceOps surfaceOps) {
- HiLog.info(logLabel,"surfaceDestroyed() called.");
- }
- }
- private void playLocalFile(Surface surface) {
- try {
- RawFileDescriptor filDescriptor = getResourceManager().getRawFileEntry(videoSource).openRawFileDescriptor();
- Source source = new Source(filDescriptor.getFileDescriptor(),filDescriptor.getStartPosition(),filDescriptor.getFileSize());
- player.setSource(source);
- player.setVideoSurface(surface);
- player.setPlayerCallback(new VideoPlayerCallback());
- player.prepare();
- sfProvider.setTop(0);
- player.play();
- } catch (Exception e) {
- HiLog.info(logLabel,"playUrl Exception:" + e.getMessage());
- }
- }
參考文章:
【軟通動力】SurfaceProvider實現(xiàn)視頻播放Demo-熱乎乎的拜年視頻-鴻蒙HarmonyOS技術(shù)社區(qū)-鴻蒙官方合作伙伴-51CTO.COM
鴻蒙應(yīng)用開發(fā)入門(六):頁面間跳轉(zhuǎn)-鴻蒙HarmonyOS技術(shù)社區(qū)-鴻蒙官方合作伙伴-51CTO.CO
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)