Facebook SDK for Android providing comprehensive integration with Facebook platform features including Login, Sharing, Messenger, App Links, Analytics, and Graph API
—
The Facebook Graph API module provides direct access to Facebook's Graph API for reading and writing Facebook data. It offers request building, batch operations, response handling, and comprehensive error management.
The GraphRequest class is the primary interface for making Graph API calls.
class GraphRequest private constructor() {
val accessToken: AccessToken?
val graphPath: String?
val httpMethod: HttpMethod
val parameters: Bundle?
val graphObject: JSONObject?
val tag: Any?
val version: String?
val skippedResultKeys: Set<String>?
val callback: Callback?
companion object {
// Me requests
fun newMeRequest(
accessToken: AccessToken?,
callback: GraphJSONObjectCallback?
): GraphRequest
fun newMyFriendsRequest(
accessToken: AccessToken?,
callback: GraphJSONArrayCallback?
): GraphRequest
// Generic requests
fun newGraphPathRequest(
accessToken: AccessToken?,
graphPath: String?,
callback: Callback?
): GraphRequest
// Post requests
fun newPostRequest(
accessToken: AccessToken?,
graphPath: String?,
graphObject: JSONObject?,
callback: Callback?
): GraphRequest
// Delete requests
fun newDeleteObjectRequest(
accessToken: AccessToken?,
objectId: String?,
callback: Callback?
): GraphRequest
// Places search
fun newPlacesSearchRequest(
accessToken: AccessToken?,
location: Location,
radiusInMeters: Int,
resultsLimit: Int,
searchText: String?,
callback: GraphJSONArrayCallback?
): GraphRequest
// Custom audience
fun newCustomAudienceThirdPartyIdRequest(
accessToken: AccessToken?,
context: Context,
callback: Callback?
): GraphRequest
}
// Execution
fun executeAsync(): GraphRequestAsyncTask
fun executeAndWait(): GraphResponse
// Configuration
fun setParameters(parameters: Bundle?)
fun setGraphObject(graphObject: JSONObject?)
fun setTag(tag: Any?)
fun setVersion(version: String?)
fun setSkippedResultKeys(skippedResultKeys: Collection<String>?)
fun setCallback(callback: Callback?)
// Callbacks
interface Callback {
fun onCompleted(response: GraphResponse)
}
interface GraphJSONObjectCallback {
fun onCompleted(jsonObject: JSONObject?, response: GraphResponse)
}
interface GraphJSONArrayCallback {
fun onCompleted(jsonArray: JSONArray?, response: GraphResponse)
}
interface OnProgressCallback {
fun onProgress(current: Long, max: Long)
}
}
enum class HttpMethod {
GET, POST, DELETE
}// Get current user information
val request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken()
) { jsonObject, response ->
if (response.error == null) {
val userId = jsonObject?.getString("id")
val name = jsonObject?.getString("name")
val email = jsonObject?.getString("email")
Log.d("GraphAPI", "User: $name ($userId), Email: $email")
} else {
Log.e("GraphAPI", "Error: ${response.error?.errorMessage}")
}
}
// Request specific fields
val parameters = Bundle()
parameters.putString("fields", "id,name,email,picture.type(large)")
request.parameters = parameters
// Execute the request
request.executeAsync()// Make a custom GET request
val request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/me/posts"
) { response ->
if (response.error == null) {
val jsonObject = response.jsonObject
val postsArray = jsonObject?.optJSONArray("data")
// Process posts
}
}
// Add parameters for pagination and fields
val parameters = Bundle()
parameters.putString("fields", "id,message,created_time,likes.summary(true)")
parameters.putInt("limit", 25)
request.parameters = parameters
request.executeAsync()
// Make a POST request
val postData = JSONObject()
postData.put("message", "Hello from my app!")
postData.put("link", "https://example.com")
val postRequest = GraphRequest.newPostRequest(
AccessToken.getCurrentAccessToken(),
"/me/feed",
postData
) { response ->
if (response.error == null) {
val postId = response.jsonObject?.getString("id")
Log.d("GraphAPI", "Post created with ID: $postId")
}
}
postRequest.executeAsync()class GraphResponse(
request: GraphRequest,
connection: HttpURLConnection?,
error: FacebookRequestError?
) {
val request: GraphRequest
val rawResponse: String?
val jsonObject: JSONObject?
val jsonArray: JSONArray?
val error: FacebookRequestError?
val connection: HttpURLConnection?
companion object {
fun createResponsesFromString(
responseString: String,
requests: List<GraphRequest>
): List<GraphResponse>
fun fromHttpConnection(
connection: HttpURLConnection,
requests: List<GraphRequest>
): List<GraphResponse>
}
}Execute multiple Graph API requests in a single HTTP call:
class GraphRequestBatch : AbstractList<GraphRequest> {
constructor()
constructor(requests: Collection<GraphRequest>)
constructor(vararg requests: GraphRequest)
val requests: List<GraphRequest>
val timeout: Int
val callbackHandler: Handler?
val batchApplicationId: String?
fun setTimeout(timeoutInMilliseconds: Int)
fun addCallback(callback: Callback)
fun removeCallback(callback: Callback)
// Execution
fun executeAsync(): GraphRequestAsyncTask
fun executeAndWait(): List<GraphResponse>
interface Callback {
fun onBatchCompleted(batch: GraphRequestBatch)
}
interface OnProgressCallback {
fun onBatchProgress(batch: GraphRequestBatch, current: Long, max: Long)
}
}// Create multiple requests
val meRequest = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { obj, response ->
// Handle user info
}
val friendsRequest = GraphRequest.newMyFriendsRequest(AccessToken.getCurrentAccessToken()) { array, response ->
// Handle friends list
}
val postsRequest = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/me/posts"
) { response ->
// Handle posts
}
// Create batch and execute
val batch = GraphRequestBatch(meRequest, friendsRequest, postsRequest)
batch.addCallback { batch ->
Log.d("GraphAPI", "Batch completed with ${batch.size} requests")
}
batch.executeAsync()class GraphRequestAsyncTask : AsyncTask<Void, Void, List<GraphResponse>> {
constructor(connection: HttpURLConnection, vararg requests: GraphRequest)
constructor(requests: Collection<GraphRequest>)
constructor(batch: GraphRequestBatch)
val requests: List<GraphRequest>
val exception: Exception?
override fun toString(): String
}class FacebookRequestError(
requestStatusCode: Int,
errorCode: Int,
errorType: String?,
errorMessage: String?
) {
val requestStatusCode: Int
val errorCode: Int
val errorType: String?
val errorMessage: String?
val errorUserMessage: String?
val errorUserTitle: String?
val requestResult: JSONObject?
val batchRequestResult: JSONObject?
val exception: FacebookException?
val category: Category
enum class Category {
LOGIN_RECOVERABLE, // User can fix by logging in again
OTHER, // Non-recoverable error
TRANSIENT // Temporary error, retry may work
}
companion object {
const val INVALID_ERROR_CODE = -1
const val INVALID_HTTP_STATUS_CODE = -1
}
}
class FacebookGraphResponseException(
response: GraphResponse,
message: String?
) : FacebookException(message) {
val graphResponse: GraphResponse
}val request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { jsonObject, response ->
val error = response.error
if (error != null) {
when (error.category) {
FacebookRequestError.Category.LOGIN_RECOVERABLE -> {
// Token expired or invalid, prompt user to login again
Log.w("GraphAPI", "Login required: ${error.errorMessage}")
AccessToken.setCurrentAccessToken(null)
redirectToLogin()
}
FacebookRequestError.Category.TRANSIENT -> {
// Temporary error, retry after delay
Log.w("GraphAPI", "Transient error: ${error.errorMessage}")
Handler().postDelayed({ request.executeAsync() }, 5000)
}
FacebookRequestError.Category.OTHER -> {
// Permanent error
Log.e("GraphAPI", "API error: ${error.errorMessage}")
showErrorToUser(error.errorUserMessage ?: error.errorMessage)
}
}
} else {
// Success - process the response
processUserData(jsonObject)
}
}Handle paginated Graph API responses:
fun loadUserPosts(after: String? = null) {
val request = GraphRequest.newGraphPathRequest(
AccessToken.getCurrentAccessToken(),
"/me/posts"
) { response ->
if (response.error == null) {
val jsonObject = response.jsonObject
val data = jsonObject?.optJSONArray("data")
// Process current page of posts
processPosts(data)
// Check for next page
val paging = jsonObject?.optJSONObject("paging")
val nextPageUrl = paging?.optString("next")
val cursors = paging?.optJSONObject("cursors")
val afterCursor = cursors?.optString("after")
if (!nextPageUrl.isNullOrEmpty()) {
// Load next page
loadUserPosts(afterCursor)
}
}
}
// Set parameters including pagination cursor
val parameters = Bundle()
parameters.putString("fields", "id,message,created_time")
parameters.putInt("limit", 25)
if (after != null) {
parameters.putString("after", after)
}
request.parameters = parameters
request.executeAsync()
}Upload files through the Graph API:
fun uploadPhoto(bitmap: Bitmap, message: String) {
val request = GraphRequest.newUploadPhotoRequest(
AccessToken.getCurrentAccessToken(),
"/me/photos",
bitmap,
message
) { response ->
if (response.error == null) {
val photoId = response.jsonObject?.getString("id")
Log.d("GraphAPI", "Photo uploaded with ID: $photoId")
} else {
Log.e("GraphAPI", "Upload failed: ${response.error?.errorMessage}")
}
}
request.executeAsync()
}
fun uploadVideo(videoUri: Uri, title: String) {
val request = GraphRequest.newUploadVideoRequest(
AccessToken.getCurrentAccessToken(),
"/me/videos",
videoUri,
title
) { response ->
if (response.error == null) {
val videoId = response.jsonObject?.getString("id")
Log.d("GraphAPI", "Video uploaded with ID: $videoId")
}
}
request.executeAsync()
}// Use specific API version
val request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken()) { obj, response ->
// Handle response
}
request.version = "v18.0"
request.executeAsync()
// Set default version for all requests
FacebookSdk.setGraphApiVersion("v18.0")Install with Tessl CLI
npx tessl i tessl/maven-com-facebook-android--facebook-android-sdk