如何用HMS Nearby Service给自己的APP开发一个名片交换功能?

2023-10-30 01:10

本文主要是介绍如何用HMS Nearby Service给自己的APP开发一个名片交换功能?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  在工作和生活中,遇见新的同事或者合作伙伴,交换名片是一个常见的用户需求,纸质名片常忘带、易丢失,是客户的一个痛点。因此,市场上出现了很多交换电子名片的APP和小程序。那么,如何给自己的APP开发一个名片交换功能呢?

在这里插入图片描述

  我们可以接入华为近距离通信服务,通过近距离设备间消息订阅(Nearby Message),快速实现一对一或一对多名片交换。下图是功能演示:

在这里插入图片描述

  如果你对实现方式感兴趣,可以去Github去下载源代码,大家可以基于具体的应用场景优化。

  Github demo下载地址:https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCardExchange

开发具体步骤如下:

1. 开发准备

  如果您已经是华为的开发者,可以省略此步骤。如果您以前没有集成华为移动服务的经验,那么需要先配置AppGallery Connect,开通近距离通信服务并集成HMS SDK。相关步骤请参考官方文档。

2. 添加权限

  在使用Nearby Message之前,需要添加网络权限、蓝牙权限、位置权限。在工程的AndroidManifest.xml文件中添加如下权限:

<uses-permission android:name="android.permission.INTERNET " /><uses-permission android:name="android.permission.BLUETOOTH" /><uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /><!-- The location permission is also required in Android 6.0 or later. --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

3. 代码开发

3.1 动态权限申请

  检查蓝牙开关、位置开关是否打开、网络是否可用,并对位置权限进行动态权限申请

@Overridepublic void onStart() {super.onStart();getActivity().getApplication().registerActivityLifecycleCallbacks(this);checkPermission();}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {for (int i = 0; i < permissions.length; ++i) {if (grantResults[i] != 0) {showWarnDialog(Constants.LOCATION_ERROR);}}}private void checkPermission() {if (!BluetoothCheckUtil.isBlueEnabled()) {showWarnDialog(Constants.BLUETOOTH_ERROR);return;}if (!LocationCheckUtil.isLocationEnabled(this.getActivity())) {showWarnDialog(Constants.LOCATION_SWITCH_ERROR);return;}if (!NetCheckUtil.isNetworkAvailable(this.getActivity())) {showWarnDialog(Constants.NETWORK_ERROR);return;}String[] deniedPermission = PermissionUtil.getDeniedPermissions(this.getActivity(), new String[] {Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION});if (deniedPermission.length > 0) {PermissionUtil.requestPermissions(this.getActivity(), deniedPermission, 10);}}

3.2 封装名片发布接口和名片订阅接口

  订阅到的名片消息(onFound),把名片添加到查找名片对话框中显示;名片消息丢失时(onLost),从查找名片对话框中删除该名片

private MessageHandler mMessageHandler = new MessageHandler() {@Overridepublic void onFound(Message message) {CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),CardInfo.class);if (cardInfo == null) {return;}mSearchCardDialogFragment.addCardInfo(cardInfo);}@Overridepublic void onLost(Message message) {CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),CardInfo.class);if (cardInfo == null) {return;}mSearchCardDialogFragment.removeCardInfo(cardInfo);}};private void publish(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener) {Message message = new Message(JsonUtils.object2Json(mCardInfo).getBytes(Charset.forName("UTF-8")), type,namespace);Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();PutOption option = new PutOption.Builder().setPolicy(policy).build();Nearby.getMessageEngine(getActivity()).put(message, option).addOnCompleteListener(listener);}private void subscribe(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener,GetCallback callback) {Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();MessagePicker picker = new MessagePicker.Builder().includeNamespaceType(namespace, type).build();GetOption.Builder builder = new GetOption.Builder().setPolicy(policy).setPicker(picker);if (callback != null) {builder.setCallback(callback);}Nearby.getMessageEngine(getActivity()).get(mMessageHandler, builder.build()).addOnCompleteListener(listener);}

