Android GCM快速入门:检查令牌是否存在

4
我正在尝试理解Google 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中,注释说明最初调用是为了检索令牌,但后续调用是本地的。这是否意味着它只是检查应用程序是否已经有令牌,而不再进行调用?我真的不理解这部分内容,也没有看到任何示例代码在哪里检查令牌的存在。
2个回答

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();
}
}

您可以阅读以下链接以获取更多信息:

添加Google云消息(GCM)用于Android - 注册过程

希望这能帮到您!


R.string.gcm_defaultSenderId(发送者ID)通常是从google-services.json中获取的。您知道这是如何完成的吗?我的意思是,gcm sdk如何读取json并将其加载到R.string中? - Weishi Z
@WeishiZeng 抱歉,我不知道,但是也许你可以在https://dev59.com/SVwZ5IYBdhLWcg3wVO5U找到更多信息。 - BNK

1

InstanceID是Google Play Services库的一部分,它会检查是否有缓存的令牌,并在调用getToken时返回该令牌。如果没有缓存的令牌,则会向网络请求获取新的令牌并返回。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接