文档章节

如何用Nearby Service开发针对附近人群的精准广告推送功能

o
 osc_7dwwmolq
发布于 07/02 16:01
字数 1444
阅读 21
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

  当你想找一家餐厅吃饭,却不知道去哪家,这时候手机跳出一条通知,为你自动推送附近优质餐厅的信息,你会点击查看吗?当你还在店内纠结于是否买下一双球鞋时,手机应用给了你发放了老顾客5折优惠券,这样的广告你有拒绝的理由吗?

  这样的广告不仅不会引起用户的厌烦,还满足了用户的需求。更准确的广告推送,减少对用户不必要的打扰,提高用户对应用的满意度。那如何才能给自己的APP增加一个针对附近人群的精准广告推送功能呢?

在这里插入图片描述

  可以接入华为近距离通信服务,通过蓝牙信标消息订阅功能(Nearby Beacon Message)来实现. 在商场中部署Beacon,Beacon消息提供精确的相对位置信息,当用户走近餐厅、商店时,就会收到本店预先配置好的促销消息,例如优惠券、打折信息等等,从而可以很便捷的对本店进行推广,下图是功能演示。

在这里插入图片描述

  如果你对实现方式感兴趣,可以在Github上下载源码:
  https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCanteens

1.开发准备

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

1.1 在项目级gradle里添加华为maven仓和agcp配置

  增量添加如下maven地址和agcp配置,以下不用修改,拷贝即可。

buildscript {
     repositories {
         google()
         jcenter()
         maven { url 'http://developer.huawei.com/repo/' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:3.4.1'
         classpath 'com.huawei.agconnect:agcp:1.2.1.301'
     }
 }

 allprojects {
     repositories {
         google()
         jcenter()
         maven { url 'http://developer.huawei.com/repo/' }
     }
 }

1.2 在应用级的build.gradle里面加上SDK依赖

  把近距离通信服务SDK引入,最重要的是以下com.huawei开头的SDK。

dependencies {
     implementation fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.appcompat:appcompat:1.1.0'
     implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
     testImplementation 'junit:junit:4.12'
     androidTestImplementation 'androidx.test.ext:junit:1.1.1'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
     implementation "com.huawei.hmf:tasks:1.3.1.301"
     implementation "com.huawei.hms:network-grs:1.0.9.302"
     implementation 'com.huawei.agconnect:agconnect-core:1.2.1.301'
     implementation 'com.huawei.hms:nearby:4.0.4.300'
     api 'com.google.code.gson:gson:2.8.5'
 }

1.3 在AndroidManifest.xml文件里面申请网络权限、蓝牙权限和位置权限

  以下权限见名知义,比如android.permission.INTERNET就是需要网络权限,android.permission.BLUETOOTH就是需要蓝牙权限。以下权限都是必须的。

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.BLUETOOTH" />
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

2. 代码开发

2.1 初始化以及动态权限申请

  onCreate是当前activity创建时会调用的方法,在这个方法里头,我们可以做一些准备动作,比如必要权限的申请,以及检查手机网络、蓝牙、GPS是否开启等。

@RequiresApi(api = Build.VERSION_CODES.P)
 @Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     Log.i(TAG, "onCreate");
     setContentView(R.layout.activity_canteen);
     boolean isSuccess = requestPermissions(this, this);
     if (!isSuccess) {
         return;
     }
     Log.i(TAG, "requestPermissions success");
     if (!NetCheckUtil.isNetworkAvailable(this)) {
         showWarnDialog(Constant.NETWORK_ERROR);
         return;
     }
     if (!BluetoothCheckUtil.isBlueEnabled()) {
         showWarnDialog(Constant.BLUETOOTH_ERROR);
         return;
     }
     if (!GpsCheckUtil.isGpsEnabled(this)) {
         showWarnDialog(Constant.GPS_ERROR);
         return;
     }
     intView();
     init();
 }

  注册监听,当检测到手机蓝牙、GPS、网络未连接时,给出提示: 以下使用的是Android中的AlertDialog组件来做提示。

private void showWarnDialog(String content) {
     DialogInterface.OnClickListener onClickListener =
         new DialogInterface.OnClickListener() {
             @Override
             public void onClick(DialogInterface dialog, int which) {
                 android.os.Process.killProcess(android.os.Process.myPid());
             }
         };
     AlertDialog.Builder builder = new AlertDialog.Builder(this);
     builder.setTitle(R.string.warn);
     builder.setIcon(R.mipmap.warn);
     builder.setMessage(content);
     builder.setNegativeButton(getText(R.string.btn_confirm), onClickListener);
     builder.show();
 }

2.2 接收Beacon消息的过程

  以下这个startScanning方法,是在onStart方法中被调用的,表示开始启动蓝牙扫描,并且以下的MessageHandler对象中,封装了4个回调方法(onFound表示获取到beacon消息,OnLost表示消息丢失,onDistanceChanged表示beacon与本手机的距离变化,onBleSignalChanged表示监测到beacon的信号变化)。

  最重要的就是以下的doOnFound方法,表示接收到beacon消息时,客户端的处理方式,可以做个性化展示。

private void doOnFound(Message message) {
     if (message == null) {
         return;
     }
     String type = message.getType();
     if (type == null) {
         return;
     }
     String messageContent = new String(message.getContent());
     Log.d(TAG, "New Message:" + messageContent + " type:" + type);
     if (type.equalsIgnoreCase(Constant.CANTEEN)) {
         operateOnFoundCanteen(messageContent);
     } else if (type.equalsIgnoreCase(Constant.NOTICE)) {
         operateOnFoundNotice(messageContent);
     }
 }

