Enhance: Update Google Play Games integration and versioning

- Incremented version code to 3 and version name to 0.2 in build.gradle.
- Added INTERNET and ACCESS_NETWORK_STATE permissions in AndroidManifest.xml.
- Refactored leaderboard display logic in HighScoresActivity and MainActivity to utilize a listener for intent success and failure.
- Introduced silent sign-in functionality for Google Play Games in MainActivity.
- Updated GooglePlayGamesManager to support the new listener interface for leaderboard intent handling.
- Added Google Play sign-in buttons in both portrait and landscape layouts for improved user interaction.
This commit is contained in:
cmclark00 2025-04-02 18:04:24 -04:00
parent 220caa39f7
commit 808dc79396
7 changed files with 143 additions and 26 deletions

View file

@ -11,8 +11,8 @@ android {
applicationId "com.pixelmintdrop" applicationId "com.pixelmintdrop"
minSdk 30 minSdk 30
targetSdk 35 targetSdk 35
versionCode 2 versionCode 3
versionName "0.1" versionName "0.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }

View file

@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> <manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Add permission to handle system gestures if needed on some devices --> <!-- Add permission to handle system gestures if needed on some devices -->
<application <application
@ -14,6 +16,9 @@
<meta-data <meta-data
android:name="com.google.android.gms.games.APP_ID" android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" /> android:value="@string/app_id" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true" android:exported="true"

View file

@ -7,6 +7,7 @@ import com.pixelmintdrop.databinding.HighScoresBinding
import com.pixelmintdrop.model.HighScoreAdapter import com.pixelmintdrop.model.HighScoreAdapter
import com.pixelmintdrop.model.HighScoreManager import com.pixelmintdrop.model.HighScoreManager
import com.pixelmintdrop.model.PlayerProgressionManager import com.pixelmintdrop.model.PlayerProgressionManager
import com.pixelmintdrop.model.GooglePlayGamesManager
import android.graphics.Color import android.graphics.Color
import android.util.Log import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
@ -17,6 +18,7 @@ import android.widget.Toast
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import android.content.Intent
class HighScoresActivity : AppCompatActivity() { class HighScoresActivity : AppCompatActivity() {
private lateinit var binding: HighScoresBinding private lateinit var binding: HighScoresBinding
@ -24,6 +26,10 @@ class HighScoresActivity : AppCompatActivity() {
private lateinit var highScoreAdapter: HighScoreAdapter private lateinit var highScoreAdapter: HighScoreAdapter
private lateinit var progressionManager: PlayerProgressionManager private lateinit var progressionManager: PlayerProgressionManager
private var currentTheme = PlayerProgressionManager.THEME_CLASSIC private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
companion object {
private const val RC_LEADERBOARD_UI_HS = 9005 // Unique request code for HighScoresActivity
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -136,8 +142,23 @@ class HighScoresActivity : AppCompatActivity() {
Toast.makeText(this, "Signing in to Google Play Games...", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Signing in to Google Play Games...", Toast.LENGTH_SHORT).show()
} }
// Show the leaderboard // Call the updated showLeaderboard with a listener
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this) highScoreManager.getGooglePlayGamesManager().showLeaderboard(this,
object : GooglePlayGamesManager.LeaderboardIntentListener {
override fun onLeaderboardIntentSuccess(intent: Intent) {
try {
startActivityForResult(intent, RC_LEADERBOARD_UI_HS)
} catch (e: Exception) {
Log.e("HighScoresActivity", "Failed to start leaderboard activity for result", e)
Toast.makeText(this@HighScoresActivity, "Could not display leaderboard.", Toast.LENGTH_SHORT).show()
}
}
override fun onLeaderboardIntentFailure(exception: Exception) {
Log.e("HighScoresActivity", "Failed to get leaderboard intent.", exception)
Toast.makeText(this@HighScoresActivity, "Could not display leaderboard.", Toast.LENGTH_SHORT).show()
}
})
} catch (e: Exception) { } catch (e: Exception) {
Log.e("HighScoresActivity", "Error showing leaderboard", e) Log.e("HighScoresActivity", "Error showing leaderboard", e)
Toast.makeText(this, "Could not open leaderboard", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Could not open leaderboard", Toast.LENGTH_SHORT).show()

View file

@ -59,6 +59,10 @@ import kotlin.random.Random
import com.google.android.gms.games.PlayGames import com.google.android.gms.games.PlayGames
import com.google.android.gms.games.PlayGamesSdk import com.google.android.gms.games.PlayGamesSdk
import com.google.android.gms.games.GamesSignInClient import com.google.android.gms.games.GamesSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignIn // Added for silent sign-in
import com.google.android.gms.auth.api.signin.GoogleSignInClient // Added for silent sign-in
import com.google.android.gms.auth.api.signin.GoogleSignInOptions // Added for silent sign-in
import com.pixelmintdrop.model.GooglePlayGamesManager // Added import for listener
class MainActivity : AppCompatActivity(), class MainActivity : AppCompatActivity(),
GamepadController.GamepadConnectionListener, GamepadController.GamepadConnectionListener,
@ -67,6 +71,7 @@ class MainActivity : AppCompatActivity(),
companion object { companion object {
private const val TAG = "MainActivity" private const val TAG = "MainActivity"
private const val RC_LEADERBOARD_UI = 9004 // Request code for leaderboard UI
} }
// ViewModel // ViewModel
@ -74,6 +79,7 @@ class MainActivity : AppCompatActivity(),
// Google Play Games Services // Google Play Games Services
private lateinit var gamesSignInClient: GamesSignInClient private lateinit var gamesSignInClient: GamesSignInClient
private lateinit var googleSignInClient: GoogleSignInClient // Added for silent sign-in
// UI components // UI components
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
@ -167,6 +173,9 @@ class MainActivity : AppCompatActivity(),
// Initialize Google Play Games Services // Initialize Google Play Games Services
PlayGamesSdk.initialize(this) PlayGamesSdk.initialize(this)
gamesSignInClient = PlayGames.getGamesSignInClient(this) gamesSignInClient = PlayGames.getGamesSignInClient(this)
// Initialize GoogleSignInClient for silent sign-in
val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build()
googleSignInClient = GoogleSignIn.getClient(this, signInOptions)
// Request sign-in silently // Request sign-in silently
signInToPlayGames() signInToPlayGames()
@ -2256,23 +2265,51 @@ class MainActivity : AppCompatActivity(),
// Method to show Google Play Games leaderboard // Method to show Google Play Games leaderboard
private fun showLeaderboard() { private fun showLeaderboard() {
gamesSignInClient.isAuthenticated.addOnCompleteListener { task -> // New logic: Try silent sign-in first, then interactive if needed.
val isAuthenticated = task.isSuccessful && task.result.isAuthenticated Log.d(TAG, "Attempting silent sign-in before showing leaderboard...")
// Use googleSignInClient for silentSignIn
if (isAuthenticated) { googleSignInClient.silentSignIn().addOnCompleteListener { silentSignInTask ->
// Show leaderboard if (silentSignInTask.isSuccessful) {
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this) // Silent sign-in successful OR user already signed in.
Log.d(TAG, "Silent sign-in successful/already signed in. Getting leaderboard intent.")
getAndShowLeaderboardIntent()
} else { } else {
// Sign in first // Silent sign-in failed. Need explicit sign-in.
gamesSignInClient.signIn().addOnCompleteListener { signInTask -> Log.w(TAG, "Silent sign-in failed. Attempting interactive sign-in.", silentSignInTask.exception)
if (signInTask.isSuccessful) { // Use gamesSignInClient for interactive signIn
// Now try to show leaderboard again gamesSignInClient.signIn().addOnCompleteListener { interactiveSignInTask ->
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this) if (interactiveSignInTask.isSuccessful) {
// Interactive sign-in successful
Log.d(TAG, "Interactive sign-in successful. Getting leaderboard intent.")
getAndShowLeaderboardIntent()
} else { } else {
Toast.makeText(this, "Sign-in required to view leaderboard", Toast.LENGTH_SHORT).show() // Interactive sign-in failed
Log.e(TAG, "Interactive sign-in failed.", interactiveSignInTask.exception)
Toast.makeText(this, "Sign-in failed. Please try again.", Toast.LENGTH_SHORT).show()
} }
} }
} }
} }
} }
// Helper function to get the intent from GooglePlayGamesManager and show it
private fun getAndShowLeaderboardIntent() {
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this,
object : GooglePlayGamesManager.LeaderboardIntentListener {
override fun onLeaderboardIntentSuccess(intent: Intent) {
Log.d(TAG, "Received leaderboard intent, starting activity for result.")
try {
startActivityForResult(intent, RC_LEADERBOARD_UI)
} catch (e: Exception) {
Log.e(TAG, "Failed to start leaderboard activity for result", e)
Toast.makeText(this@MainActivity, "Could not display leaderboard.", Toast.LENGTH_SHORT).show()
}
}
override fun onLeaderboardIntentFailure(exception: Exception) {
Log.e(TAG, "Failed to get leaderboard intent.", exception)
Toast.makeText(this@MainActivity, "Could not display leaderboard.", Toast.LENGTH_SHORT).show()
}
})
}
} }

