Pour accéder aux modèles Gemini Pro et Flash, nous recommandons aux développeurs Android d'utiliser l'API Gemini Developer avec Firebase AI Logic. Il vous permet de vous lancer sans avoir besoin d'une carte de crédit et propose un niveau sans frais généreux. Une fois que vous avez validé votre intégration auprès d'une petite base d'utilisateurs, vous pouvez passer au forfait payant pour évoluer.
Premiers pas
Avant d'interagir avec l'API Gemini directement depuis votre application, vous devez effectuer quelques étapes. Par exemple, vous devez vous familiariser avec les requêtes, et configurer Firebase et votre application pour utiliser le SDK.
Tester des requêtes
Faire des tests avec des requêtes peut vous aider à trouver la formulation, le contenu et le format les plus adaptés à votre application Android. Google AI Studio est un IDE que vous pouvez utiliser pour prototyper et concevoir des requêtes pour les cas d'utilisation de votre application.
Créer la requête idéale pour votre cas d'utilisation est un art plus qu'une science, ce qui rend l'expérimentation essentielle. Pour en savoir plus sur les invites, consultez la documentation Firebase.
Une fois que vous êtes satisfait de votre requête, cliquez sur le bouton "<>" pour obtenir des extraits de code que vous pouvez ajouter à votre code.
Configurer un projet Firebase et associer votre application à Firebase
Lorsque vous êtes prêt à appeler l'API depuis votre application, suivez les instructions de l'étape 1 du guide de démarrage de Firebase AI Logic pour configurer Firebase et le SDK dans votre application.
Ajouter la dépendance Gradle
Ajoutez la dépendance Gradle suivante au module de votre application :
Kotlin
dependencies {
// ... other androidx dependencies
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:firebase-bom:34.2.0"))
// Add the dependency for the Firebase AI Logic library When using the BoM,
// you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-ai")
}
Java
dependencies {
// Import the BoM for the Firebase platform
implementation(platform("com.google.firebase:34.2.0"))
// Add the dependency for the Firebase AI Logic library When using the BoM,
// you don't specify versions in Firebase library dependencies
implementation("com.google.firebase:firebase-ai")
// Required for one-shot operations (to use `ListenableFuture` from Guava
// Android)
implementation("com.google.guava:guava:31.0.1-android")
// Required for streaming operations (to use `Publisher` from Reactive
// Streams)
implementation("org.reactivestreams:reactive-streams:1.0.4")
}
Initialiser le modèle génératif
Commencez par instancier un GenerativeModel
et spécifiez le nom du modèle :
Kotlin
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel("gemini-2.5-flash")
Java
GenerativeModel firebaseAI = FirebaseAI.getInstance(GenerativeBackend.googleAI())
.generativeModel("gemini-2.5-flash");
GenerativeModelFutures model = GenerativeModelFutures.from(firebaseAI);
En savoir plus sur les modèles disponibles pour l'utilisation avec l'API Gemini Developer Vous pouvez également en savoir plus sur la configuration des paramètres du modèle.
Interagir avec l'API Gemini Developer depuis votre application
Maintenant que vous avez configuré Firebase et votre application pour utiliser le SDK, vous êtes prêt à interagir avec l'API Gemini Developer depuis votre application.
Générer du texte
Pour générer une réponse textuelle, appelez generateContent()
avec votre requête.
Kotlin
scope.launch {
val response = model.generateContent("Write a story about a magic backpack.")
}
Java
Content prompt = new Content.Builder()
.addText("Write a story about a magic backpack.")
.build();
ListenableFuture<GenerateContentResponse> response = model.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
[...]
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Générer du texte à partir d'images et d'autres contenus multimédias
Vous pouvez également générer du texte à partir d'une requête incluant du texte, des images ou d'autres contenus multimédias. Lorsque vous appelez generateContent()
, vous pouvez transmettre le contenu multimédia en tant que données intégrées.
Par exemple, pour utiliser un bitmap, utilisez le type de contenu image
:
Kotlin
scope.launch {
val response = model.generateContent(
content {
image(bitmap)
text("what is the object in the picture?")
}
)
}
Java
Content content = new Content.Builder()
.addImage(bitmap)
.addText("what is the object in the picture?")
.build();
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
[...]
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Pour transmettre un fichier audio, utilisez le type de contenu inlineData
:
Kotlin
val contentResolver = applicationContext.contentResolver
val inputStream = contentResolver.openInputStream(audioUri).use { stream ->
stream?.let {
val bytes = stream.readBytes()
val prompt = content {
inlineData(bytes, "audio/mpeg") // Specify the appropriate audio MIME type
text("Transcribe this audio recording.")
}
val response = model.generateContent(prompt)
}
}
Java
ContentResolver resolver = getApplicationContext().getContentResolver();
try (InputStream stream = resolver.openInputStream(audioUri)) {
File audioFile = new File(new URI(audioUri.toString()));
int audioSize = (int) audioFile.length();
byte audioBytes = new byte[audioSize];
if (stream != null) {
stream.read(audioBytes, 0, audioBytes.length);
stream.close();
// Provide a prompt that includes audio specified earlier and text
Content prompt = new Content.Builder()
.addInlineData(audioBytes, "audio/mpeg") // Specify the appropriate audio MIME type
.addText("Transcribe what's said in this audio recording.")
.build();
// To generate text output, call `generateContent` with the prompt
ListenableFuture<GenerateContentResponse> response = model.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String text = result.getText();
Log.d(TAG, (text == null) ? "" : text);
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "Failed to generate a response", t);
}
}, executor);
} else {
Log.e(TAG, "Error getting input stream for file.");
// Handle the error appropriately
}
} catch (IOException e) {
Log.e(TAG, "Failed to read the audio file", e);
} catch (URISyntaxException e) {
Log.e(TAG, "Invalid audio file", e);
}
Pour fournir un fichier vidéo, continuez à utiliser le type de contenu inlineData
:
Kotlin
val contentResolver = applicationContext.contentResolver
contentResolver.openInputStream(videoUri).use { stream ->
stream?.let {
val bytes = stream.readBytes()
val prompt = content {
inlineData(bytes, "video/mp4") // Specify the appropriate video MIME type
text("Describe the content of this video")
}
val response = model.generateContent(prompt)
}
}
Java
ContentResolver resolver = getApplicationContext().getContentResolver();
try (InputStream stream = resolver.openInputStream(videoUri)) {
File videoFile = new File(new URI(videoUri.toString()));
int videoSize = (int) videoFile.length();
byte[] videoBytes = new byte[videoSize];
if (stream != null) {
stream.read(videoBytes, 0, videoBytes.length);
stream.close();
// Provide a prompt that includes video specified earlier and text
Content prompt = new Content.Builder()
.addInlineData(videoBytes, "video/mp4")
.addText("Describe the content of this video")
.build();
// To generate text output, call generateContent with the prompt
ListenableFuture<GenerateContentResponse> response = model.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
System.out.println(resultText);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
}
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
De même, vous pouvez également transmettre des documents PDF (application/pdf
) et en texte brut (text/plain
) en transmettant leur type MIME respectif en tant que paramètre.
Chat multitour
Vous pouvez également prendre en charge les conversations multitours. Initialisez une discussion avec la fonction startChat()
. Vous pouvez éventuellement fournir à votre modèle un historique des messages. Appelez ensuite la fonction sendMessage()
pour envoyer des messages de chat.
Kotlin
val chat = model.startChat(
history = listOf(
content(role = "user") { text("Hello, I have 2 dogs in my house.") },
content(role = "model") { text("Great to meet you. What would you like to know?") }
)
)
scope.launch {
val response = chat.sendMessage("How many paws are in my house?")
}
Java
Content.Builder userContentBuilder = new Content.Builder();
userContentBuilder.setRole("user");
userContentBuilder.addText("Hello, I have 2 dogs in my house.");
Content userContent = userContentBuilder.build();
Content.Builder modelContentBuilder = new Content.Builder();
modelContentBuilder.setRole("model");
modelContentBuilder.addText("Great to meet you. What would you like to know?");
Content modelContent = userContentBuilder.build();
List<Content> history = Arrays.asList(userContent, modelContent);
// Initialize the chat
ChatFutures chat = model.startChat(history);
// Create a new user message
Content.Builder messageBuilder = new Content.Builder();
messageBuilder.setRole("user");
messageBuilder.addText("How many paws are in my house?");
Content message = messageBuilder.build();
// Send the message
ListenableFuture<GenerateContentResponse> response = chat.sendMessage(message);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
String resultText = result.getText();
System.out.println(resultText);
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Générer des images
Le modèle Gemini 2.5 Flash Image (alias Nano Banana) peut générer et retoucher des images en s'appuyant sur la connaissance du monde et le raisonnement. Il génère des images contextuellement pertinentes, en mélangeant ou en entrelaçant de manière fluide les sorties de texte et d'image. Il peut également générer des visuels précis avec de longues séquences de texte et prend en charge la modification conversationnelle d'images tout en conservant le contexte.
Vous pouvez utiliser les modèles Imagen à la place de Gemini, en particulier pour générer des images de haute qualité qui nécessitent du réalisme photographique, des détails artistiques ou des styles spécifiques. Toutefois, pour la majorité des cas d'utilisation côté client pour les applications Android, Gemini sera plus que suffisant.
Ce guide explique comment utiliser le modèle Gemini 2.5 Flash Image à l'aide du SDK Firebase AI Logic pour Android. Pour en savoir plus sur la génération d'images avec Gemini, consultez la documentation Générer des images avec Gemini sur Firebase. Si vous souhaitez utiliser les modèles Imagen, consultez la documentation.

Initialiser le modèle génératif
Instanciez un GenerativeModel
et spécifiez le nom du modèle :
gemini-2.5-flash-image-preview
. Vérifiez que vous configurez responseModalities
pour inclure TEXT
et IMAGE
.
Kotlin
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
modelName = "gemini-2.5-flash-image-preview",
// Configure the model to respond with text and images (required)
generationConfig = generationConfig {
responseModalities = listOf(ResponseModality.TEXT,
ResponseModality.IMAGE)
}
)
Java
GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI()).generativeModel(
"gemini-2.5-flash-image-preview",
// Configure the model to respond with text and images (required)
new GenerationConfig.Builder()
.setResponseModalities(Arrays.asList(ResponseModality.TEXT, ResponseModality.IMAGE))
.build()
);
GenerativeModelFutures model = GenerativeModelFutures.from(ai);
Générer des images (entrée de texte uniquement)
Vous pouvez demander à un modèle Gemini de générer des images en fournissant une requête textuelle uniquement :
Kotlin
// Provide a text prompt instructing the model to generate an image
val prompt = "A hyper realistic picture of a t-rex with a blue bag pack roaming a pre-historic forest."
// To generate image output, call `generateContent` with the text input
val generatedImageAsBitmap = model.generateContent(prompt)
.candidates.first().content.parts.filterIsInstance<ImagePart>()
.firstOrNull()?.image
Java
// Provide a text prompt instructing the model to generate an image
Content prompt = new Content.Builder()
.addText("Generate an image of the Eiffel Tower with fireworks in the background.")
.build();
// To generate an image, call `generateContent` with the text input
ListenableFuture<GenerateContentResponse> response = model.generateContent(prompt);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
// iterate over all the parts in the first candidate in the result object
for (Part part : result.getCandidates().get(0).getContent().getParts()) {
if (part instanceof ImagePart) {
ImagePart imagePart = (ImagePart) part;
// The returned image as a bitmap
Bitmap generatedImageAsBitmap = imagePart.getImage();
break;
}
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Modifier des images (entrée de texte et d'image)
Vous pouvez demander à un modèle Gemini de retoucher des images existantes en fournissant à la fois du texte et une ou plusieurs images dans votre requête :
Kotlin
// Provide an image for the model to edit
val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.scones)
// Provide a text prompt instructing the model to edit the image
val prompt = content {
image(bitmap)
text("Edit this image to make it look like a cartoon")
}
// To edit the image, call `generateContent` with the prompt (image and text input)
val generatedImageAsBitmap = model.generateContent(prompt)
.candidates.first().content.parts.filterIsInstance<ImagePart>().firstOrNull()?.image
// Handle the generated text and image
Java
// Provide an image for the model to edit
Bitmap bitmap = BitmapFactory.decodeResource(resources, R.drawable.scones);
// Provide a text prompt instructing the model to edit the image
Content promptcontent = new Content.Builder()
.addImage(bitmap)
.addText("Edit this image to make it look like a cartoon")
.build();
// To edit the image, call `generateContent` with the prompt (image and text input)
ListenableFuture<GenerateContentResponse> response = model.generateContent(promptcontent);
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
// iterate over all the parts in the first candidate in the result object
for (Part part : result.getCandidates().get(0).getContent().getParts()) {
if (part instanceof ImagePart) {
ImagePart imagePart = (ImagePart) part;
Bitmap generatedImageAsBitmap = imagePart.getImage();
break;
}
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Itérer et modifier des images grâce au chat multitour
Pour une approche conversationnelle de la retouche d'images, vous pouvez utiliser le chat multitours. Cela permet d'affiner les modifications à l'aide de demandes de suivi sans avoir à renvoyer l'image d'origine.
Commencez par initialiser une discussion avec startChat()
, en fournissant éventuellement un historique des messages. Ensuite, utilisez sendMessage()
pour les messages suivants :
Kotlin
// Provide an image for the model to edit
val bitmap = BitmapFactory.decodeResource(context.resources, R.drawable.scones)
// Create the initial prompt instructing the model to edit the image
val prompt = content {
image(bitmap)
text("Edit this image to make it look like a cartoon")
}
// Initialize the chat
val chat = model.startChat()
// To generate an initial response, send a user message with the image and text prompt
var response = chat.sendMessage(prompt)
// Inspect the returned image
var generatedImageAsBitmap = response
.candidates.first().content.parts.filterIsInstance<ImagePart>().firstOrNull()?.image
// Follow up requests do not need to specify the image again
response = chat.sendMessage("But make it old-school line drawing style")
generatedImageAsBitmap = response
.candidates.first().content.parts.filterIsInstance<ImagePart>().firstOrNull()?.image
Java
// Provide an image for the model to edit
Bitmap bitmap = BitmapFactory.decodeResource(resources, R.drawable.scones);
// Initialize the chat
ChatFutures chat = model.startChat();
// Create the initial prompt instructing the model to edit the image
Content prompt = new Content.Builder()
.setRole("user")
.addImage(bitmap)
.addText("Edit this image to make it look like a cartoon")
.build();
// To generate an initial response, send a user message with the image and text prompt
ListenableFuture<GenerateContentResponse> response = chat.sendMessage(prompt);
// Extract the image from the initial response
ListenableFuture<@Nullable Bitmap> initialRequest = Futures.transform(response,
result -> {
for (Part part : result.getCandidates().get(0).getContent().getParts()) {
if (part instanceof ImagePart) {
ImagePart imagePart = (ImagePart) part;
return imagePart.getImage();
}
}
return null;
}, executor);
// Follow up requests do not need to specify the image again
ListenableFuture<GenerateContentResponse> modelResponseFuture = Futures.transformAsync(
initialRequest,
generatedImage -> {
Content followUpPrompt = new Content.Builder()
.addText("But make it old-school line drawing style")
.build();
return chat.sendMessage(followUpPrompt);
}, executor);
// Add a final callback to check the reworked image
Futures.addCallback(modelResponseFuture, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
for (Part part : result.getCandidates().get(0).getContent().getParts()) {
if (part instanceof ImagePart) {
ImagePart imagePart = (ImagePart) part;
Bitmap generatedImageAsBitmap = imagePart.getImage();
break;
}
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
}, executor);
Bonnes pratiques et limites
- Format de sortie : les images sont générées au format PNG avec une dimension maximale de 1 024 px.
- Types d'entrée : le modèle n'est pas compatible avec les entrées audio ou vidéo pour la génération d'images.
- Langues disponibles : pour des performances optimales, utilisez les langues suivantes : anglais (
en
), espagnol mexicain (es-mx
), hindi (hi-in
), japonais (ja-jp
) et chinois simplifié (zh-cn
). - Problèmes de génération :
- La génération d'images ne se déclenche pas toujours, ce qui peut entraîner une sortie textuelle uniquement. Essayez de demander explicitement des images (par exemple, "génère une image", "fournis des images au fur et à mesure", "mets à jour l'image").
- Le modèle peut s'arrêter de générer du contenu en cours de route. Réessayez ou envoyez une autre requête.
- Le modèle peut générer du texte sous forme d'image. Demandez explicitement des résultats textuels (par exemple, "générer un texte narratif avec des illustrations").
Pour en savoir plus, consultez la documentation de Firebase.
Étapes suivantes
- Consultez l'exemple d'application Android Quickstart Firebase et le catalogue d'exemples d'IA Android sur GitHub.
- Préparez votre application pour la production, y compris en configurant Firebase App Check pour protéger l'API Gemini contre les utilisations abusives par des clients non autorisés.
- Pour en savoir plus sur Firebase AI Logic, consultez la documentation Firebase.