2012-07-25 73 views
0

我在寫一個使用GCM信息的遊戲。當一名玩家進入轉向移動到服務器時,服務器將向其對手發送一條GCM消息,讓該客戶知道額外的轉彎數據可用。這應該很簡單。我儘可能遵循GCM客戶端代碼示例。GCM不在薑餅上工作,但正在研究冰淇淋三明治

我有測試兩個設備: 一個摩托羅拉XOOM與冰淇淋三明治版本4.0.4 摩托羅拉一位X2與薑餅2.3.5版

兩種設備都護目鏡帳戶設置(其實,同樣的帳戶)。我可以在Play商店中下載應用程序。當我收到新的Google Talk消息或Gmail郵件時,我都會收到通知消息。他們都在我面前使用相同的Wi-Fi網絡,所以我可以確認沒有防火牆問題。我在兩者上安裝了相同的遊戲應用程序。我已經能夠在兩臺設備上獲得GCM註冊ID號。除Android OS版本外,兩款設備幾乎完全相同。但是,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完全不起作用,但我看不到任何類型的錯誤消息。

任何人都可以幫助我嗎?

+0

我也忘了提及,我正在使用幾天前發佈的最新的gcm.jar文件。 – user1552958 2012-07-25 22:47:06

+0

您可以嘗試使用Google Apis在模擬器上運行其他測試用例。如果它在ICS仿真器上工作,並且不在2.3.3上,那麼至少可以確認它是Android的版本問題。 – MichaC 2012-07-25 22:58:41

+0

謝謝你的建議。它激勵我做了類似的事情,這導致我找到了答案。我會立即發佈解決方案。 – user1552958 2012-07-26 21:00:04

回答

0

我編譯了GCM消息的示例代碼。我做的唯一更改是使用我在遊戲應用程序中使用的相同API密鑰和發件人ID。這個應用程序可以在兩個設備上工作,所以我可以再次確認沒有網絡問題,我可以確認X2實際上可以接收GCM消息。

壞消息是X2還沒有收到我的遊戲的GCM消息。經過更多的研究,我發現當服務器試圖發送GCM消息給X2(僅適用於我的遊戲應用程序)時,服務器會收到ERROR_NOT_REGISTERED結果。發送到Xoom沒有這樣的錯誤。我已確認服務器正在成功接收註冊ID號碼。我知道這很難說,但註冊ID在傳輸過程中不會受到影響。

我嘗試了幾個不同的發佈建議,關於如何從GCM服務器註銷設備,但似乎沒有任何工作。我總是再次收到相同的註冊ID。所以我完全卸載了我的遊戲,然後重新安裝在X2上。這迫使它得到一個新的註冊ID號碼,解決了這個問題。我的遊戲現在可以在兩臺設備上正常運行我必須假設,在我調試時,註冊ID在某種程度上混淆了遊戲和GCM服務器。

我只能希望這不會成爲一個常見問題,因爲除卸載應用程序之外似乎沒有成功的解決方案。

相關問題