GCM 不致力于姜饼,但致力于冰淇淋三明治

2024-02-02

我正在编写一个使用 GCM 消息的游戏。当一名玩家进入服务器的回合移动时,服务器将向其对手发送一条 GCM 消息,让该客户端知道有额外的回合数据可用。这应该很简单。我已尽可能严格地遵循示例 GCM 客户端代码。

我有两台设备用于测试: 带冰淇淋三明治的 Motorola Xoom 版本 4.0.4 带有 Gingerbread 版本 2.3.5 的 Motorola X2

两种设备都有一个 Goggle 帐户设置(实际上是同一个帐户)。我可以从两者的 Play 商店下载应用程序。当我收到新的 Google Talk 消息或 Gmail 消息时,我都会收到通知消息。它们都在我面前,使用相同的 Wi-Fi 网络,因此我可以确认没有防火墙问题。我在两者上安装了相同的游戏应用程序。我已经能够在两台设备上获得 GCM 注册 ID 号。除了 Android 操作系统版本之外,这两款设备几乎完全相同。但是,Xoom 将接收 GCM 消息,而 X2 不会,或者至少消息不会广播到 X2 上的我的应用程序。

这是我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="myGame.app.main" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="myGame.app.main.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="myGame.app.main.permission.C2D_MESSAGE" />

<application android:icon="@drawable/icon" android:name="myGameApp" android:label="@string/app_name" android:description="@string/description" android:theme="@style/GlobalTheme" android:killAfterRestore="false" android:allowTaskReparenting="false" android:persistent="false">

    ... Other Activities ...

    <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
            <category android:name="myGame.app.main" />
        </intent-filter>
    </receiver>
    <service android:name=".GCMIntentService" android:enabled="true" />
    </application>
</manifest>

这是我的 GCMIntentService 的代码:

package myGame.app.main;

import com.google.android.gcm.GCMBaseIntentService;
import com.google.android.gcm.GCMRegistrar;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import java.util.logging.Logger;

public class GCMIntentService extends GCMBaseIntentService
{
    private static PowerManager.WakeLock sWakeLock;
    private static final Object LOCK = GCMIntentService.class;
    private static final String GCM_SENDER_ID = "... My Sender ID...";
    private static final String GCM_INTENT_FILTER = "myGame.app.main.GCM_MESSAGE";
    private static final String MESSAGE_TYPE = "Type";
    private static final String MESSAGE_CONTENT = "Body";
    private static Logger log = Logger.getLogger(GCMIntentService.class.getName());

    public GCMIntentService()
    {
        super(GCM_SENDER_ID);
    }

    static void runIntentInService(Context context,Intent intent)
    {
        synchronized(LOCK)
        {
            if (sWakeLock == null)
            {
                PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
                sWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"sc_wakelock");
            }
        }
        sWakeLock.acquire();
        intent.setClassName(context,GCMIntentService.class.getName());
        context.startService(intent);
    }

    @Override protected void onRegistered(Context context,String registrationId)
    {
        log.warning("From GCMIntentService: Device successfully registered as "+registrationId);
        ... Other Code ...
    }

    @Override protected void onUnregistered(Context context,String registrationId)
    {
        log.warning("From GCMIntentService: Device successfully unregistered");
        ... Other Code ...
    }

    @Override protected void onMessage(Context context,Intent messageIntent)
    {
        log.warning("From GCMIntentService: Game update notice received");
        ... Other Code ...
    }

    @Override protected void onDeletedMessages(Context context,int total)
    {
        log.warning("From GCMIntentService: Server deleted "+Integer.toString(total)+" pending messages");
    }

    @Override public void onError(Context context,String errorId)
    {
        log.warning("From GCMIntentService: Error "+errorId);
        ... Other Code ...
    }

    @Override protected boolean onRecoverableError(Context context,String errorId)
    {
        log.warning("From GCMIntentService: Recoverable error "+errorId);
        return(super.onRecoverableError(context,errorId));
    }
}

