使用 GCM、PHP 和 MySQL 的 Android 推送通知

Posted

技术标签:

【中文标题】使用 GCM、PHP 和 MySQL 的 Android 推送通知【英文标题】:Android Push Notification using GCM, PHP and MySQL 【发布时间】:2014-03-07 16:23:26 【问题描述】:

我在推送通知方面遇到问题。我正在按照 androidHive 中提到的说明使用 Google Cloud Messaging (GCM)、phpmysql 尝试 Android 推送通知。我的设备已在 GCM 中注册,可以看到数据库中的记录,但是在发送推送通知时,无法在设备上接收。我正在发布我关注的链接。请告知我是否缺少任何东西。 http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/

清单文件:

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidhive.pushnotifications"
    android:versionCode="1"
    android:versionName="1.0" >

    <!-- GCM requires Android SDK version 2.2 (API level 8) or above. -->
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="16" />

    <!-- GCM connects to Internet Services. -->
    <uses-permission android:name="android.permission.INTERNET" />

    <!-- GCM requires a Google account. -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />

    <!-- Keeps the processor from sleeping when a message is received. -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <!-- Creates a custom permission so only this app can receive its messages. -->
    <permission
        android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.androidhive.pushnotifications.permission.C2D_MESSAGE" />

    <!-- This app has permission to register and receive data message. -->
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <!-- Network State Permissions to detect Internet status -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <!-- Permission to vibrate -->
    <uses-permission android:name="android.permission.VIBRATE" />

    <!-- Main activity. -->
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <!-- Register Activity -->
        <activity
            android:name=".RegisterActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Main Activity -->
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name" >
        </activity>

        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>

                <!-- Receives the actual messages. -->
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <!-- Receives the registration id. -->
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.androidhive.pushnotifications" />
            </intent-filter>
        </receiver>

        <service android:name=".GCMIntentService" />
    </application>

</manifest>


index.php

