Ramp Me Up, Scotty!

EN | DE

Building a GPT Client for Android with Jetpack Compose in Kotlin

2023-03-07

Adding AI-Generated Text to Your Android App with Jetpack Compose and GPT

This tutorial shows how to build a GPT client for Android using Jetpack Compose in Kotlin. It covers sending a request to the OpenAI GPT API and decoding the JSON response to display the generated text.

Note: this tutorial focuses on the logic for sending and receiving requests to /from the OpenAI GPT API; it does not cover all UI details.

For the full code, including the UI implementation, see my GitHub repo with working iOS and Android samples.

What is GPT?

GPT (Generative Pre-trained Transformer) is a machine learning model that generates natural language text. It is pre-trained on large amounts of text and can be fine-tuned for specific tasks, such as producing text in response to a prompt.

What will we build?

We will build an app that:

The sendRequest function handles communication with the OpenAI GPT API. It encodes the user’s question as a JSON payload and sends a POST request. If the API responds with status code 200, the function extracts the generated text from the JSON response and displays it in a Text view. If the API responds with an error, the function displays an error message.

Here is an animated screenshot of the final app:

2023-03-07 gpt.gif

Sending a Request to the GPT API

Below is the code needed to send a request to the GPT API. A step-by-step explanation follows.

data class GptRequest(
  val prompt: String,
  val max_tokens: Int,
  val model: String
)

data class GptResponse(
  val choices: List<Choice>
)

data class Choice(
  val text: String
)

interface GptApi {
  @Headers(
    "Content-Type: application/json",
    "Authorization: Bearer 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"
  )
  @POST("/v1/completions")
  fun getCompletion(
    @Body requestBody: GptRequest
  ): Call<GptResponse>
}

class ContentViewModel: ViewModel() {

  var answer by mutableStateOf("")
    private set

  var isLoading by mutableStateOf(false)
    private set

  val retrofit = Retrofit.Builder()
   .baseUrl("https://api.openai.com")
   .addConverterFactory(GsonConverterFactory.create())
   .build()

  val api = retrofit.create(GptApi::class.java)

  fun sendRequest(question: String) {
    val request = GptRequest(
      prompt = question,
      max_tokens = 100,
      model = "text-davinci-003"
    )

    viewModelScope.launch(Dispatchers.IO) {
      isLoading = true
      val call = api.getCompletion(request)
      val response = call.execute()
      isLoading = false

      if (response.isSuccessful) {
        val choice = response.body()?.choices?.get(0)
        viewModelScope.launch(Dispatchers.Main) {
          choice?.text?.let {
            answer = it
          }
        }
      } else {
        viewModelScope.launch(Dispatchers.Main) {
          answer = "Error: ${response.code()} - ${response.message()}"
        }
      }
    }
  }
}

The source code above enables the app to communicate with the OpenAI GPT API. Below is a concise explanation of the main parts:

Note: The Authorization header in the code above contains an API key specific to the developer (me). Replace it with your own API key—using the provided key will result in an error because it was invalidated before this tutorial’s release.

To obtain an OpenAI API key, create an account at openai.com, go to the API section, and follow the instructions to generate a key. Keep your API key secure and do not share it.

Conclusion

In this tutorial we built an Android app that accepts user input, sends it to the OpenAI GPT API, and displays the generated text.

I hope you found this tutorial informative and that it inspired you to create your own project using the GPT API. If you have questions or feedback, feel free to leave a comment.

The full code is available in my repo with working samples for iOS and Android: https://github.com/twissmueller/mobile-snippets

Thank you for reading!