2015-10-23 57 views
4

我想了解Google的GCM快速入门示例背后的代码。具体来说,我不明白代码是如何检查注册是否已经完成。Android GCM快速入门检查令牌

MainActivity:

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ... 
     if (checkPlayServices()) { 
      // Start IntentService to register this application with GCM. 
      Intent intent = new Intent(this, RegistrationIntentService.class); 
      startService(intent); 
     } 
    } 

RegistrationIntentService:

@Override 
protected void onHandleIntent(Intent intent) 
{ 
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 

    try { 
     // [START register_for_gcm] 
     // Initially this call goes out to the network to retrieve the token, subsequent calls 
     // are local. 
     // [START get_token] 
     InstanceID instanceID = InstanceID.getInstance(this); 
     // R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json. 
     // See https://developers.google.com/cloud-messaging/android/start for details on this file. 
     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); 

     // 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(AppSharedPreferences.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(AppSharedPreferences.SENT_TOKEN_TO_SERVER, false).apply(); 
    } 
    // Notify UI that registration has completed, so the progress indicator can be hidden. 
    Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE); 
    LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete); 
} 

RegistrationIntentService,评论说,最初的呼叫转到检索令牌,但后续调用是本地的。这是否意味着它只会检查应用程序是否已经拥有该令牌并且不再进行通话?我真的不明白这个部分,我没有看到这个示例代码中的任何地方,它检查令牌的存在。

回答

4

对于逻辑,你可以参考我的工作示例代码:

public class MainActivity extends AppCompatActivity { 

private final Context mContext = this; 
private final String SENDER_ID = "425...."; // Project Number at https://console.developers.google.com/project/.... 
private final String SHARD_PREF = "com.example.gcmclient_preferences"; 
private final String GCM_TOKEN = "gcmtoken"; 
private final String LOG_TAG = "GCM"; 
public static TextView mTextView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE); 
    String token = appPrefs.getString(GCM_TOKEN, ""); 
    if (token.isEmpty()) { 
     try { 
      getGCMToken(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    mTextView = (TextView) findViewById(R.id.textView); 
}  

private void getGCMToken() { 
    new AsyncTask<Void, Void, Void>() { 
     @Override 
     protected Void doInBackground(Void... params) { 
      try { 
       InstanceID instanceID = InstanceID.getInstance(mContext); 
       String token = instanceID.getToken(SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); 
       if (token != null && !token.isEmpty()) { 
        SharedPreferences appPrefs = mContext.getSharedPreferences(SHARD_PREF, Context.MODE_PRIVATE); 
        SharedPreferences.Editor prefsEditor = appPrefs.edit(); 
        prefsEditor.putString(GCM_TOKEN, token); 
        prefsEditor.apply(); 
       } 
       Log.i(LOG_TAG, token); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    }.execute(); 
} 
} 

您可以获取更多信息下面看我的回答

Adding Google Cloud Messagin (GCM) for Android - Registration process

希望这有助于!

+0

'R.string.gcm_defaultSenderId(发件人ID)通常来自google-services.json.'你是否知道这是如何完成的?我的意思是如何gcm sdk阅读'json'并将其加载到'R.string' –

+0

@WeishiZeng抱歉,我不知道,但是,也许你可以在http://stackoverflow.com/questions/31597953找到更多信息。 /什么 - 不 - 谷歌的服务,JSON-真的-DO – BNK

1

作为Google Play服务库一部分的InstanceID将检查是否存在缓存的令牌,并在调用getToken时返回该令牌。如果没有缓存的令牌,那么它将发送到网络以检索新令牌并返回该令牌。

因此,您的应用程序必须处理调用InstanceID.getToken将导致网络调用的可能性。因此它在IntentService中被调用的原因。