GCM 如何使用 GCM 和 3rd 方服务器注销设备

Posted

技术标签:

【中文标题】GCM 如何使用 GCM 和 3rd 方服务器注销设备【英文标题】:GCM how to unregister a device with GCM and 3rd party server 【发布时间】:2013-04-29 12:45:25 【问题描述】:

我有一个使用 GCM 推送通知的应用。它工作正常,我的设备注册并接收推送消息。

如果我从我的设备上卸载该应用程序,我将不再收到您所期望的消息。在我卸载应用程序后,您在服务器上发送消息的文本框仍然存在,这也是我所期望的。

我查看了有关注销的文档,您可以手动或自动执行此操作。

The end user uninstalls the application.
The 3rd-party server sends a message to GCM server.
The GCM server sends the message to the device.
The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it, which returns false.
The GCM client informs the GCM server that the application was uninstalled.
The GCM server marks the registration ID for deletion.
The 3rd-party server sends a message to GCM.
The GCM returns a NotRegistered error message to the 3rd-party server.
The 3rd-party deletes the registration ID.

我不明白上面列表中倒数第二个语句。

The GCM returns a NotRegistered error message to the 3rd-party server.

这是如何实现的?

另外,如果从设备上卸载了该应用程序,它如何执行以下语句?是否有在从设备中删除应用程序时执行的应用程序生命周期方法?如果有,这是放置代码的地方,通知 GCM 服务器卸载并调用 3rd 方服务器上的 php 脚本从数据库中删除 regID?

The GCM client informs the GCM server that the application was uninstalled.

提前致谢,

马特

[edit1]

static void unregister(final Context context, final String regId) 
        Log.i(TAG, "unregistering device (regId = " + regId + ")");
        String serverUrl = SERVER_URL + "/unregister.php";
        Map<String, String> params = new HashMap<String, String>();
        params.put("regId", regId);
        try 
            post(serverUrl, params);
            GCMRegistrar.setRegisteredOnServer(context, false);
            String message = context.getString(R.string.server_unregistered);
            CommonUtilities.displayMessage(context, message);
         catch (IOException e) 
            // At this point the device is unregistered from GCM, but still
            // registered in the server.
            // We could try to unregister again, but it is not necessary:
            // if the server tries to send a message to the device, it will get
            // a "NotRegistered" error message and should unregister the device.
            String message = context.getString(R.string.server_unregister_error,
                    e.getMessage());
            CommonUtilities.displayMessage(context, message);
        
    

[编辑2] 下面的注销代码用于在从手机中删除应用程序后在 3rd 方服务器上注销设备。该代码是对下面教程的补充。

tutorial

send_messages.php

<?php
if (isset($_GET["regId"]) && isset($_GET["message"])) 
    $regId = $_GET["regId"];
    $message = $_GET["message"];
    $strRegID = strval($regId);

    include_once './GCM.php';
    include_once './db_functions.php';
    $gcm = new GCM();

    $registatoin_ids = array($regId);
    $message = array("price" => $message);

    $result = $gcm->send_notification($registatoin_ids, $message);
    $db = new db_Functions();

    if (strcasecmp ( strval($result) , 'NotRegistered' )) 
    $db->deleteUser($strRegID);
    

?>

db_functions.php

public function deleteUser($regid) 

    $strRegID = strval($regid);

    $serverName = "LOCALHOST\SQLEXPRESS"; 
        $uid = "gcm";     
        $pwd = "gcm";    
        $databaseName = "gcm";   

        $connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd, "Database"=>$databaseName); 


             $db = sqlsrv_connect($serverName,$connectionInfo) or die("Unable to connect to server");

             $query = "DELETE FROM gcmUser2 WHERE gcuRegID = '$regid'";
             $result = sqlsrv_query($db, $query);


    

【问题讨论】:

【参考方案1】:

当 GCM 服务器在应用卸载后尝试向设备发送消息时,GCM 客户端检测到该应用不再安装在设备上。您不在应用程序代码中执行此操作。 android 操作系统的 GCM 客户端组件会执行此操作。

下次尝试向卸载它的设备上的应用发送消息时,GCM 服务器将已经知道它已被卸载,并向您发送NotRegistered 错误。

从设备中删除应用时不会调用生命周期方法。如果有,您将不需要上面引用的事件序列,以便 GCM 服务器和第 3 方服务器检测到应用程序已卸载(因为您可以使用这种方法从GCM 服务器并让第 3 方服务器知道该应用已从该设备上卸载)。

【讨论】:

好的,谢谢,那么我会在什么时候通知带有 regID 的第 3 方服务器删除?如果我只是从设备中删除应用程序,我的 [edit1] 中的代码是否会在某些时候执行,这可能会将 regID 传递给从数据库中删除 regID 的 php 文件? 不客气。你没有。您无法知道应用程序何时被卸载,因此您无法知道何时调用该代码。您应该调用此代码的唯一情况是,如果您想停止将 GCM 消息发送到应用程序,即使它仍安装在设备上。如果应用程序被卸载,第 3 方服务器在尝试向该设备发送消息后收到 NotRegistered 错误时将知道删除 regID。 嗨,我明白你在说什么,但我仍然对我所遵循的教程感到有些不知所措。在我看来,我认为教程中可能缺少一个文件来处理从 3rd 方服务器的数据库中删除 regID。您说 GCM 服务器告诉第 3 方服务器从数据库中删除 regID,但没有相应的 php 文件可以执行此操作。如果您有时间,您能否快速查看一下 php 文件,并验证我对丢失的取消注册文件的想法 @turtleboy 我不懂 PHP,所以我无法帮助你。但是,您不需要特定的 PHP 文件来删除 regID。发送消息的 PHP 应该处理来自 Google 的所有可能的响应。如果返回 NotRegistered 错误作为对已发送消息之一的响应,则应从数据库中删除与该消息一起发送的注册 ID。 [edit2] 是我编写的代码,用于在用户从手机中删除应用程序后从 3rd 方服务器中删除 regID。希望这对任何人都有帮助

以上是关于GCM 如何使用 GCM 和 3rd 方服务器注销设备的主要内容,如果未能解决你的问题,请参考以下文章

GCM 的注册 ID 重复

使所有 gcm 令牌无效

GCM API 密钥,第三方服务器的注册 ID

Android-GCM:如何照顾注销的用户?

使用 3rd 方库和为同一应用程序单独 GCM 实现时 GCM 注册步骤冲突?

GCM,注册 ID 和处理用户登录/注销