我什至使用自己的 getGCMIntentServiceClassName() 函数创建自己的 GCMBroadcastReceiver 类,并在那里放置一条日志消息。在我尝试过的每个变体中,当应用程序在 Xoom 上运行时,我都会看到正确的 LogCat 消息,但在 X2 上我根本看不到任何 GCM 消息的证据。就好像 GCMBroadcastReceiver 和/或 GCMIntentService 根本不起作用,但我没有看到任何类型的错误消息。

谁能帮我这个?


我编译了 GCM 消息的示例代码。我所做的唯一更改是使用我在游戏应用程序中使用的相同 API 密钥和发件人 ID。该应用程序适用于两台设备,因此我可以再次确认不存在网络问题,并且我可以确认 X2 实际上可以接收 GCM 消息。

坏消息是 X2 仍然没有收到我的游戏的 GCM 消息。经过更多研究,我发现当服务器尝试向 X2 发送 GCM 消息(仅适用于我的游戏应用程序)时,服务器会收到 ERROR_NOT_REGISTERED 结果。发送到 Xoom 时不存在此类错误。我已确认服务器已成功接收注册 ID 号。我知道这很难说,但注册 ID 在传输过程中不会被破坏。

我尝试了一些关于如何从 GCM 服务器取消注册设备的不同已发布建议,但似乎都不起作用。我总是再次收到相同的注册 ID。所以我完全卸载了游戏,然后在 X2 上重新安装了它。这迫使它获得一个新的注册ID号,从而解决了这个问题。我的游戏现在可以在两台设备上正常运行。我必须假设在我调试时,注册 ID 在游戏和 GCM 服务器之间以某种方式混淆了。

我只能希望这不会成为一个常见问题,因为除了卸载应用程序之外似乎没有成功的修复方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GCM 不致力于姜饼,但致力于冰淇淋三明治 的相关文章

