2015-04-03 53 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