Facebook SDK for Android providing comprehensive integration with Facebook platform features including Login, Sharing, Messenger, App Links, Analytics, and Graph API
—
The Facebook Gaming Services module provides gaming-specific features including tournaments, gaming contexts, friend finder, custom updates, and social gaming capabilities. This module is designed specifically for games that want to integrate with Facebook's gaming platform.
Manage gaming contexts for multiplayer and social gaming experiences:
class GamingContext private constructor() {
val identifier: String?
companion object {
// Current context
fun getCurrentGamingContext(): GamingContext?
// Context switching
fun switchGamingContext(
context: Context,
gamingContextId: String,
callback: FacebookCallback<GamingContext>
)
fun createGamingContext(
activity: Activity,
playerID: String,
callback: FacebookCallback<GamingContext>
)
}
}class MultiplayerGameActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Check current gaming context
val currentContext = GamingContext.getCurrentGamingContext()
if (currentContext != null) {
Log.d("Gaming", "Current context: ${currentContext.identifier}")
loadMultiplayerGame(currentContext.identifier)
} else {
// Create new gaming context or switch to existing one
createOrSwitchContext()
}
}
private fun createOrSwitchContext() {
// Option 1: Create new context with a friend
val friendPlayerId = "friend_user_id_123"
GamingContext.createGamingContext(this, friendPlayerId) { result ->
when {
result.error != null -> {
Log.e("Gaming", "Failed to create context: ${result.error?.message}")
}
result.cancelled -> {
Log.d("Gaming", "Context creation cancelled")
}
else -> {
val context = result.result
Log.d("Gaming", "Created context: ${context?.identifier}")
startMultiplayerGame(context)
}
}
}
// Option 2: Switch to existing context
val existingContextId = "existing_context_123"
GamingContext.switchGamingContext(this, existingContextId) { result ->
when {
result.error != null -> {
Log.e("Gaming", "Failed to switch context: ${result.error?.message}")
}
result.cancelled -> {
Log.d("Gaming", "Context switch cancelled")
}
else -> {
val context = result.result
Log.d("Gaming", "Switched to context: ${context?.identifier}")
joinExistingGame(context)
}
}
}
}
}Allow players to select or create gaming contexts:
class ContextChooseDialog : FacebookDialogBase<ContextChooseContent, ContextChooseDialog.Result> {
constructor(activity: Activity)
constructor(fragment: Fragment)
companion object {
fun canShow(): Boolean
}
fun show(content: ContextChooseContent)
data class Result(val contextId: String)
}
class ContextChooseContent private constructor() {
val filters: List<Filter>?
val maxSize: Int?
val minSize: Int?
enum class Filter {
NEW_CONTEXT_ONLY, // Only allow creating new contexts
INCLUDE_EXISTING // Include existing contexts
}
class Builder {
fun setFilters(filters: List<Filter>): Builder
fun setMaxSize(maxSize: Int): Builder
fun setMinSize(minSize: Int): Builder
fun build(): ContextChooseContent
}
}Create new gaming contexts:
class ContextCreateDialog : FacebookDialogBase<ContextCreateContent, ContextCreateDialog.Result> {
constructor(activity: Activity)
constructor(fragment: Fragment)
companion object {
fun canShow(): Boolean
}
fun show(content: ContextCreateContent)
data class Result(val contextId: String)
}
class ContextCreateContent private constructor() {
val playerID: String
val suggestedPlayers: List<String>?
class Builder(playerID: String) {
fun setSuggestedPlayers(suggestedPlayers: List<String>): Builder
fun build(): ContextCreateContent
}
}class GamingDialogManager {
private lateinit var callbackManager: CallbackManager
fun showContextChooser(activity: Activity) {
val content = ContextChooseContent.Builder()
.setFilters(listOf(ContextChooseContent.Filter.INCLUDE_EXISTING))
.setMaxSize(8) // Maximum 8 players
.setMinSize(2) // Minimum 2 players
.build()
val dialog = ContextChooseDialog(activity)
dialog.registerCallback(callbackManager, object : FacebookCallback<ContextChooseDialog.Result> {
override fun onSuccess(result: ContextChooseDialog.Result) {
Log.d("Gaming", "Context chosen: ${result.contextId}")
switchToContext(result.contextId)
}
override fun onCancel() {
Log.d("Gaming", "Context selection cancelled")
}
override fun onError(error: FacebookException) {
Log.e("Gaming", "Context selection error: ${error.message}")
}
})
if (ContextChooseDialog.canShow()) {
dialog.show(content)
}
}
fun showContextCreator(activity: Activity, playerID: String, friends: List<String>) {
val content = ContextCreateContent.Builder(playerID)
.setSuggestedPlayers(friends)
.build()
val dialog = ContextCreateDialog(activity)
dialog.registerCallback(callbackManager, object : FacebookCallback<ContextCreateDialog.Result> {
override fun onSuccess(result: ContextCreateDialog.Result) {
Log.d("Gaming", "Context created: ${result.contextId}")
startNewGame(result.contextId)
}
override fun onCancel() {
Log.d("Gaming", "Context creation cancelled")
}
override fun onError(error: FacebookException) {
Log.e("Gaming", "Context creation error: ${error.message}")
}
})
if (ContextCreateDialog.canShow()) {
dialog.show(content)
}
}
}Help players discover and invite friends:
class FriendFinderDialog : FacebookDialogBase<Void, FriendFinderDialog.Result> {
constructor(activity: Activity)
constructor(fragment: Fragment)
companion object {
fun canShow(): Boolean
}
fun show()
data class Result(
val requestId: String,
val to: List<String>
)
}fun showFriendFinder(activity: Activity) {
val dialog = FriendFinderDialog(activity)
dialog.registerCallback(callbackManager, object : FacebookCallback<FriendFinderDialog.Result> {
override fun onSuccess(result: FriendFinderDialog.Result) {
Log.d("Gaming", "Friend finder success")
Log.d("Gaming", "Request ID: ${result.requestId}")
Log.d("Gaming", "Invited friends: ${result.to}")
// Track successful friend invitations
trackFriendInvitations(result.to.size)
}
override fun onCancel() {
Log.d("Gaming", "Friend finder cancelled")
}
override fun onError(error: FacebookException) {
Log.e("Gaming", "Friend finder error: ${error.message}")
}
})
if (FriendFinderDialog.canShow()) {
dialog.show()
}
}Send custom updates to gaming contexts:
class CustomUpdate private constructor() {
companion object {
fun newCustomUpdateBuilder(): Builder
}
class Builder {
fun setText(text: String): Builder
fun setImage(image: Bitmap): Builder
fun setCTA(cta: String): Builder
fun setData(data: JSONObject): Builder
fun setStrategy(strategy: Strategy): Builder
fun setNotification(notification: String): Builder
fun build(): CustomUpdate
}
enum class Strategy {
IMMEDIATE, // Send immediately
LAST, // Replace last update
REPLACE_ALL // Replace all updates
}
}
class CustomUpdateContent private constructor() {
val customUpdate: CustomUpdate
val contextID: String?
class Builder(customUpdate: CustomUpdate) {
fun setContextID(contextID: String): Builder
fun build(): CustomUpdateContent
}
}class GameUpdateManager {
fun sendGameUpdate(
activity: Activity,
message: String,
screenshot: Bitmap,
gameData: JSONObject
) {
val customUpdate = CustomUpdate.newCustomUpdateBuilder()
.setText(message)
.setImage(screenshot)
.setCTA("Join Game")
.setData(gameData)
.setStrategy(CustomUpdate.Strategy.LAST)
.setNotification("Your turn!")
.build()
val contextId = GamingContext.getCurrentGamingContext()?.identifier
if (contextId != null) {
val content = CustomUpdateContent.Builder(customUpdate)
.setContextID(contextId)
.build()
sendCustomUpdate(activity, content)
}
}
fun sendScoreUpdate(score: Int, level: Int, screenshot: Bitmap) {
val gameData = JSONObject().apply {
put("score", score)
put("level", level)
put("timestamp", System.currentTimeMillis())
put("game_version", BuildConfig.VERSION_NAME)
}
val message = "I just scored $score points on level $level! Can you beat it?"
val customUpdate = CustomUpdate.newCustomUpdateBuilder()
.setText(message)
.setImage(screenshot)
.setCTA("Play Now")
.setData(gameData)
.setStrategy(CustomUpdate.Strategy.IMMEDIATE)
.build()
val contextId = GamingContext.getCurrentGamingContext()?.identifier
if (contextId != null) {
val content = CustomUpdateContent.Builder(customUpdate)
.setContextID(contextId)
.build()
sendCustomUpdate(activity, content)
}
}
fun sendTurnNotification(playerName: String, gameState: JSONObject) {
val customUpdate = CustomUpdate.newCustomUpdateBuilder()
.setText("$playerName made their move!")
.setCTA("Your Turn")
.setData(gameState)
.setStrategy(CustomUpdate.Strategy.REPLACE_ALL)
.setNotification("It's your turn to play!")
.build()
val contextId = GamingContext.getCurrentGamingContext()?.identifier
if (contextId != null) {
val content = CustomUpdateContent.Builder(customUpdate)
.setContextID(contextId)
.build()
sendCustomUpdate(activity, content)
}
}
}Retrieve tournament information:
class TournamentFetcher {
companion object {
fun fetchTournaments(callback: FacebookCallback<List<Tournament>>)
fun fetchTournament(tournamentId: String, callback: FacebookCallback<Tournament>)
}
}
data class Tournament(
val identifier: String,
val endTime: String,
val title: String?,
val payload: JSONObject?
)Share tournament results and invite players:
class TournamentShareDialog : FacebookDialogBase<TournamentConfig, TournamentShareDialog.Result> {
constructor(activity: Activity)
constructor(fragment: Fragment)
companion object {
fun canShow(): Boolean
}
fun show(config: TournamentConfig)
data class Result(val tournamentId: String?)
}
class TournamentConfig private constructor() {
val title: String?
val endTime: String?
val scoreType: ScoreType?
val sortOrder: SortOrder?
val image: Bitmap?
val payload: JSONObject?
enum class ScoreType {
NUMERIC, // Numeric scores
TIME // Time-based scores
}
enum class SortOrder {
HIGHER_IS_BETTER, // Higher scores are better
LOWER_IS_BETTER // Lower scores are better (e.g., time)
}
class Builder {
fun setTitle(title: String): Builder
fun setEndTime(endTime: String): Builder
fun setScoreType(scoreType: ScoreType): Builder
fun setSortOrder(sortOrder: SortOrder): Builder
fun setImage(image: Bitmap): Builder
fun setPayload(payload: JSONObject): Builder
fun build(): TournamentConfig
}
}class TournamentManager {
fun createTournament(
activity: Activity,
title: String,
duration: Long,
screenshot: Bitmap
) {
val endTime = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US).apply {
timeZone = TimeZone.getTimeZone("UTC")
}.format(Date(System.currentTimeMillis() + duration))
val payload = JSONObject().apply {
put("game_mode", "tournament")
put("created_by", AccessToken.getCurrentAccessToken()?.userId)
put("created_at", System.currentTimeMillis())
}
val config = TournamentConfig.Builder()
.setTitle(title)
.setEndTime(endTime)
.setScoreType(TournamentConfig.ScoreType.NUMERIC)
.setSortOrder(TournamentConfig.SortOrder.HIGHER_IS_BETTER)
.setImage(screenshot)
.setPayload(payload)
.build()
val dialog = TournamentShareDialog(activity)
dialog.registerCallback(callbackManager, object : FacebookCallback<TournamentShareDialog.Result> {
override fun onSuccess(result: TournamentShareDialog.Result) {
val tournamentId = result.tournamentId
Log.d("Tournament", "Tournament created: $tournamentId")
startTournamentGame(tournamentId)
}
override fun onCancel() {
Log.d("Tournament", "Tournament creation cancelled")
}
override fun onError(error: FacebookException) {
Log.e("Tournament", "Tournament creation error: ${error.message}")
}
})
if (TournamentShareDialog.canShow()) {
dialog.show(config)
}
}
fun fetchActiveTournaments() {
TournamentFetcher.fetchTournaments(object : FacebookCallback<List<Tournament>> {
override fun onSuccess(result: List<Tournament>) {
Log.d("Tournament", "Found ${result.size} tournaments")
result.forEach { tournament ->
Log.d("Tournament", "Tournament: ${tournament.title} (${tournament.identifier})")
Log.d("Tournament", "Ends: ${tournament.endTime}")
}
displayTournaments(result)
}
override fun onCancel() {
Log.d("Tournament", "Tournament fetch cancelled")
}
override fun onError(error: FacebookException) {
Log.e("Tournament", "Tournament fetch error: ${error.message}")
}
})
}
fun submitTournamentScore(tournamentId: String, score: Int) {
// Tournament scores are typically submitted through Game Events
val logger = AppEventsLogger.newLogger(context)
val parameters = Bundle().apply {
putString("tournament_id", tournamentId)
putInt("score", score)
putLong("timestamp", System.currentTimeMillis())
}
logger.logEvent("tournament_score_submitted", score.toDouble(), parameters)
}
}Integration with Facebook Gaming Groups:
class GamingGroupIntegration {
companion object {
fun openGroupCreationDialog(
activity: Activity,
name: String,
description: String,
privacy: GroupPrivacy
)
fun openGameGroupTab(activity: Activity)
fun performAppToUserFriendFinderDialog(
activity: Activity,
callback: FacebookCallback<FriendFinderDialog.Result>
)
}
enum class GroupPrivacy {
PRIVATE,
PUBLIC
}
}Track gaming-specific events and metrics:
class GamingAnalytics {
private val logger = AppEventsLogger.newLogger(context)
fun trackGameStart(gameMode: String, level: Int) {
val parameters = Bundle().apply {
putString("game_mode", gameMode)
putInt("level", level)
putLong("session_start", System.currentTimeMillis())
}
logger.logEvent("game_started", parameters)
}
fun trackGameEnd(gameMode: String, score: Int, duration: Long) {
val parameters = Bundle().apply {
putString("game_mode", gameMode)
putInt("final_score", score)
putLong("game_duration", duration)
putLong("session_end", System.currentTimeMillis())
}
logger.logEvent("game_ended", score.toDouble(), parameters)
}
fun trackMultiplayerAction(action: String, contextId: String?) {
val parameters = Bundle().apply {
putString("multiplayer_action", action)
contextId?.let { putString("context_id", it) }
putLong("action_timestamp", System.currentTimeMillis())
}
logger.logEvent("multiplayer_action", parameters)
}
fun trackTournamentParticipation(tournamentId: String, action: String) {
val parameters = Bundle().apply {
putString("tournament_id", tournamentId)
putString("tournament_action", action) // "joined", "score_submitted", "completed"
putLong("action_timestamp", System.currentTimeMillis())
}
logger.logEvent("tournament_participation", parameters)
}
fun trackSocialFeatureUsage(feature: String, success: Boolean) {
val parameters = Bundle().apply {
putString("social_feature", feature) // "friend_invite", "context_switch", "custom_update"
putBoolean("success", success)
putLong("usage_timestamp", System.currentTimeMillis())
}
logger.logEvent("social_feature_used", parameters)
}
}Install with Tessl CLI
npx tessl i tessl/maven-com-facebook-android--facebook-android-sdk