index.php
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
            $(document).ready(function()

            );
            function sendPushNotification(id)
                var data = $('form#'+id).serialize();
                $('form#'+id).unbind('submit');               
                $.ajax(
                    url: "send_message.php",
                    type: 'GET',
                    data: data,
                    beforeSend: function() 

                    ,
                    success: function(data, textStatus, xhr) 
                          $('.txt_message').val("");
                    ,
                    error: function(xhr, textStatus, errorThrown) 

                    
                );
                return false;
            
        </script>
        <style type="text/css">
            .container
                width: 950px;
                margin: 0 auto;
                padding: 0;
            
            h1
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                font-size: 24px;
                color: #777;
            
            div.clear
                clear: both;
            
            ul.devices
                margin: 0;
                padding: 0;
            
            ul.devices li
                float: left;
                list-style: none;
                border: 1px solid #dedede;
                padding: 10px;
                margin: 0 15px 25px 0;
                border-radius: 3px;
                -webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                -moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                color: #555;
            
            ul.devices li label, ul.devices li span
                font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
                font-size: 12px;
                font-style: normal;
                font-variant: normal;
                font-weight: bold;
                color: #393939;
                display: block;
                float: left;
            
            ul.devices li label
                height: 25px;
                width: 50px;               
            
            ul.devices li textarea
                float: left;
                resize: none;
            
            ul.devices li .send_btn
                background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
                background: -webkit-linear-gradient(0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
                background: -moz-linear-gradient(center top, #0096FF, #005DFF);
                background: linear-gradient(#0096FF, #005DFF);
                text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
                border-radius: 3px;
                color: #fff;
            
        </style>
    </head>
    <body>
        <?php
        include_once 'db_functions.php';
        $db = new DB_Functions();
        $users = $db->getAllUsers();
        if ($users != false)
            $no_of_users = mysql_num_rows($users);
        else
            $no_of_users = 0;
        ?>
        <div class="container">
            <h1>No of Devices Registered: <?php echo $no_of_users; ?></h1>
            <hr/>
            <ul class="devices">
                <?php
                if ($no_of_users > 0) 
                    ?>
                    <?php
                    while ($row = mysql_fetch_array($users)) 
                        ?>
                        <li>
                            <form id="<?php echo $row["id"] ?>" name="" method="post" onsubmit="return sendPushNotification('<?php echo $row["id"] ?>')">
                                <label>Name: </label> <span><?php echo $row["name"] ?></span>
                                <div class="clear"></div>
                                <label>Email:</label> <span><?php echo $row["email"] ?></span>
                                <div class="clear"></div>
                                <div class="send_container">                               
                                    <textarea rows="3" name="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
                                    <input type="hidden" name="regId" value="<?php echo $row["gcm_regid"] ?>"/>
                                    <input type="submit" class="send_btn" value="Send" onclick=""/>
                                </div>
                            </form>
                        </li>
                    <?php 
                 else  ?>
                    <li>
                        No Users Registered Yet!
                    </li>
                <?php  ?>
            </ul>
        </div>
    </body>
</html>

注册.php

<?php

// response json
$json = array();

/**
 * Registering a user device
 * Store reg id in users table
 */
if (isset($_POST["name"]) && isset($_POST["email"]) && isset($_POST["regId"])) 
    $name = $_POST["name"];
    $email = $_POST["email"];
    $gcm_regid = $_POST["regId"]; // GCM Registration ID
    // Store user details in db
    include_once './db_functions.php';
    include_once './GCM.php';

    $db = new DB_Functions();
    $gcm = new GCM();

    $res = $db->storeUser($name, $email, $gcm_regid);

    $registatoin_ids = array($gcm_regid);
    $message = array("product" => "shirt");

    $result = $gcm->send_notification($registatoin_ids, $message);
    $headers = array(
        'Authorization: key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );

    echo $result;
 else 
    // user details missing

?>

【问题讨论】:

如果您需要帮助,您必须发布更多详细信息。您是否从 Google 的 GCM 服务器获得了成功的响应?此外,请向我们展示您的清单和相关的客户端代码。发布教程链接没有帮助。 因为代码很大,我只好发布链接。是的,我收到服务器的回复,说该设备已注册。我将使用代码和清单文件编辑问题。 感谢您发布清单。看起来不错。我的意思是,当我询问响应时,当您从服务器向 GCM 发送消息时会得到什么响应(我没有询问注册)。 不幸的是。我没有收到任何回复。我将发布我用来发送通知的 index.php。 你是说echo $result;什么都不打印? 【参考方案1】:

您也可以使用在线工具测试 GCM 推送通知。使用这些在线工具,您将知道您的代码是否存在问题或使用了错误的凭据(GCM 密钥)。

http://pushtry.com/ http://apns-gcm.bryantan.info/ http://www.pushwatch.com/

除此之外,您可以使用 chiarg 的脚本进行测试,该脚本将显示状态(失败和成功以及其他详细信息)。

希望这会对你有所帮助。

【讨论】:

【参考方案2】:

当我尝试使用上面的链接实现推送通知时,我也遇到了同样的问题。 经过几天的废话研发,我找到了解决方案,即我在 php 代码中提供了错误的谷歌密钥。我收到了一些 404 状态错误。

那么解决办法就是

登录谷歌控制台账户Link 创建新项目 在 APIs & Auth-> 选择 API 并启用 Google Cloud Messaging for Android 服务 然后在 APIs & Auth -> 在 Public API access 部分选择“Credentials”->“Create New Key” 在“创建新密钥”对话框下选择“浏览器密钥”。并再次点击“创建”(不在 textarea 中添加任何内容) 它将获得新的 API 密钥。

复制此 api 密钥并将其粘贴到 register.php 代码中。

 $headers = array(
        'Authorization: key=' . 'AIzaSyDa4aTJMblZixlatAZjdDXxCf_2mJqc3WM', // HERE IT IS DEMO KEY
        'Content-Type: application/json'
    );

现在您可以尝试发送通知。它应该可以工作。

享受...快乐的编码。

【讨论】:

对不起 sachin,我已经添加了代码,但它不起作用。我将发布 register.php 文件供您参考。 您是否更改了 GOOGLE_API_KEY,看起来像这样 AIzaSyDa4aTJMblZixlatAZjdDXxCf_2mJqc3WM 您能检查一下 google 注册密钥是否已添加到数据库中吗? 是的。 Reg id 被添加到数据库中。我可以发送完整的代码以供参考吗? 我已将 google api 密钥粘贴到提及的位置。 您是否创建了“浏览器密钥”?或任何其他键?它不会与任何其他键一起使用。不要使用“Android Key”【参考方案3】:

这是一个工作脚本

<?php
class GCM 

    //put your code here
    // constructor
    function __construct() 

    
    /**
    * Sending Push Notification
    */
    static function send_notification($data=array()) 

        // Set POST variables
        $ = 'https://android.googleapis.com/gcm/send';
        $apiKey = 'API key register via google console';
        $data = array(
            'registration_ids' => array($data['device_token']),
            'data' =>array("message"=>$data['message'])
        ); 

        $headers = array(
            'Authorization: key=' . $apiKey,
            'Content-Type: application/json'
        );
        // Open connection

        $ch = curl_init();

        // Set the , number of POST vars, POST data
        curl_setopt($ch, CURLOPT_, $);

        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

        //echo json_encode($data);
        // Execute post
        $result = curl_exec($ch);

        if ($result === FALSE) 
            die('Curl failed: ' . curl_error($ch));
        
        print_r($result);
        // Close connection
        curl_close($ch);
    

这里有 2 个需要考虑的 IMP 事项

1) 通过 google 控制台注册的 API KEY 必须有效。

2) 接收推送的android设备的设备令牌

【讨论】:

以上是关于使用 GCM、PHP 和 MySQL 的 Android 推送通知的主要内容,如果未能解决你的问题,请参考以下文章

使用 C# 与 PHP 的 AES GCM 加密

什么是 GCM 注册 ID?

使用 PHP 的 Google 云消息传递 (GCM)

GCM 推送通知的依赖项

GCM 与 PHP(谷歌云消息)

使用 php 的 gcm 推送通知中的错误