我正在为Godot Engine开发一个模块,它叫做godot-android。您可以找到this module here。该模块通过SnapshotClient使用Google Drive API将游戏保存在Google Drive中。
由于我在今年早些时候发布的一款Android游戏中使用了该模块,因此我收到了一封关于Google Drive Android API弃用的电子邮件,内容是我的应用程序使用了Google Drive不推荐使用的API。
因此,我已经开始重新阅读Google Play Games Services documentation for android,但是他们没有更新文档。然后,花了几个小时在Stack-overflow / github migration guide上查找如何迁移SnapshotClient,我才碰壁。
我的第一步是将模块的所有依赖项升级到最新版本,进行编译,看看有什么问题:
com.google.firebase:firebase-core:16.0.6
com.google.firebase:firebase-auth:16.1.0
com.google.firebase:firebase-invites:16.0.6
com.google.firebase:firebase-messaging:17.3.4
com.google.firebase:firebase-appindexing:17.1.0
com.google.android.gms:play-services-auth:16.0.1
com.google.android.gms:play-services-games:16.0.0
com.google.android.gms:play-services-drive:16.0.0
com.google.apis:google-api-services-drive:v3-rev136-1.25.0
我很高兴看到一切正常。第2步,更改用于访问Google Drive API的代码:
public GoogleAuthentication(Activity p_activity) {
activity = p_activity;
String webclientId = activity.getString(R.string.default_web_client_id);
GoogleSignInOptions options = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestIdToken(webclientId)
// Since we are using SavedGames, we need to add the SCOPE_APPFOLDER to access Google Drive.
.requestScopes(new Scope(DriveScopes.DRIVE))
.requestScopes(new Scope(DriveScopes.DRIVE_FILE))
.requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
.build();
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addApi(Games.API)
.addScope(Games.SCOPE_GAMES)
.addApi(Auth.GOOGLE_SIGN_IN_API, options)
.setGravityForPopups(Gravity.TOP | Gravity.CENTER_HORIZONTAL)
.setViewForPopups(activity.getWindow().getDecorView().findViewById(android.R.id.content))
.build();
mAuth = FirebaseAuth.getInstance();
}
所以,游戏开始了,我弹出登录窗口询问作用域(正确的作用域),单击授权,然后我无权访问我的保存游戏。亚行logcat:
E/Parcel ( 820): Class not found when unmarshalling: com.google.android.gms.common.api.Scope
E/Parcel ( 820): java.lang.ClassNotFoundException: com.google.android.gms.common.api.Scope
E/Parcel ( 820): Class not found when unmarshalling: com.google.android.gms.auth.firstparty.shared.ScopeData
E/Parcel ( 820): java.lang.ClassNotFoundException: com.google.android.gms.auth.firstparty.shared.ScopeData
E/Parcel ( 820): Class not found when unmarshalling: com.google.android.gms.auth.api.signin.internal.SignInConfiguration
E/Parcel ( 820): java.lang.ClassNotFoundException: com.google.android.gms.auth.api.signin.internal.SignInConfiguration
E/Parcel ( 820): at java.lang.Class.classForName(Native Method)
E/Parcel ( 820): at java.lang.Class.forName(Class.java:251)
E/Parcel ( 820): at java.lang.Class.forName(Class.java:216)
E/Parcel ( 820): at android.os.Parcel.readParcelableCreator(Parcel.java:2140)
E/Parcel ( 820): at android.os.Parcel.readParcelable(Parcel.java:2104)
E/Parcel ( 820): at android.os.Parcel.readValue(Parcel.java:2020)
E/Parcel ( 820): at android.os.Parcel.readArrayMapInternal(Parcel.java:2321)
E/Parcel ( 820): at android.os.Bundle.unparcel(Bundle.java:249)
E/Parcel ( 820): at android.os.Bundle.getString(Bundle.java:1118)
E/Parcel ( 820): at android.content.Intent.getStringExtra(Intent.java:5261)
E/Parcel ( 820): at com.android.server.am.ActivityStackSupervisor.startActivityLocked(ActivityStackSupervisor.java:1591)
E/Parcel ( 820): at com.android.server.am.ActivityStackSupervisor.startActivityMayWait(ActivityStackSupervisor.java:1169)
E/Parcel ( 820): at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:4359)
E/Parcel ( 820): at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:4241)
E/Parcel ( 820): at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:164)
E/Parcel ( 820): at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2878)
E/Parcel ( 820): at android.os.Binder.execTransact(Binder.java:404)
E/Parcel ( 820): at dalvik.system.NativeStart.run(Native Method)
E/Parcel ( 820): Caused by: java.lang.NoClassDefFoundError: com/google/android/gms/auth/api/signin/internal/SignInConfiguration
E/Parcel ( 820): ... 18 more
E/Parcel ( 820): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.auth.api.signin.internal.SignInConfiguration" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
答案 0 :(得分:0)
发现了根本问题,范围不正确:
public GoogleAuthentication(Activity p_activity) {
activity = p_activity;
String webclientId = activity.getString(R.string.default_web_client_id);
GoogleSignInOptions options = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestIdToken(webclientId)
// Since we are using SavedGames, we need to add the SCOPE_APPFOLDER to access Google Drive.
.requestScopes(new Scope(DriveScopes.DRIVE_FILE))
.requestScopes(new Scope(DriveScopes.DRIVE_APPDATA))
.build();
mGoogleApiClient = new GoogleApiClient.Builder(activity)
.addApi(Games.API)
.addScope(Games.SCOPE_GAMES)
.addApi(Auth.GOOGLE_SIGN_IN_API, options)
.setGravityForPopups(Gravity.TOP | Gravity.CENTER_HORIZONTAL)
.setViewForPopups(activity.getWindow().getDecorView().findViewById(android.R.id.content))
.build();
mAuth = FirebaseAuth.getInstance();
}
这段代码很好用,我更新了github模块,可以看看at the commit。