2015-04-03 32 views
0

我有叫Otto Event称为LoadAuthenticateEvent那么这个事件去一个活动我ClientManager.java在下面的代码是:合适的设计模式来抓取GCM推送通知的注册ID?

@Subscribe 
public void onLoadAuthenticateEvent(LoadAuthenticateEvent loadAuthenticateEvent) { 

    // GCM cannot register on the main thread 
    String deviceID = ""; 
    Thread thread = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      String differentId = GCMRegistrationUtil.registerDevice(mContext); 
      Log.d(TAG, "Device Id: " + differentId); 
     } 
    }); 
    thread.start(); 


    String email = loadAuthenticateEvent.getEmail(); 
    String password = loadAuthenticateEvent.getPassword(); 

    Callback<User> callback = new Callback<User>() { 
     @Override 
     public void success(User user, Response response) { 
      sClient.setOrganization(user.getRole().getOrganization().getSubdomain()); 
      mBus.post(new LoadedMeEvent(user)); 
     } 

     @Override 
     public void failure(RetrofitError retrofitError) { 
      mBus.post(new LoadedErrorEvent(retrofitError)); 
     } 
    }; 

    sClient.authenticate(email, password, deviceID, PLATFORM, callback); 
} 

的问题是,服务器需要deviceID,但GCM需要一个电话是异步而不是在主线程上,我应该如何去实现这一点,我可以正确获取deviceID并将其传递给sClient?由于deviceID可能为空。

回答

2

,最好的办法是联系内部GCM是通过服务

  1. 创建IntentService捕捉从 活性

    onHandleIntent(意向意图)

  2. 设备发送服务请求GCM和接收tokenID释放的意图。

    InstanceID instanceID = InstanceID.getInstance(this); String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE,null);

  3. 实施此方法将任何注册发送到您的应用程序的服务器。

    sendRegistrationToserver(令牌)

  4. 通知registrationComplete

    意图registrationComplete =新意图(GcmUtils.REGISTRATION_COMPLETE)UI; LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);

  5. (可选)订阅主题频道 私人无效subscribeTopics(字符串令牌,ArrayList的topics_gcm)抛出IOException异常{ 为(字符串主题:topics_gcm){ GcmPubSub发布订阅= GcmPubSub.getInstance(本); pubSub。订阅(令牌,主题,空); } }

全IntentService:

public class RegistrationIntentService extends IntentService { 
private static final String TAG = "RegIntentService"; 

public RegistrationIntentService() { 
    super(TAG); 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    ArrayList<String> topics_gcm = intent.getStringArrayListExtra("topics_gcm"); 
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 

    try { 
     // In the (unlikely) event that multiple refresh operations occur simultaneously, 
     // ensure that they are processed sequentially. 
     synchronized (TAG) { 
      // Initially this call goes out to the network to retrieve the token, subsequent calls 
      // are local. 
      // [START get_token] 
      InstanceID instanceID = InstanceID.getInstance(this); 
      String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), 
        GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
      // [END get_token] 
      Log.i(TAG, "GCM Registration Token: " + token); 

      // TODO: Implement this method to send any registration to your app's servers. 
      //sendRegistrationToServer(token); 

      // TODO: Subscribe to topic channels 
      //subscribeTopics(token, topics_gcm); 

      // You should store a boolean that indicates whether the generated token has been 
      // sent to your server. If the boolean is false, send the token to your server, 
      // otherwise your server should have already received the token. 
      sharedPreferences.edit().putBoolean(GcmUtils.SENT_TOKEN_TO_SERVER, true).apply(); 
      // [END register_for_gcm] 
     } 
    } catch (Exception e) { 
     Log.d(TAG, "Failed to complete token refresh", e); 
     // If an exception happens while fetching the new token or updating our registration data 
     // on a third-party server, this ensures that we'll attempt the update at a later time. 
     sharedPreferences.edit().putBoolean(GcmUtils.SENT_TOKEN_TO_SERVER, false).apply(); 
    } 
    // Notify UI that registration has completed, so the progress indicator can be hidden. 
    Intent registrationComplete = new Intent(GcmUtils.REGISTRATION_COMPLETE); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); 
} 

/** 
* Persist registration to third-party servers. 
* 
* Modify this method to associate the user's GCM registration token with any server-side account 
* maintained by your application. 
* 
* @param token The new token. 
*/ 
private void sendRegistrationToServer(String token) { 
    // Add custom implementation, as needed. 
} 

/** 
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant. 
* 
* @param token GCM token 
* @throws IOException if unable to reach the GCM PubSub service 
*/ 
// [START subscribe_topics] 
private void subscribeTopics(String token, ArrayList<String> topics_gcm) throws IOException { 
    for (String topic : topics_gcm) { 
     GcmPubSub pubSub = GcmPubSub.getInstance(this); 
     pubSub.subscribe(token, topic, null); 
    } 
} 
// [END subscribe_topics] 

}

从任何上下文
  • 开始IntentService:活动,服务....
    Intent intent = new Intent(getContext(), egistrationIntentService.class); intent.putCharSequenceArrayListExtra("topics_gcm", topcics_gcm); getContext().startService(intent);
  • 0

    如果您想在UI线程上进行sClient调用(不确定这是否适合您),请在您的GCM注册ID由GCM返回后使用Handler调用它。

    接受的答案here有示例代码来帮助你。

    +0

    谢谢Koh我现在回到这个实现,现在看看这个。 – AndyRoid 2015-05-22 20:47:29

    0

    最后我用一个AsyncTask像所以这个具体的事情:

    private void registerInBackground() { 
    
        new AsyncTask<Void, Void, String>() { 
    
         @Override 
         protected String doInBackground(Void... params) { 
          String regId = ""; 
          try { 
           if (gcm == null) { 
            gcm = GoogleCloudMessaging.getInstance(mContext); 
           } 
    
           regId = gcm.register(GCMConfig.getSenderId()); 
           storeRegistrationId(mContext, regId); 
    
          } catch (IOException e) { 
           Log.e(TAG, "Error: ", e); 
           e.printStackTrace(); 
          } 
    
          Log.d(TAG, "GCM AsyncTask completed"); 
          return regId; 
         } 
    
         @Override 
         protected void onPostExecute(String result) { 
    
          // Get the message 
          Log.d(TAG, "Registered with GCM Result: " + result); 
    
         } 
    
        }.execute(null, null, null); 
    
    } 
    

    这真的很好的GCMRegistration