當你想找一家餐廳吃飯,卻不知道去哪家,這時候手機跳出一條通知,為你自動推送附近優質餐廳的信息,你會點擊查看嗎?當你還在店內糾結於是否買下一雙球鞋時,手機應用給了你發放了老顧客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
原作者:趙照