用鸿蒙的分布式助力七夕
2023-03-15 22:45:38 时间
在情人节后,为之前的B站卡片项目增加一个隐藏功能。如果升级了最新的B站服务卡片,那么当桌面上添加头像卡片时,只要点击头像,就会看到下图的效果。一个应用鸿蒙分布式能力的小功能。
视频预览地址:https://harmonyos.51cto.com/show/7762
完整项目地址:https://gitee.com/liangzili/bilibili-cards
1.添加一个播放页
比如PlayerSlice,这个页面用来实现视频的播放。
2.为头像卡片添加点击事件
当点击卡片上的头像时实现页面跳转,代码如下
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中设置跳转到刚才新建的播放页面。
src/main/js/fans/pages/index/index.json
- "actions": {
- "sendRouterEvent": {
- "action": "router",
- "abilityName": "com.liangzili.demos.Player",
- "params": true
- }
- }
3.在播放页判断拉起方式
从intent中提取参数params,如果播放页是服务卡片拉起的,得到true。如果是分布式拉起的得到false。
- params = intent.getStringParam("params");//从intent中获取 跳转事件定义的params字段的值
- if(params.equals("true")){
- Intent intent0 = new Intent();
- Operation op = new Intent.OperationBuilder()
- .withDeviceId(DistributedUtils.getDeviceId())//参数1.是否跨设备,空,不跨设备
- .withBundleName("com.liangzili.demos")//参数2.在config.json中的bundleName
- .withAbilityName("com.liangzili.demos.Player")//参数3.要跳转的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.申请分布式拉起页面权限
如果params就调用分布式拉起页面,得提前为应用获取权限。
在app首次启动时提醒用户获取分布式权限。
src/main/java/com/liangzili/demos/MainAbility.java
- requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"},0);
5.获取远端设备ID
要拉起远端设备上的页面,得先获取设备的ID。
- public class DistributedUtils {
- public static String getDeviceId(){
- //获取在线设备列表,getDeviceList拿到的设备不包含本机。
- 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); //提取设备Id
- List<String> deviceNames = new ArrayList<>(deviceNum); //提取设备名
- deviceList.forEach((device)->{
- deviceIds.add(device.getDeviceId());
- deviceNames.add(device.getDeviceName());
- });
- String devcieIdStr = deviceIds.get(0);
- return devcieIdStr;
- }
- }
6.获取资源地址播放视频
视频播放参考的是软通动力HarmonyOS学院的拜年视频代码,官方的demo和CadeLabs还没跑通,时间有点来不及了,原谅我大段复制。
- //设置沉浸式状态栏
- getWindow().addFlags(WindowManager.LayoutConfig.MARK_TRANSLUCENT_STATUS);
- initPlayer();
- //需要重写两个回调: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)--如果设置为true, 视频控件会在最上层展示,但是设置为false时,虽然不在最上层展示,却出现黑屏,
- // 需加上一行代码:WindowManager.getInstance().getTopWindow().get().setTransparent(true);
- sfProvider.pinToZTop(true);
- //WindowManager.getInstance().getTopWindow().get().setTransparent(true);
- player=new Player(getContext());
- //sfProvider添加监听事件
- sfProvider.setClickedListener(new Component.ClickedListener() {
- @Override
- public void onClick(Component component) {
- if(player.isNowPlaying()){
- //如果正在播放,就暂停
- player.pause();
- //播放按钮可见
- image.setVisibility(Component.VISIBLE);
- }else {
- //如果暂停,点击继续播放
- 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实现视频播放Demo-热乎乎的拜年视频-鸿蒙HarmonyOS技术社区-鸿蒙官方合作伙伴-51CTO.COM
鸿蒙应用开发入门(六):页面间跳转-鸿蒙HarmonyOS技术社区-鸿蒙官方合作伙伴-51CTO.CO
相关文章
- 金融服务领域的大数据:即时分析
- 影响大数据、机器学习和人工智能未来发展的8个因素
- 从0开始构建一个属于你自己的PHP框架
- 如何将Hadoop集成到工作流程中?这6个优秀实践必看
- SEO公司使用大数据优化其模型的5种方法
- 关于Web Workers你需要了解的七件事
- 深入理解HTTPS原理、过程与实践
- 增强分析:数据和分析的未来
- PHP协程实现过程详解
- AI专家:大数据知识图谱——实战经验总结
- 关于PHP的错误机制总结
- 利用数据分析量化协同过滤算法的两大常见难题
- 怎么做大数据工作流调度系统?大厂架构师一语点破!
- 2019大数据处理必备的十大工具,从Linux到架构师必修
- OpenCV中的KMeans算法介绍与应用
- 教大家如果搭建一套phpstorm+wamp+xdebug调试PHP的环境
- CentOS下三种PHP拓展安装方法
- Go语言HTTP Server源码分析
- Go语言HTTP Server源码分析
- 2017年4月编程语言排行榜:Hack首次进入前五十