自定义展示:
  下面的方法只是简单的演示其中一种消息处理方式,包括客户端上的通知栏横幅通知、页面字体滑动展示等操作。

private void operateOnFoundCanteen(String messageContent) {
     CanteenAdapterInfo canteenAdapterInfo =
             (CanteenAdapterInfo) JsonUtils.json2Object(messageContent, CanteenAdapterInfo.class);
     if (canteenAdapterInfo == null) {
         return;
     }
     String canteenName = canteenAdapterInfo.getCanteenName();
     if (canteenName == null) {
         return;
     }
     Log.d(TAG, "canteenName:" + canteenName);
     if (!canteenNameList.contains(canteenName)) {
         return;
     }

     String notice = "";
     if (receivedNoticeMap.containsKey(canteenName)) {
         notice = receivedNoticeMap.get(canteenName);
     }
     int canteenImage = getCanteenImage(canteenName);
     int requestCode = getRequestCode(canteenName);
     canteenAdapterInfo.setNotice(notice);
     canteenAdapterInfo.setCanteenImage(canteenImage);
     canteenAdapterInfo.setShowNotice(true);
     canteenAdapterInfo.setRequestCode(requestCode);

     canteenAdapterInfoMap.put(canteenName, canteenAdapterInfo);
     canteenAdapterInfoList.add(canteenAdapterInfo);

     sendNotification(Constant.NOTIFICATION_TITLE, Constant.NOTIFICATION_SUBTITLE, canteenName, requestCode);
     runOnUiThread(
         new Runnable() {
             @Override
             public void run() {
                 searchTipTv.setText(R.string.found_tip);
                 loadingLayout.setVisibility(View.GONE);
                 canteenAdapter.setDatas(canteenAdapterInfoList);
             }
         });
 }

结后语

  本次给大家演示的demo用到了华为Nearby Service的蓝牙信标消息订阅功能

  基于Nearby Beacon Message能力不仅仅可以用来做广告推送,还可以实现如下相关功能:

  1. 汽车生活类应用集成Nearby Beacon Message功能后,可以识别用户靠近汽车,通知App启用无钥匙进入,记录行驶轨迹等。

  2. 办公类应用集成Nearby Beacon Message功能后,可快速准确记录员工打卡位置。

  3. 旅游、展览类应用集成Nearby Beacon Message功能后,当用户靠近某个展品或文物时候,能够获取相应的介绍信息。

  4. 游戏类应用使用Nearby Beacon Message,可以实现游戏和现实场景互动。通过现实物体触发游戏关卡,或者对参与线下活动的游戏玩家给予游戏道具奖励。

  更详细的开发指南可参考华为开发者联盟官网


往期链接:超简单集成ML kit 实现听写单词播报
原文链接:https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201283747724140328&fid=18
原作者:赵照

o
粉丝 0
博文 69
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.7K
0
我的架构演化笔记 功能1: 基本的用户注册

“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...

强子哥哥
2014/05/31
976
3
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
TDD的测试框架--Machine.Specification

Machine.Specification 是一个 TDD 测试驱动开发的测试框架,简化了测试,无需关心语言本身特性。 Machine.Specifications 带来的好处是不需要在代码里有注释,但同时阅读代码的人可以一目了...

匿名
2013/01/22
1.2K
0
mvc框架--Razor

Razor 是一个轻巧而优雅的servlet mvc框架 # 又一个轮子? no,写就她是为了证实我个人的某些想法,并在这个过程中练练手,这两种冲动碰撞在一起,自然而然地产生了Razor # Razor的现在和未来...

dtubest
2013/01/25
3.1K
0

没有更多内容

加载失败,请刷新页面

加载更多

功能之前,感叹号有什么作用? - What does the exclamation mark do before the function?

问题: !function () {}(); 解决方案: 参考一: https://stackoom.com/question/Fl0I/功能之前-感叹号有什么作用 参考二: https://oldbug.net/q/Fl0I/What-does-the-exclamation-mark-do-......

富含淀粉
17分钟前
3
0
微服务分布式构架开发实战 附下载地址

微服务是一种软件架构风格,目标是将一个复杂的应用拆分成多个服务模块,每个模块专注单一业务功能对外提供服务,并可以独立编译及部署,同时各模块间互相通信彼此协作,组合为整体对外提供完...

Idea
34分钟前
6
0
AppEmit v0.9.5 新功能 chrome 浏览器调用本地应用程序 支持打开 编辑 金山 wps office,  excel  ppt

AppEmit v0.9.5 新功能 浏览器调用本地应用程序 支持打开 编辑 金山 office 更多主页 能在以及几乎所有支持websock浏览器,包括chrome各个版本,支持打开 编辑 金山 wps office, excel ppt ...

AppEmit
36分钟前
5
0
Git(学习二)----->Tortoise Git(图形化工具) 安装

下载: 本人使用版本为2.4.0.2有需要的可以从网盘下载,也可以百度找资源 链接:https://pan.baidu.com/s/13Vu0VNUQMZNFKLFhl6VzDw 提取码:y27p 一、安装 步骤1:安装向导 步骤2:许可介绍 步...

安然_oschina
40分钟前
7
0
TarsGo 服务获取自定义模版(配置)值

作者:amc 导语:之前的文章中我们介绍了如何使用TarsGo创建HTTP服务和TARS RPC服务,本篇文章中,我们将介绍如何在TarsGo服务中获得自定义模板的配置值。 TARS 模版是什么? TARS 框架中,有...

TARS基金会
56分钟前
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部