Android Studio实现:设备触发地理围栏时向另一设备推送FCM通知
嘿,看起来你已经把地理围栏和FCM的基础配置都搞定了,很棒!接下来要实现不用FCM控制台自动推送,核心就是在设备1触发地理围栏事件时,直接调用FCM的发送接口推送给设备2的Token。下面分两种方案给你详细说明:
实现方案与步骤
1. 后端中转发送(生产环境推荐)
直接在Android客户端调用FCM发送API会暴露你的服务端密钥,存在严重的安全风险,所以优先推荐用后端来处理推送逻辑:
- 当设备1触发地理围栏的进入/退出事件时,将设备2的Token、通知标题和内容(比如「设备1进入地理围栏」)发送到你自己的后端接口
- 后端接收到请求后,调用FCM的官方SDK或者HTTP API,使用服务端密钥完成鉴权,向指定Token推送通知
- 示例Java Spring Boot后端代码(依赖FCM Java SDK):
import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Notification; public void sendFcmNotification(String targetToken, String title, String body) { // 构建FCM消息 Message message = Message.builder() .setNotification(Notification.builder() .setTitle(title) .setBody(body) .build()) .setToken(targetToken) .build(); try { String response = FirebaseMessaging.getInstance().send(message); System.out.println("推送成功,响应:" + response); } catch (Exception e) { e.printStackTrace(); // 处理推送失败逻辑 } }
2. 客户端临时测试方案(不推荐生产)
如果暂时没有后端资源,你可以在客户端直接调用FCM的HTTP API完成推送,但务必注意:绝对不能把服务端密钥硬编码在客户端代码中,测试完成后一定要切换到后端方案:
- 在设备1的地理围栏回调逻辑里,用OkHttp或Retrofit发起POST请求到FCM的API地址:
https://fcm.googleapis.com/fcm/send - 请求头需要包含两个字段:
Authorization: key=你的FCM服务端密钥和Content-Type: application/json - 请求体示例(JSON格式):
{ "to": "设备2的FCM Token", "notification": { "title": "地理围栏事件通知", "body": "设备1已进入地理围栏区域" } }
- Android端用OkHttp实现的示例代码(Kotlin):
val okHttpClient = OkHttpClient() // 构建请求体 val requestBodyJson = JSONObject().apply { put("to", "设备2的Token") val notificationObj = JSONObject().apply { put("title", "围栏事件提醒") put("body", "设备1进入了地理围栏") } put("notification", notificationObj) } // 构建请求 val request = Request.Builder() .url("https://fcm.googleapis.com/fcm/send") .addHeader("Authorization", "key=你的FCM服务端密钥") .addHeader("Content-Type", "application/json") .post( RequestBody.create( MediaType.parse("application/json; charset=utf-8"), requestBodyJson.toString() ) ) .build() // 发起异步请求 okHttpClient.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理推送失败,比如打印日志或本地提示 Log.e("FCM推送", "失败:${e.message}") } override fun onResponse(call: Call, response: Response) { if (response.isSuccessful) { Log.d("FCM推送", "成功:${response.body()?.string()}") } else { Log.e("FCM推送", "响应错误:${response.code()}") } } })
关键注意事项
- 服务端密钥安全:生产环境必须使用后端发送方案,客户端存储服务端密钥会被反编译获取,导致你的FCM服务被恶意滥用
- Token生命周期管理:设备的FCM Token可能会因重装应用、系统更新等情况刷新,建议把设备Token同步到你的后端数据库,确保推送时使用最新的Token
- 地理围栏回调时机:在
GeofencingClient.addGeofences()的回调中,或者PendingIntent触发的广播接收器/服务里,执行推送通知的逻辑
内容的提问来源于stack exchange,提问作者Caelez Waltz
相关产品推荐
相关产品推荐