随机推荐

  • 将一系列趋势线方程获取到形状文本框

    我试图将图表中第一个系列的趋势线方程获取到工作表上其他位置的形状文本框 但是 只有当我逐行执行代码时 我才能正确填充文本框 在运行时它没有效果 For Each chtObj In ActiveSheet ChartObjects Set
  • 如何获取联系人照片 URI

    我正在与 Android Contact ContentProvider 合作 我有一个电话号码我需要得到URI of the Photo与此电话号码关联的联系人 我该怎么做 我知道我可以得到raw data照片并构建输入流 但我不需要输入
  • 在 jQuery 中向给定日期添加天数[重复]

    这个问题在这里已经有答案了 我有一个包含三个字段的表单 start date days end date 我想通过在开始日期上添加天数来获取结束日期 我的 jQuery 代码是 days change function var start
  • 硬件断点始终为 EXCEPTION_SINGLE_STEP

    我有一个充当调试器的程序 我为线程设置了一个 hw bp 将 dr0 设置为我想要 bp 所在的地址 并将 dr7 设置为 1 因为我希望 bp 在每次执行该地址时生成一个事件 它有效 但现在的问题是我一直没有停止接收 EXCEPTION
  • 当我尝试在 Excel 工作表上运行查询时出现“名称无效括号”错误

    为了制作一些报告 我需要解析一些 Excel 文件 当我尝试从工作表中选择记录时 出现下一个错误 名称 1 的括号无效 页 这是我的代码 OleDbDataAdapter myCommand new OleDbDataAdapter SEL
  • 如何使用泛型来替代一堆处理不同类型的重载方法?

    我有一堆重载方法 它们都获取某种类型的数组作为参数 并从该数组返回一个随机值 function GetRandomValueFromArray Arr array of String String overload begin Result
  • .NET Core - 更改控制器中的依赖关系

    我正在开发一个 Web 应用程序 net core 2 2 并尝试替换控制器中对查询字符串参数的现有依赖项 我知道 可以替换 Startup cs 中的依赖项 ConfigureServices IServiceCollection ser
  • 插入(I,[],[I,[],[]])。如何向二叉树插入一个值?

    要将新元素添加到堆中 我们必须 创建一个包含该元素值的节点 在最后一层的第一个空位置尽可能向左打结 如有必要 创建一个新层 我们总是得到一个完整的二叉树 但不一定是一个堆 我写了这段代码 insert I I insert I G D N
  • 当我尝试使用 winrt 发出通知时,出现错误

    我正在尝试让 winRT 发送通知 我尝试这样做来发出通知 import winrt windows ui notifications as notifications import winrt windows data xml dom a
  • 使用 PPSE 而不是 PSE 读取 EMV 卡

    我正在尝试读取非接触式 Visa Paywave 卡上的数据 对于 Paywave 我必须使用 PPSE 2PAY SYS DDF01 而不是 PSE 1PAY SYS DDF01 提交 SELECT EMV 书籍 1 第 11 3 4 节
  • 选择 ..... 其中 .... 或

    有没有一种方法可以选择同一字段上出现多个条件中的任何一个的数据 示例 我通常会写一个声明 例如 select from TABLE where field 1 or field 2 or field 3 有没有办法可以这样说 select
  • 单向 @OnetoMany 映射会删除所有关系并重新添加剩余关系,而不是删除特定关系

    给出以下代码 public class Course Id GeneratedValue private Long id private String name OneToMany cascade CascadeType ALL orpha
  • (a== 1 && a ==2 && a==3) 可以评估为 true 吗?

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 版主注 请抵制编辑代码或删除此通知的冲动 空白模式可能是问题的一部分 因此不应被不必要地篡改 如果您属于 空白无关紧要 阵营
  • move_uploaded_file 在 nginx 下创建无法访问(403禁止)的文件

    我在 php 中创建了一个简单的上传脚本 该脚本获取从表单提交的文件并将其放入所需的目录中 问题是 由于某种原因 当您尝试在浏览器中显示此文件时 服务器会返回 403 Forbidden 消息 事实上 我修改了脚本 因此它首先从 tmp 文
  • 在没有 jQuery mobile 的情况下在移动设备上使用 mousedown 事件?

    我已经构建了一个 Web 应用程序 为了进行一些改进 我想添加 mousedown 和 mouseup 处理程序来交换图像 在本例中 使按钮看起来像是被按下的 我的代码是这样的 window onload function preload
  • 我可以创建一个 Android 应用程序作为模板吗?

    我不确定它的标题是否正确 但我会解释我的意思 我正在制作多个 Android 应用程序 但它们具有相同的结构 滑动菜单 列表视图 关于我 服装对话框 复制 分享 喜欢 对样式进行一些修改 颜色 背景 字体 菜单字符串 我的问题是 有没有办法
  • JSON Jackson 将不同的键解析到同一字段中

    我有一个 POJO 其中有一个字段 public class Media private Asset asset 将 json 响应解析到此资产 POJO 中时 一切正常 但该资产附带的密钥略有不同 它可以是 JsonProperty co
  • 同时进行网页插入

    我们开发了一个在线测验 用户可以注册一个团队来参加测验 在 asp 中会检查该团队名称是否已提交 如果已提交 则会生成错误 我们注意到一个问题 如果两支球队在同一时间以相同的名称注册 则两支球队都注册了 尽管这种情况不太可能发生 但我们想知
  • 如何比较以逗号分隔的两个列值?

    我有一个包含特定列的表 其中有一列包含逗号分隔的值 例如测试 考试 结果 其他 我将传递一个字符串 例如结果 样本 未知 额外作为存储过程的参数 然后我想通过检查该字符串中的每个短语来获取相关记录 例如 TableA ID Name Wor
  • GCM 不致力于姜饼,但致力于冰淇淋三明治

    我正在编写一个使用 GCM 消息的游戏 当一名玩家进入服务器的回合移动时 服务器将向其对手发送一条 GCM 消息 让该客户端知道有额外的回合数据可用 这应该很简单 我已尽可能严格地遵循示例 GCM 客户端代码 我有两台设备用于测试 带冰淇淋