如何用Nearby Service开发针对附近人群的精准广告推送功能
当你想找一家餐厅吃饭,却不知道去哪家,这时候手机跳出一条通知,为你自动推送附近优质餐厅的信息,你会点击查看吗?当你还在店内纠结于是否买下一双球鞋时,手机应用给了你发放了老顾客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能力不仅仅可以用来做广告推送,还可以实现如下相关功能:
汽车生活类应用集成Nearby Beacon Message功能后,可以识别用户靠近汽车,通知App启用无钥匙进入,记录行驶轨迹等。
办公类应用集成Nearby Beacon Message功能后,可快速准确记录员工打卡位置。
旅游、展览类应用集成Nearby Beacon Message功能后,当用户靠近某个展品或文物时候,能够获取相应的介绍信息。
游戏类应用使用Nearby Beacon Message,可以实现游戏和现实场景互动。通过现实物体触发游戏关卡,或者对参与线下活动的游戏玩家给予游戏道具奖励。
更详细的开发指南可参考华为开发者联盟官网
往期链接:超简单集成ML kit 实现听写单词播报
原文链接:https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201283747724140328&fid=18
原作者:赵照
如何用Nearby Service开发针对附近人群的精准广告推送功能的更多相关文章
- HMS Core地理围栏能力助你实现指定范围人群的精准消息推送
精准推送是移动端产品留存阶段的主要运营手段,精准推送常常会与用户画像紧密结合,针对用户的喜好.画像,采用不同策略,但基于用户所属区域推送消息却很难实现.目前市面上大多数第三方消息推送服务商,在系统未深 ...
- Java使用HTTPClient3.0.1开发的公众平台消息模板的推送功能
package com.company.product.manager.busniess.impl; import java.io.IOException;import java.nio.charse ...
- Java使用HTTPClient4.3开发的公众平台消息模板的推送功能
代码引用,参考文章:http://www.cnblogs.com/feiyun126/p/4778556.html,表示感谢! package com.yuanchuangyun.cyb.manage ...
- MQTT是IBM开发的一个即时通讯协议,构建于TCP/IP协议上,是物联网IoT的订阅协议,借助消息推送功能,可以更好地实现远程控制
最近一直做物联网方面的开发,以下内容关于使用MQTT过程中遇到问题的记录以及需要掌握的机制原理,主要讲解理论. 背景 MQTT是IBM开发的一个即时通讯协议.MQTT构建于TCP/IP协议上,面向M2 ...
- C#微信公众号开发系列教程五(接收事件推送与消息排重)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- 苹果IOS、安卓推送功能开发
IOS推送开发:以下是基于开源javapns推送开发1.DerInputStream.getLength(): lengthTag=111, too big.先排除是否由于打包时证书 .p12 文件被 ...
- 【二次开发jumpserver】——整合jumpserver与zabbix推送主机功能
jasset/forms.py "ip", "other_ip", "hostname", "port", " ...
- Android开发学习笔记-关于Android的消息推送以及前后台切换
下面是最简单的Android的消息推送的实现方法 package com.example.shownotic; import java.util.Random; import android.supp ...
- ASP.NET 微信公众平台模板消息推送功能完整开发
最近公众平台的用户提出了新需求,他们希望当收到新的邮件或者日程的时候,公众平台能主动推送一条提醒给用户.看了看平台提供的接口,似乎只有[模板消息]能尽量满足这一需求,但不得不说微信提供的实例太少,而且 ...
随机推荐
- Java实现 蓝桥杯 算法训练VIP 报数(暴力+数学)约瑟夫环问题
试题 算法训练 报数 问题描述 现有n个同学站成一圈,顺时针编号1至n.从1号同学开始顺时针1/2报数,报到1的同学留在原地,报到2的同学退出圆圈,直到只剩一名同学为止.问最后剩下的同学编号. 输入格 ...
- java实现第九届蓝桥杯最大乘积
最大乘积 把 1~9 这9个数字分成两组,中间插入乘号, 有的时候,它们的乘积也只包含1~9这9个数字,而且每个数字只出现1次. 比如: 984672 * 351 = 345619872 98751 ...
- 基于ABP做一个简单的系统——实战篇:1.项目准备
现阶段需要做一个小项目,体量很小,业务功能比较简单,就想到用最熟悉的.net来做,更何况现在.net core已经跨平台,也可以在linux服务器上部署.所以决定用.net core 3.1+mysq ...
- N47-冯天驰-学习进度计划表
马哥就业课程学习进度规划--N47-冯天驰 第一周 6.1-6.7 8. 06- ...
- 6、react中的交互
1.ajax 再react中使用ajax和直接使用ajax的用法是完全一样的,只要找好路径即可,但是也有不一样的地方,再react中是通过改变状态state来达到让组件重新渲染的效果,并且放ajax的 ...
- EIGRP-14-EIGRP的命名模式
从IOS 15.0(1)M版本开始,工程师可以在路由器上使用命名模式(Named Mode)配置EIGRP进程.按照IPv4和IPv6,通过AS号来配置EIGRP进程的做法称为经典模式(Classic ...
- Springboot搭建Eureka并设置Eureka登录账号密码
Springboot搭建Eureka并设置Eureka登录账号密码 一.创建一个springboot项目 1.可以使用Spring Initializr,用浏览器打开http://start.spri ...
- 用python简单爬取一个网页
1打开编辑器 2撸几行代码 import urllib.request import urllib.error def main(): askURl("http://movie.douban ...
- Django 源码阅读笔记(基础视图)
django源码解读之 View View. ContextMixin.TemplateResponseMixin.TemplateView.RedirectView View class View( ...
- CSS优先级的两种理解方式
方式一:值相加 我们先去MDN看看官方的解释: 优先级是如何计算的? 优先级就是分配给指定的 CSS 声明的一个权重,它由 匹配的选择器中的 每一种选择器类型的 数值 决定. 而当优先级与多个 CSS ...