在玩家未登录时处理 Google 玩游戏成就

Handling Google Play Game Achievements when player isn't logged in

我第一次使用 Google 的成就 API,发现它的设置相当简单。我搞定了,运行在大约一个小时后完成了,但是,有一件事我想不通,就是当用户不在的时候如何解锁成就t 已登录(或者更确切地说,存储成就 x 已在本地解锁的事实,以便在用户下次登录时实际解锁)。

如果用户已登录,我的成就可以解锁。

最初,当我在没有登录的情况下进行测试时,我得到了一个'googleAPI客户端尚未连接' 在我的 LogCat.

中弹出错误

所以我做了这样的事情:

public void unlockAchievements(){
    if (isSignedIn()){        
        Games.Achievements.unlock(getApiClient(), myAchievementID);
    }
}

这显然避免了崩溃,但是(同样,很明显)如果用户尚未登录则不会解锁成就。

有没有 'official' 处理这个的方法(我似乎在文档中找不到任何关于这个的提及 - 虽然我可能已经错过了)。

如果没有,执行此操作的好方法是什么?

我可以这样做:

if (score>1000){  
    score1000Achievement = true;  //Save this to SharedPreferences
}

稍后,执行此操作:

onSignInSucceeded(){
    if (score1000Achievement){
        Games.Achievements.unlock(getApiClient(), myAchievementID);  
    }
}

但是,这会 运行 并尝试在 每次 登录时解锁,如果有多个成就和多个用户,这肯定会增加我的 API打电话,因此不必要地占用了我的配额?

感谢任何建议

编辑

刚在 Android 开发者网站上找到这个

An unlocked achievement means that the player has successfully earned the achievement. An achievement can be unlocked offline. When the game comes online, it syncs with the Google Play games services to update the achievement's unlocked state.

然而,似乎没有进一步提及它,也没有说明这是如何实现的。

我采用了与您相同的方法,但我保存了另一个布尔值以了解该成就是否在 Google 游戏中解锁。但是不记得了,如果解锁有成功-return 值。

我知道已经晚了但还是想分享我的方法 我的方法类似,即将所有成就的状态保存到 SharedPreferences。但是我没有使用两个布尔值(根据 Simon 的回答),一个用于存储成就,另一个用于检查成就是否在 Google Play 上解锁。相反,我使用一个 int 来存储成就的状态。

例如 -1 表示成就尚未解锁,0 表示已解锁,1 表示已发布到 Google Play。

这里有一小段代码供参考。

public class AccomplishmentsOutbox {
    public static final int LOCKED = -1;
    public static final int UNLOCKED = 0;
    public static final int PUSHED = 1;

    private static final String PREFS_KEY_ACCOMPLISHMENTS = "player_accomplishments";
    // ACHIEVEMENTS
    private static String PREFS_KEY_ACH_1;

    // Singleton instance
    private static AccomplishmentsOutbox mOutbox;
    private SharedPreferences settings;

    private AccomplishmentsOutbox(Context mContext) {
        settings = mContext.getSharedPreferences(PREFS_KEY_ACCOMPLISHMENTS, Context.MODE_PRIVATE);

        // ACHIEVEMENTS
        PREFS_KEY_ACH_1 = mContext.getString(R.string.achievement_one);
    }
    public static AccomplishmentsOutbox getAccomplishmentsOutbox(Context context) {
        if (mOutbox == null) {
            mOutbox = new AccomplishmentsOutbox(context);
        }
        return mOutbox;
    }

    public int isOne() {
        return settings.getInt(PREFS_KEY_ACH_1, LOCKED);
    }

    public void putOne(int value) {
        settings.edit().putInt(PREFS_KEY_ACH_1, value).apply();
    }
}

现在,当我想检查成就是否已在 Activity 中解锁时,我使用了:这现在将状态保存在共享首选项中。

AccomplishmentsOutbox mOutbox = AccomplishmentsOutbox.getAccomplishmentsOutbox(this);

if (corrected == 0) {
            mOutbox.putOne(AccomplishmentsOutbox.UNLOCKED);
}

现在,当我连接到 Play Games 时,我会简单地检查成就是否在本地解锁,然后在 Play Games 上解锁。

if (isSignedIn()) {
            if (mOutbox.isOne() == AccomplishmentsOutbox.UNLOCKED) {
                Games.Achievements.unlock(mGoogleApiClient, getString(R.string.achievement_one));
                mOutbox.putOne(AccomplishmentsOutbox.PUSHED);
            }

祝一切顺利:)希望对某人有所帮助。

看来,没有足够的文档。嗯,在一些研发工作之后,我做了一些观察。可能对某人有用。

  1. 初始登录需要网络连接。

  2. 初始"sign-in"在本地创建成就副本。

  3. 只要应用程序离线(即没有网络连接,但已登录),应用程序就会在本地存储的副本上运行。

  4. 每当 mGoogleApiClient 再次通过网络连接到 google 服务器时,它会自动更新服务器,在本地解锁成就。