View file

@ -16,6 +16,12 @@ import com.google.android.gms.tasks.Task
class GooglePlayGamesManager(private val context: Context) { class GooglePlayGamesManager(private val context: Context) {
private val TAG = "GooglePlayGamesManager" private val TAG = "GooglePlayGamesManager"
// Define a listener interface for the leaderboard intent
interface LeaderboardIntentListener {
fun onLeaderboardIntentSuccess(intent: Intent)
fun onLeaderboardIntentFailure(exception: Exception)
}
// Leaderboard ID // Leaderboard ID
companion object { companion object {
const val LEADERBOARD_ID = "CgkImJW2mKsSEAIQAQ" const val LEADERBOARD_ID = "CgkImJW2mKsSEAIQAQ"
@ -71,26 +77,33 @@ class GooglePlayGamesManager(private val context: Context) {
} }
} }
// Show the leaderboard // Show the leaderboard - Now uses a listener to return the Intent
fun showLeaderboard(activity: Activity) { fun showLeaderboard(activity: Activity, listener: LeaderboardIntentListener) {
val account = GoogleSignIn.getLastSignedInAccount(context) Log.d(TAG, "showLeaderboard called in GooglePlayGamesManager")
if (account == null) {
Log.w(TAG, "Not signed in, cannot show leaderboard")
return
}
Log.d(TAG, "Attempting to get LeaderboardsClient (assuming user is signed in)")
try { try {
val leaderboardsClient = PlayGames.getLeaderboardsClient(activity) val leaderboardsClient = PlayGames.getLeaderboardsClient(activity)
Log.d(TAG, "LeaderboardsClient obtained, attempting to get leaderboard intent for ID: $LEADERBOARD_ID")
leaderboardsClient leaderboardsClient
.getLeaderboardIntent(LEADERBOARD_ID) .getLeaderboardIntent(LEADERBOARD_ID)
.addOnSuccessListener { intent -> .addOnSuccessListener { intent ->
activity.startActivity(intent) Log.d(TAG, "Successfully obtained leaderboard intent. Calling listener.")
// try { // Removed - Activity start is now handled by MainActivity
// activity.startActivity(intent)
// Log.d(TAG, "Leaderboard activity started successfully.")
// } catch (e: Exception) {
// Log.e(TAG, "Error starting leaderboard activity", e)
// }
listener.onLeaderboardIntentSuccess(intent)
} }
.addOnFailureListener { e -> .addOnFailureListener { e ->
Log.e(TAG, "Error showing leaderboard", e) Log.e(TAG, "Error getting leaderboard intent", e)
listener.onLeaderboardIntentFailure(e)
} }
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Error showing leaderboard", e) Log.e(TAG, "Error obtaining LeaderboardsClient or getting leaderboard intent", e) // Updated log message
listener.onLeaderboardIntentFailure(e)
} }
} }
} }

View file

@ -438,6 +438,34 @@
android:singleLine="true" android:singleLine="true"
android:focusable="true" android:focusable="true"
android:focusableInTouchMode="true" /> android:focusableInTouchMode="true" />
<!-- Leaderboard Button -->
<Button
android:id="@+id/leaderboardButton"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@color/transparent"
android:text="Global Leaderboard"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<!-- Google Play Sign In Button -->
<Button
android:id="@+id/googlePlaySignInButton"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@color/transparent"
android:text="Sign in to Google Play"
android:textColor="@color/white"
android:textSize="20sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
</LinearLayout> </LinearLayout>

View file

@ -419,6 +419,19 @@
android:textStyle="bold" android:textStyle="bold"
android:fontFamily="sans-serif" android:fontFamily="sans-serif"
android:textAllCaps="false" /> android:textAllCaps="false" />
<Button
android:id="@+id/googlePlaySignInButton"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@color/transparent"
android:text="Sign in to Google Play"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold"
android:fontFamily="sans-serif"
android:textAllCaps="false" />
<Button <Button
android:id="@+id/statsButton" android:id="@+id/statsButton"