2014-02-13 34 views
0

目標:向Android客戶端發送ping。我在我的用戶對象中保存了一系列設備註冊ID。帶有GCM的App Engine到Android客戶端

在GCMIntentService.java,我的應用程序中創建的汽車,我得到的註冊ID這裏

/** 
* Called back when a registration token has been received from the Google 
* Cloud Messaging service. 
* 
* @param context 
*   the Context 
*/ 
@Override 
public void onRegistered(Context context, String registration) { 
    Log.d(TAG, "onRegistered(context, registration), Registration: " + registration); 

,然後創建DeviceInfo對象(也預置了應用引擎定義),然後這個ID添加到用戶通過另一個端點。我已經證實了這個作品/看到持有的字符串,並假設我的設備現在已正確註冊。

當某些事情在後臺發生,我有一個自定義通知類,並運行此方法:

public void sendNotificationPingToUsers(
     @Named("userIds") ArrayList<Long> userIds, 
     ZeppaNotification notification) throws IOException { 

    Sender sender = new Sender(Constants.SENDER_ID); 
    PersistenceManager mgr = getPersistenceManager(); 

    try { 
     ArrayList<String> allDevices = new ArrayList<String>(); 

     for (int i = 0; i < userIds.size(); i++) { 
      long userId = userIds.get(i); 

      ZeppaUser zeppaUser = mgr 
        .getObjectById(ZeppaUser.class, userId); 

      if (zeppaUser != null) { 
       ZeppaNotification specificNotification = new ZeppaNotification(); 
       specificNotification.setToUserId(userId); 
       specificNotification.setFromUserId(notification 
         .getFromUserId()); 
       specificNotification.setEventId(notification.getEventId()); 
       specificNotification.setExtraMessage(notification 
         .getExtraMessage()); 
       specificNotification.setNotificationType(notification 
         .getType()); 

       String extraMessage = specificNotification 
         .getExtraMessage(); 
       if (extraMessage.length() > 1000) { 
        extraMessage = extraMessage.substring(0, 1000) 
          + "[...]"; 
       } 

       mgr.makePersistent(specificNotification); 

       allDevices.addAll(zeppaUser.getDevices()); 

      } 

     } 

     if (!allDevices.isEmpty()) { 
      Message msg = new Message.Builder().collapseKey("sendToSync") 
        .build(); 

      MulticastResult result = sender.send(msg, allDevices, 5); 
      result.getTotal(); 

     } 

    } catch (IOException ex) { 
     ex.printStackTrace(); 

    } finally { 

     mgr.close(); 
    } 

} 

我通過在其他通知,以便我可以重新創建它的所有用戶,將其保持在通知表,然後ping該設備,以便它可以拉這個和任何其他人看不見,並創建一個狀態欄通知。

這個方法,又在GCMIntentService:

@Override 
public void onMessage(Context context, Intent intent) { 
    Log.d(TAG, "received message ping"); 

不會被調用而這正是我試圖處理所有從事物的設備端。任何人都可以指出我可能做錯了什麼,或者如果我錯誤地解釋了這種服務的工作方式?

謝謝

<?xml version="1.0" encoding="utf-8" standalone="no"?> 

<uses-sdk 
    android:minSdkVersion="15" 
    android:targetSdkVersion="19" /> 

<permission 
    android:name="com.minook.zeppa.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 

<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="com.minook.zeppa.permission.C2D_MESSAGE" /> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<uses-permission android:name="android.permission.READ_CONTACTS" /> 
<uses-permission android:name="android.permission.WAKE_LOCK" /> 
<uses-permission android:name="android.permission.READ_CALENDAR" /> 
<uses-permission android:name="android.permission.WRITE_CALENDAR" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

<application 
    android:name=".ZeppaApplication" 
    android:allowBackup="true" 
    android:icon="@drawable/zeppa_icon" 
    android:label="@string/app_name" 
    android:testOnly="false" 
    android:theme="@style/ZeppaTheme" 
    android:uiOptions="none" > 
    <meta-data 
     android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 

    <activity 
     android:name=".LoginActivity" 
     android:label="@string/app_name" 
     android:logo="@drawable/zeppa_icon" 
     android:screenOrientation="portrait" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:name=".CreateAccountActivity" 
     android:label="@string/create_account" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 
    <activity 
     android:name=".NewFriendsActivity" 
     android:label="@string/add_friends" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
    </activity> 
    <activity 
     android:name=".EventViewActivity" 
     android:label="@string/app_name" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 
    <activity 
     android:name=".NewEventActivity" 
     android:label="@string/app_name" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 
    <activity 
     android:name=".UserActivity" 
     android:label="@string/app_name" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 
    <activity 
     android:name=".ZeppaPreferenceActivity" 
     android:label="@string/event_details" 
     android:logo="@drawable/zeppa_icon" > 
    </activity> 

    <!-- 
    <activity 
     android:name=".RegisterActivity" 
     android:launchMode="singleTop" > 
    </activity> 
    --> 

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

    <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" /> 

      <category android:name="com.minook.zeppa" /> 
     </intent-filter> 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 

      <category android:name="com.minook.zeppa" /> 
     </intent-filter> 
    </receiver> 
</application> 

另注:我一直在使用的項目數,並通過與沒有指定IP的GAE控制檯生成的服務器密鑰嘗試。迄今爲止都沒有工作。

+1

請張貼您的清單。 – Eran

+0

任何想法..? – PSchuette

+0

您的服務器從Google獲得什麼響應? – Eran

回答

0

我剛剛意識到我從來沒有回到這個。 原來他應用引擎創建的GCM代碼並不是實現它的理想方式。這是我的應用程序中的基本代碼,現在已經成功從後端發送一個發送到同步,並在狀態欄中顯示一條通知。

public class ZeppaGCMReceiver extends WakefulBroadcastReceiver { 

    final private static String TAG = "GCMIntentService"; 
    private static String registrationId = null; 

    public static void register(final ZeppaApplication application) { 

     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(application 
       .getApplicationContext()); 
     try { 

      registrationId = gcm.register(Constants.PROJECT_NUMBER); 
      Log.d(TAG, "gcm.register(" + registrationId + ")"); 

      ZeppaUser currentUser = ZeppaUserSingleton.getInstance().getUser(); 
      if (currentUser.getDevices() == null 
        || !currentUser.getDevices().contains(registrationId)) { 
       new AsyncTask<Void, Void, Void>() { 

        @Override 
        protected Void doInBackground(Void... params) { 
         Zeppauserendpoint.Builder endpointBuilder = new Zeppauserendpoint.Builder(
           AndroidHttp.newCompatibleTransport(), 
           new JacksonFactory(), 
           application.getGoogleAccountCredential()); 
         endpointBuilder = CloudEndpointUtils 
           .updateBuilder(endpointBuilder); 

         Zeppauserendpoint userEndpoint = endpointBuilder 
           .build(); 
         try { 
          RegisterUserDevice registerTask = userEndpoint 
            .registerUserDevice(
              ZeppaUserSingleton.getInstance().getUserId(), 
              registrationId); 
          registerTask.execute(); 

         } catch (IOException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 

         return null; 
        } 

       }.execute(); 
      } else { 
       Log.d(TAG, "Already Registered"); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public static void unregister(final ZeppaApplication application) { 
     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(application 
       .getApplicationContext()); 
     // TODO: registration id in preferences and 
     try { 
      gcm.unregister(); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public void onReceive(Context context, Intent intent) { 

     Log.d(TAG, "received message ping"); 

     GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); 
     String messageType = gcm.getMessageType(intent); 

     Log.d(TAG, "MessageType: " + messageType); 

     if (messageType == null) { 
      Log.d(TAG, "Message is null"); 
      return; 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR 
       .equals(messageType)) { 
      Log.d(TAG, "Error!"); 
      return; 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED 
       .equals(messageType)) { 
      Log.d(TAG, "Deleted"); 
      return; 
     } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE 
       .equals(messageType)) { 
      Log.d(TAG, "Message"); 
      handlePingInAsync(context); 
     } else { 
      Log.d(TAG, "WTF are you..? " + intent.toString()); 
     } 

    } 

    private void handlePingInAsync(Context context) { 

     Context[] param = {context}; 
     new AsyncTask<Context, Void, Void>() { 

      @Override 
      protected Void doInBackground(Context... params) { 
       Context context = params[0]; 
       GoogleAccountCredential credential = getCredential(context); 
       if (credential == null) { 
        return null; 
       } 

       Zeppanotificationendpoint.Builder endpointBuilder = new Zeppanotificationendpoint.Builder(
         AndroidHttp.newCompatibleTransport(), 
         new JacksonFactory(), credential); 
       endpointBuilder = CloudEndpointUtils 
         .updateBuilder(endpointBuilder); 
       Zeppanotificationendpoint notificationEndpoint = endpointBuilder 
         .build(); 

       try { 
        SharedPreferences prefs = context.getSharedPreferences(
          Constants.SHARED_PREFS, Context.MODE_PRIVATE); 

        Long userId = prefs.getLong(Constants.USER_ID, -1); 
        if (userId > 0) { 
         GetUnseenNotifications getUnseenNotifications = notificationEndpoint 
           .getUnseenNotifications(userId); 
         CollectionResponseZeppaNotification collectionResponse = getUnseenNotifications 
           .execute(); 
         if (collectionResponse == null 
           || collectionResponse.getItems() == null) { 
         } else { 

          List<ZeppaNotification> notifications = collectionResponse 
            .getItems(); 
          sendNotificationsForResult(notifications, 
            context); 

          try { 
           NotificationSingleton.getInstance() 
             .addAllNotifcations(notifications); 
          } catch (NullPointerException ex) { 
           ex.printStackTrace(); 
          } 
         } 

        } else { 
         Log.d(TAG, "No Set userId"); 
        } 
       } catch (IOException ioEx) { 
        ioEx.printStackTrace(); 
       } 
       return null; 

      } 

     }.execute(param); 

    } 

    private GoogleAccountCredential getCredential(Context context) { 
     GoogleAccountCredential credential = ((ZeppaApplication) context.getApplicationContext()) 
       .getGoogleAccountCredential(); 
     if (credential == null) { 
      SharedPreferences prefs = context.getSharedPreferences(
        Constants.SHARED_PREFS, Context.MODE_PRIVATE); 
      String email = prefs.getString(Constants.EMAIL_ADDRESS, null); 
      if (email != null && !email.isEmpty() && Constants.IS_CONNECTED) { 
       credential = GoogleAccountCredential.usingAudience(context, 
         Constants.APP_ENGINE_AUDIENCE_CODE); 
       credential.setSelectedAccountName(email); 
       return credential; 
      } 

      return null; 
     } else { 
      return credential; 
     } 
    } 

    @SuppressLint("NewApi") 
    @SuppressWarnings("deprecation") 
    private void sendNotificationsForResult(List<ZeppaNotification> resultList, 
              Context context) { 

     Log.d(TAG, "trying to send Notifications for result"); 
     Notification.Builder notifBuilder = new Notification.Builder(context); 

     if (resultList.size() > 1) { 
      notifBuilder.setContentTitle(resultList.size() 
        + " new notifications"); 

      StringBuilder stringBuilder = new StringBuilder(); 
      for (ZeppaNotification notification : resultList) { 
       stringBuilder.append(notification.getExtraMessage()).append(
         '\n'); 
      } 

      notifBuilder.setContentText(stringBuilder.toString()); 

      Intent intent = new Intent(context, MainActivity.class); 
      intent.putExtra(Constants.INTENT_NOTIFICATIONS, true); 
      PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, 
        intent, 0); 
      notifBuilder.setContentIntent(pendingIntent); 
     } else { 
      ZeppaNotification notification = resultList.get(0); 
      manageSingleNotification(context, notification, notifBuilder); 
      notifBuilder.setContentText(notification.getExtraMessage()); 
     } 

     notifBuilder.setLights(Color.CYAN, 750, 3000); 
     notifBuilder.setAutoCancel(true); 
     notifBuilder.setSmallIcon(R.drawable.notif_ic_zeppa); 
     Notification notification = null; 

     if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { 
      notifBuilder.setPriority(Notification.PRIORITY_DEFAULT); 
      notification = notifBuilder.build(); 
     } else { 
      notification = notifBuilder.getNotification(); 
     } 
     NotificationManager notificationManager = (NotificationManager) context 
       .getSystemService(Context.NOTIFICATION_SERVICE); 

     Log.d(TAG, "Notification Should Post"); 
     notificationManager.notify(0, notification); 

    } 

    private void manageSingleNotification(Context context, 
              ZeppaNotification notification, Notification.Builder builder) { 

     Intent intent = null; 
     switch (notification.getNotificationOrdinal()) { 
      case 0: 
       builder.setContentTitle("New Friend Request"); 
       intent = new Intent(context, NewFriendsActivity.class); 
       break; 
      case 1: 
       builder.setContentTitle("New Connection"); 
       intent = new Intent(context, UserActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_USER_ID, 
         notification.getFromUserId()); 
       break; 

      case 2: 
       builder.setContentTitle("Event Recommendation"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 3: 
       builder.setContentTitle("New Invite"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 4: 
       builder.setContentTitle("Event Comment"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 5: 
       builder.setContentTitle("Event Canceled"); 
       intent = new Intent(context, MainActivity.class); 
       intent.putExtra(Constants.INTENT_NOTIFICATIONS, false); 
       break; 

      case 6: 
       builder.setContentTitle("Event Updated"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 7: 
       builder.setContentTitle("Friend Joined Event"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 8: 
       builder.setContentTitle("Friend Left Event"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      case 9: 
       builder.setContentTitle("Let's Find a Time?"); 
       break; 

      case 10: 
       builder.setContentTitle("Time Found!"); 
       break; 

      case 11: 
       builder.setContentTitle("Event Reposted"); 
       intent = new Intent(context, EventViewActivity.class); 
       intent.putExtra(Constants.INTENT_ZEPPA_EVENT_ID, 
         notification.getEventId()); 
       break; 

      default: // this shouldnt happen 
       builder.setContentTitle("New Zeppa Notification"); 
       intent = new Intent(context, MainActivity.class); 
       intent.putExtra(Constants.INTENT_NOTIFICATIONS, false); 
       break; 
     } 

     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, 
       intent, 0); 

     builder.setContentIntent(pendingIntent); 
    } 
} 

然後我的清單需要:

<permission 
    android:name="package.permission.C2D_MESSAGE" 
    android:protectionLevel="signature" /> 

<uses-permission android:name="package.permission.C2D_MESSAGE" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.USE_CREDENTIALS" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> 
<receiver 
     android:name="package.ZeppaGCMReceiver" 
     android:exported="true" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 

      <category android:name="package.GCMIntentService" /> 
     </intent-filter> 
    </receiver> 

    <service 
     android:name="package.ZeppaGCMService" 
     android:enabled="true" /> 

然後,終於,從我的端點類,當某些東西被輸入到數據庫中,我確定這應該通知用戶,並觸發此方法:

注意:getDevices只返回android設備IDS。我擺脫了DeviceInfo類,它似乎不是很有用,但這應該是處理這種情況的不正確方法。我相信你知道iOS的處理方式不同。如果我改變這個/如果人們想要看到iOS的實現,將會更新。

public void sendNotificationPingToUsers(
     @Named("userIds") List<Long> userIds, 
     ZeppaNotification notification) { 

    Sender sender = new Sender(Constants.SENDER_ID); 

    PersistenceManager mgr = getPersistenceManager(); 

    try { 
     List<String> allDevices = new ArrayList<String>(); 

     for (int i = 0; i < userIds.size(); i++) { 
      long userId = userIds.get(i); 

      ZeppaUser zeppaUser = mgr 
        .getObjectById(ZeppaUser.class, userId); 

      if (zeppaUser != null) { 
       ZeppaNotification specificNotification = new ZeppaNotification(); 
       specificNotification.setToUserId(userId); 
       specificNotification.setFromUserId(notification 
         .getFromUserId()); 
       specificNotification.setEventId(notification.getEventId()); 
       specificNotification.setExtraMessage(notification 
         .getExtraMessage()); 
       specificNotification.setNotificationType(notification 
         .getType()); 

       mgr.makePersistent(specificNotification); 

       allDevices.addAll(zeppaUser.getDevices()); 

      } 

     } 
     if (!allDevices.isEmpty()) { 

      Message msg = new Message.Builder().collapseKey("sendToSync") 
        .build(); 

      MulticastResult result = sender.send(msg, allDevices, 500); 
      result.getTotal(); 

     } 

    } catch (IOException ex) { 
     ex.printStackTrace(); 
    } finally { 
     mgr.close(); 
    } 

} 
相關問題