问题 GCM如何使用GCM和第三方服务器取消注册设备


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

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

我查看了有关取消注册的文档,您可以手动或自动完成。

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服务器卸载并调用第三方服务器上的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);
        }
    }

[EDIT2] 以下取消注册代码用于在从手机中删除应用程序后取消注册第三方服务器上的设备。该代码是以下教程的补充。

教程

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);


    }

3541
2018-04-29 12:45


起源



答案:


当GCM服务器在卸载应用程序后尝试将消息发送到设备时,GCM客户端会检测到该应用程序不再安装在设备上。您不在应用程序代码中执行此操作。 Android OS的GCM客户端组件可以做到这一点。

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

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


14
2018-04-29 12:56



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


答案:


当GCM服务器在卸载应用程序后尝试将消息发送到设备时,GCM客户端会检测到该应用程序不再安装在设备上。您不在应用程序代码中执行此操作。 Android OS的GCM客户端组件可以做到这一点。

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

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


14
2018-04-29 12:56



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