unified_game_services_google_play_android 0.1.0
unified_game_services_google_play_android: ^0.1.0 copied to clipboard
Native Google Play Games provider via the Play Games v2 Java SDK over package:jni (pure Dart, no Flutter). Android only; fires native achievement/leaderboard UI.
unified_game_services_google_play_android #
Native Google Play Games provider for
unified_game_services,
backed by the Play Games v2 Java SDK reached over package:jni — pure Dart,
no Flutter. Android only.
Most apps should use unified_game_services_google_play
(auto-selects this on Android, REST elsewhere) rather than depending on this
package directly.
Why this exists #
The REST provider (unified_game_services_google_play_rest)
talks to Google's cloud and so cannot fire the native Play Services
achievement/leaderboard toasts on Android. This provider routes writes through
the on-device Play Games client, so unlocks and score submissions show the
native overlay. Authentication is handled by Play Services — there is no OAuth
token to manage.
package:jni/jnigen reach the Java SDK via JNI (the same approach
objective_c uses for GameKit), so this stays within the repo's no-Flutter
constraint. games_services is banned because it uses Flutter platform
channels — JNI does not.
Host requirements #
This package is pure Dart, but the SDK needs the host (the engine/app embedding Dart on Android) to supply the Android runtime — the same "host supplies the runtime" shape as Steam (needs the Steam client) and Game Center (needs a signed bundle + run loop):
- A running ART VM with
package:jniinitialized against it (host hands theJavaVM*/JNIEnvto JNI on startup). - An
activityResolver(JObject Function()) passed toregisterWith/ the constructor — invoked fresh before each native call so a volatile activity is never cached (e.g.() => ANativeActivity.clazzfor a stable engine activity). - The APK bundles
com.google.android.gms:play-services-games-v2and declares the Play Games app id<meta-data>in its manifest.
Status #
- Implemented: the native-UX writes —
unlockAchievement,incrementAchievement,revealAchievement,submitScore, and the provider-specificsetAchievementStepsAtLeast.signIn()triggers the native sign-in flow. - Pending: operations that read a
Task<T>result (confirming sign-in state, current player, listing achievements / leaderboard scores). jnigen 0.16.0 mis-generatescom.google.android.gms.tasks.Task/Tasks, so those are excluded from the bindings andTask-returning methods come back as opaqueJObject. Wiring reads needs a jnigen that fixes generics (or a small hand-written JNITasks.awaithelper). Meanwhile the unified facade can serve reads from the REST provider. - Runtime-verified on a Flutter Android host (see the family's
..._flutterexample/):signIn()fires the native Play Games sign-in overlay, proving the JNI path reaches the live SDK (VM/Activity wiring + bindings work). Write toasts and theTask-backed read path still need a configured Play Console game + tester account to fully exercise.
Bindings #
lib/src/playgames_bindings.dart is generated and committed. Regenerate with:
ANDROID_SDK_ROOT=/path/to/sdk tool/regenerate_bindings.sh [PLAY_GAMES_VERSION]
Needs the Android SDK (for android.jar), a JDK ≤ 21 (the ASM summarizer), and
network access to Google's Maven. The script resolves the Play Games aar +
transitive deps, extracts each classes.jar, and runs jnigen against that
classpath. Keep the runtime jni dependency aligned with the jnigen version
(jnigen 0.16.0 → jni 1.0.0).
License #
MIT — see LICENSE. Independent, unofficial; not affiliated with any
platform vendor. See the repository NOTICE.md.