3.3 名片交换菜单处理

  面对面交换名片交换码,发布个人名片成功后,订阅名片消息

private boolean onExchangeItemSelected() {PinCodeDialogFragment dialogFragment = new PinCodeDialogFragment(passwrod -> {MyCardFragment.this.publish(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_MAX, result -> {if (!result.isSuccessful()) {String str = "Exchange card fail, because publish my card fail. exception: "+ result.getException().getMessage();Log.e(TAG, str);Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();return;}MyCardFragment.this.subscribe(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_INFINITE, ret -> {if (!ret.isSuccessful()) {MyCardFragment.this.unpublish(passwrod, passwrod, task -> {String str = "Exchange card fail, because subscribe is fail, exception("+ ret.getException().getMessage() + ")";if (!task.isSuccessful()) {str = str + " and unpublish fail, exception(" + task.getException().getMessage()+ ")";}Log.e(TAG, str);Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();});return;}mSearchCardDialogFragment.setOnCloseListener(() -> {MyCardFragment.this.unpublish(passwrod, passwrod, task -> {if (!task.isSuccessful()) {Toast.makeText(getActivity(), "Unpublish my card fail, exception: "+ task.getException().getMessage(), Toast.LENGTH_LONG).show();}});MyCardFragment.this.unsubscribe(task -> {if (!task.isSuccessful()) {Toast.makeText(getActivity(), "Unsubscribe fail, exception: "+ task.getException().getMessage(), Toast.LENGTH_LONG).show();}});});mSearchCardDialogFragment.show(getParentFragmentManager(), "Search Card");}, null);});});dialogFragment.show(getParentFragmentManager(), "pin code");return true;}

3.4 收藏名片处理

  收藏名片时把名片加入收藏列表,名片取消收藏时把名片从参数列表中删除,并把数据保存到本地存储中。

@Overridepublic void onFavorite(CardInfo cardInfo, boolean isFavorite) {if (isFavorite) {mFavoriteMap.put(cardInfo.getId(), cardInfo);} else {mFavoriteMap.remove(cardInfo.getId());}Set<String> set = new HashSet<>(mFavoriteMap.size());for (CardInfo card : mFavoriteMap.values()) {set.add(JsonUtils.object2Json(card));}SharedPreferences sharedPreferences = getContext().getSharedPreferences("data", Context.MODE_PRIVATE);sharedPreferences.edit().putStringSet(Constants.MY_FAVORITES_KEY, set).apply();}

4.结后语

  本次给大家演示的demo用到了华为HMS Nearby service的近距离设备间消息订阅功能。基于Nearby Message能力不仅仅可以用来做面对面交换名片,还可以帮助开发者实现很多有趣的功能,例如:

  1. 竞技类手游中的面对面组队功能
  2. 棋牌类手游中的面对面约局功能
  3. 近场AA收款功能
  4. 音乐曲目共享功能

更详细的开发指南参考华为开发者联盟官网:https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/nearby-service-introduction


往期链接:教你如何开发一个完败Miracast的投屏新功能
原文链接:https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201276303118820181&fid=18
原作者:赵照

这篇关于如何用HMS Nearby Service给自己的APP开发一个名片交换功能?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/304622

相关文章

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

基于WinForm+Halcon实现图像缩放与交互功能

《基于WinForm+Halcon实现图像缩放与交互功能》本文主要讲述在WinForm中结合Halcon实现图像缩放、平移及实时显示灰度值等交互功能,包括初始化窗口的不同方式,以及通过特定事件添加相应... 目录前言初始化窗口添加图像缩放功能添加图像平移功能添加实时显示灰度值功能示例代码总结最后前言本文将

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

使用Python实现批量访问URL并解析XML响应功能

《使用Python实现批量访问URL并解析XML响应功能》在现代Web开发和数据抓取中,批量访问URL并解析响应内容是一个常见的需求,本文将详细介绍如何使用Python实现批量访问URL并解析XML响... 目录引言1. 背景与需求2. 工具方法实现2.1 单URL访问与解析代码实现代码说明2.2 示例调用

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要