睿诚科技协会

Android与PHP如何实现消息推送?

为什么不能直接从服务器推送到手机?

要理解一个核心问题:为什么不能让 PHP 服务器直接连接到每一台 Android 手机并发送消息?

android php 消息推送技术
(图片来源网络,侵删)

答案是:手机处在 NAT(网络地址转换)和防火墙之后,没有公网 IP,且 IP 地址是动态变化的。 这就像一个没有固定地址、不对外开门的房间,服务器找不到这个房间,也无法敲门进去。

我们必须需要一个“中间人”或“邮局”来帮忙传递消息,这个“中间人”Google 的 Firebase Cloud Messaging (FCM) 服务。


技术架构:三驾马车

整个推送系统的架构由三个核心部分组成:

  1. 你的 PHP 服务器 (后端):负责业务逻辑,有新订单了”、“用户收到新评论”,当这些事件发生时,它告诉 FCM 服务:“请帮我把这条消息推送给用户 A”。
  2. Firebase Cloud Messaging (FCM) (服务):Google 提供的免费推送服务,它像一个全球性的邮局,负责接收你服务器的请求,并将消息准确、可靠地送达目标用户的手机上。
  3. 你的 Android App (客户端):手机上的应用程序,它需要先向 FM 注册,获取一个唯一的“设备令牌 (Device Token)”,并将这个令牌发送给你的 PHP 服务器,它负责接收并处理 FCM 转发过来的消息。

流程图如下:

android php 消息推送技术
(图片来源网络,侵删)
+-------------------+      1. 注册获取Token      +--------------------------+      2. 上传Token      +-------------------+
|   Android App     | -------------------------> |      PHP 服务器         | <-------------------- |                   |
| (运行在手机上)     | <------------------------- | (存储每个用户的Device Token) | ----------------------> |                   |
+-------------------+      4. 推送消息          +--------------------------+      3. 发送推送请求      |                   |
        ^                                                    |                                   |                   |
        | 5. 接收并显示消息                                   | 6. 请求发送消息                  |                   |
        |                                                    V                                   |                   |
        +----------------------------------------------------+-----------------------------------+                   |
                                                                   | 7. 转发消息                                        |
                                                                   V                                                    |
                                                          +--------------------------+                                |
                                                          |      Firebase FCM         | <---------------------------------+
                                                          | (Google 的推送服务)        |
                                                          +--------------------------+

详细实现步骤

我们将分步讲解如何搭建这个系统。

第一步:配置 Firebase 项目 (后端准备)

  1. 创建 Firebase 项目
  2. 添加 Android App 到 Firebase 项目
    • 在项目概览页面,点击 Android 图标 (🤖)。
    • 输入你的 Android App 的包名 (com.example.myapp),你可以在 app/build.gradle 文件中找到它。
    • 按照提示下载 google-services.json 文件,并将其复制到你 Android 项目的 app 目录下
  3. 获取服务器密钥
    • 在 Firebase 控制台的左侧菜单,进入 设置 -> 项目设置
    • 云消息传递 标签页下,你会找到 “Web API 密钥”“服务器密钥”
    • 复制“服务器密钥”,这个密钥稍后会在 PHP 代码中使用,用于验证你的服务器身份。

第二步:配置 Android App (客户端准备)

  1. 添加依赖

    • 在项目级 build.gradle 文件中,添加 google-services 插件:

      buildscript {
          dependencies {
              // ...
              classpath 'com.google.gms:google-services:4.3.15' // 使用最新版本
          }
      }
    • 在应用级 build.gradle 文件中,应用插件并添加 FCM 依赖:

      android php 消息推送技术
      (图片来源网络,侵删)
      // 在文件顶部
      apply plugin: 'com.android.application'
      apply plugin: 'com.google.gms.google-services' // 应用插件
      dependencies {
          // ...
          implementation 'com.google.firebase:firebase-messaging:23.1.2' // 使用最新版本
      }
  2. 获取 Device Token 并发送给服务器

    • 创建一个服务来处理 FCM 的生命周期事件。

    • MyFirebaseMessagingService.java:

      import com.google.firebase.messaging.FirebaseMessagingService;
      import com.google.firebase.messaging.RemoteMessage;
      public class MyFirebaseMessagingService extends FirebaseMessagingService {
          @Override
          public void onNewToken(String token) {
              // 当 App 首次启动或 Token 刷新时,此方法被调用
              // token 就是设备的唯一标识符
              sendRegistrationToServer(token);
          }
          @Override
          public void onMessageReceived(RemoteMessage remoteMessage) {
              // 当手机在线且 App 在前台时,收到消息会调用此方法
              // App 在后台,消息会由系统通知栏处理
              sendNotification(remoteMessage.getNotification().getTitle(), remoteMessage.getNotification().getBody());
          }
          private void sendRegistrationToServer(String token) {
              // TODO: 将这个 token 发送到你的 PHP 服务器
              // 你可以使用 Retrofit, OkHttp 或 Volley 等网络库
              // 示例:使用 Volley
              // String url = "https://your-php-server.com/save_token.php";
              // Map<String, String> params = new HashMap<>();
              // params.put("token", token);
              // VolleySingleton.getInstance(this).addToRequestQueue(new CustomPostRequest(url, params, ...));
              System.out.println("Device Token: " + token);
          }
          private void sendNotification(String title, String body) {
              // 创建并显示一个本地通知
              // ... (使用 NotificationCompat.Builder)
          }
      }
    • 别忘了在 AndroidManifest.xml 中注册这个服务

      <service
          android:name=".MyFirebaseMessagingService"
          android:exported="false">
          <intent-filter>
              <action android:name="com.google.firebase.MESSAGING_EVENT" />
          </intent-filter>
      </service>

第三步:PHP 服务器实现 (后端核心)

PHP 服务器主要做两件事:

  1. 接收并存储 Android App 发来的 Device Token

  2. 当需要推送时,调用 FCM API 发送请求

  3. 安装 HTTP 客户端库: 推荐使用 guzzlehttp/guzzle,它能让代码更简洁。

    composer require guzzlehttp/guzzle
  4. 编写接收 Token 的脚本 (save_token.php): 这个脚本很简单,接收一个 POST 请求,将 Token 存储到你的数据库中(MySQL)。

    <?php
    // save_token.php
    header('Content-Type: application/json');
    $response = ['status' => 'error', 'message' => 'Invalid request'];
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $token = $_POST['token'] ?? null;
        $userId = $_POST['user_id'] ?? null; // 假设你关联了用户ID
        if ($token && $userId) {
            // TODO: 将 $token 和 $userId 存储到你的数据库中
            //  INSERT INTO device_tokens (user_id, token) VALUES (?, ?) ON DUPLICATE KEY UPDATE token = VALUES(token)
            // 模拟存储成功
            $response['status'] = 'success';
            $response['message'] = 'Token saved successfully.';
        } else {
            $response['message'] = 'Token or User ID is missing.';
        }
    }
    echo json_encode($response);
    ?>
  5. 编写推送消息的脚本 (send_push_notification.php): 这是 PHP 代码的核心,它负责构建并发送请求到 FCM。

    <?php
    // send_push_notification.php
    require 'vendor/autoload.php'; // 引入 Guzzle
    use GuzzleHttp\Client;
    use GuzzleHttp\Exception\RequestException;
    // 从你的数据库中获取要推送的用户的 Device Token
    // 这里我们为了演示,直接写死一个 token
    $deviceToken = 'YOUR_DEVICE_TOKEN_HERE'; // 替换成从数据库获取的真实 token
    $serverKey = 'YOUR_FCM_SERVER_KEY_HERE'; // 替换成你在 Firebase 控制台获取的 Server Key
    if (empty($deviceToken) || empty($serverKey)) {
        die('Device Token or Server Key is not set.');
    }
    $client = new Client();
    $url = 'https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send'; // 替换成你的项目ID
    $headers = [
        'Authorization
分享:
扫描分享到社交APP