Gemini Developer API

Gemini Developer API предоставляет доступ к моделям Gemini от Google, позволяя добавлять в приложения Android передовые функции генеративного ИИ, в том числе чат, генерацию изображений (с помощью Nano Banana) и текста на основе текстовых, графических, аудио- и видеозапросов.

Чтобы получить доступ к моделям Gemini Pro и Flash, можно использовать Gemini Developer API с Firebase AI Logic. Вы можете начать работу, не указывая способ оплаты (например, кредитную карту), и пользоваться бесплатным тарифным планом. После того как вы проверите интеграцию на небольшой группе пользователей, вы сможете перейти на платный тариф и увеличить масштаб.

Иллюстрация, на которой показано, как приложение Android отправляет запросы в облачный бэкэнд Firebase с помощью Firebase Android SDK. Запросы направляются в Gemini Developer API, который может использовать модели Gemini Pro и Flash.
Рисунок 1. Архитектура интеграции Firebase AI Logic для доступа к Gemini Developer API.

Начало работы

Прежде чем взаимодействовать с Gemini API напрямую из приложения, вам нужно будет выполнить несколько действий, в том числе ознакомиться с принципами создания запросов, а также настроить Firebase и приложение для использования SDK.

Экспериментируйте с запросами

Экспериментируя с запросами, вы сможете найти оптимальные формулировки, контент и формат для своего приложения Android. Google AI Studio – это интегрированная среда разработки (IDE), которую можно использовать для создания прототипов и разработки запросов для различных сценариев использования приложения.

Чтобы создать эффективные запросы для вашего варианта использования, необходимо провести множество экспериментов. Это важная часть процесса. Подробнее о запросах можно узнать из документации Firebase.

Когда вы будете довольны запросом, нажмите кнопку <>, чтобы получить фрагменты кода, которые можно добавить в свой код.

Как настроить проект Firebase и подключить к нему приложение

Когда вы будете готовы вызывать API из приложения, следуйте инструкциям из раздела "Шаг 1" руководства по началу работы с Firebase AI Logic, чтобы настроить Firebase и включить необходимые API и сервисы.

Добавьте зависимости Gradle

Добавьте в модуль приложения следующие зависимости Gradle:

Kotlin

dependencies {
  // ... other androidx dependencies

  // Import the BoM for the Firebase platform
  implementation(platform("com.google.firebase:firebase-bom:34.19.0"))

  // Add the dependencies for the Firebase AI Logic and App Check libraries
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation("com.google.firebase:firebase-ai")
  implementation("com.google.firebase:firebase-appcheck-debug")
}

Java

dependencies {
  // Import the BoM for the Firebase platform
  implementation(platform("com.google.firebase:34.19.0"))

  // Add the dependencies for the Firebase AI Logic and App Check libraries
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation("com.google.firebase:firebase-ai")
  implementation("com.google.firebase:firebase-appcheck-debug")

  // 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")
}

Как настроить поставщика данных для отладки App Check при локальной разработке

С начала июля 2026 года в рамках пошаговой настройки логики ИИ в консоли Firebase будет автоматически включаться Проверка приложений Firebase для защиты Gemini API. Для локальной разработки вам нужно настроить поставщика данных для отладки App Check, чтобы пропускать подтверждение, но при этом сохранять принудительное применение App Check.

  1. В отладочной сборке настройте App Check на использование фабрики поставщика отладки:

    Kotlin

    Firebase.initialize(context = this)
    Firebase.appCheck.installAppCheckProviderFactory(
        DebugAppCheckProviderFactory.getInstance(),
    )
    

    Java

    FirebaseApp.initializeApp(/*context=*/ this);
    FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
    firebaseAppCheck.installAppCheckProviderFactory(
            DebugAppCheckProviderFactory.getInstance());
    
  2. Получите токен отладки:

    1. Запустите приложение в эмуляторе или на тестовом устройстве.

    2. Найдите в журналах токен отладки App Check. Пример:

      D DebugAppCheckProvider: Enter this debug secret into the allow list
      in the Firebase Console for your project: 123a4567-b89c-12d3-e456-789012345678
      
    3. Скопируйте токен (например, 123a4567-b89c-12d3-e456-789012345678).

  3. Зарегистрируйте токен отладки в App Check:

    1. В консоли Firebase выберите Безопасность > Проверка приложений > вкладка Приложения.

    2. Найдите приложение, нажмите на дополнительное меню () и выберите Управление токенами отладки.

    3. Следуйте инструкциям на экране, чтобы зарегистрировать токен отладки.

Подробную информацию о поставщике отладки (в том числе о том, как получить новый токен отладки) можно найти в официальной документации по App Check.

Инициализация генеративной модели

Для начала создайте экземпляр GenerativeModel и укажите название модели:

Kotlin

// Start by instantiating a GenerativeModel and specifying the model name:
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .generativeModel("gemini-3.5-flash")

Java

GenerativeModel firebaseAI = FirebaseAI.getInstance(GenerativeBackend.googleAI())
        .generativeModel("gemini-3.5-flash");

GenerativeModelFutures model = GenerativeModelFutures.from(firebaseAI);

Подробнее о доступных моделях для использования с Gemini Developer API… Подробнее о том, как настроить параметры модели…

Как взаимодействовать с Gemini Developer API из приложения

Теперь, когда вы настроили Firebase и приложение для использования SDK, вы можете взаимодействовать с Gemini Developer API из приложения.

Как сгенерировать текст

Чтобы сгенерировать текстовый ответ, вызовите функцию generateContent() с запросом.

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);

Как генерировать текст на основе изображений и других медиафайлов

Вы также можете сгенерировать текст на основе запроса, в котором есть текст, изображения или другие медиафайлы. При вызове generateContent() вы можете передать медиаконтент как встроенные данные.

Например, чтобы использовать растровое изображение, укажите тип контента 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);

Чтобы передать аудиофайл, используйте тип контента inlineData:

Kotlin

scope.launch {
    val contentResolver = applicationContext.contentResolver
    contentResolver.openInputStream(audioUri).use { stream ->
        stream?.let {
            val bytes = it.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 = applicationContext.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);
}

Чтобы добавить видеофайл, используйте тип контента inlineData:

Kotlin

scope.launch {
    val contentResolver = applicationContext.contentResolver
    contentResolver.openInputStream(videoUri).use { stream ->
        stream?.let {
            val bytes = it.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 = applicationContext.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();
}

Аналогичным образом можно передавать документы PDF (application/pdf) и обычный текст (text/plain), указав их MIME-тип в качестве параметра.

Многоходовые чаты

Также можно поддерживать многоходовые диалоги. Инициализируйте чат с помощью функции startChat(). Вы также можете предоставить модели историю сообщений. Затем вызовите функцию sendMessage(), чтобы отправить сообщения в чат.

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 = modelContentBuilder.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);

Как создавать изображения на устройстве Android с помощью Nano Banana

Модели Gemini для работы с изображениями (также известные как модели Nano Banana) могут генерировать и редактировать изображения, используя знания о мире и логику. Они генерируют изображения, соответствующие контексту, и органично сочетают текст и изображения. Они также могут создавать точные изображения с длинными текстовыми последовательностями и поддерживают редактирование изображений в диалоговом режиме с сохранением контекста.

В этом руководстве рассказывается, как использовать модели Gemini Image (модели Nano Banana) с помощью Firebase AI Logic SDK для Android. Подробнее о том, как генерировать изображения с помощью Gemini, можно узнать в документации Firebase.

Интерфейс Google AI Studio с текстовым полем, в котором введен запрос &quot;Гиперреалистичное изображение тираннозавра с синим рюкзаком, гуляющего по доисторическому лесу&quot;, и сгенерированным изображением тираннозавра в лесу с синим рюкзаком.
Рисунок 2. Как использовать Google AI Studio, чтобы улучшить запросы для генерации изображений с помощью Nano Banana в приложении для Android

Инициализация генеративной модели

Создайте экземпляр GenerativeModel и укажите название модели Gemini Image (например, gemini-3.1-flash-image). Затем настройте responseModalities, чтобы включить TEXT и IMAGE для создания чередующегося текста и изображений. Если вы исключите TEXT, модель будет возвращать только изображения.

Kotlin

val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
    modelName = "gemini-3.1-flash-image",
    // Configure the model to respond with images (required) and text (optional)
    generationConfig = generationConfig {
        responseModalities = listOf(
            ResponseModality.TEXT,
            ResponseModality.IMAGE
        )
    }
)

Java

GenerativeModel ai = FirebaseAI.getInstance(GenerativeBackend.googleAI()).generativeModel(
        "gemini-3.1-flash-image",
        // 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);

Создание изображений по текстовым описаниям

Вы можете попросить модель Gemini сгенерировать изображения, предоставив текстовый запрос:

Kotlin

scope.launch {
    // 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: Bitmap? = 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);

Редактирование изображений (текстовый и графический ввод)

Вы можете попросить модель Gemini отредактировать существующие изображения, добавив в запрос текст и одно или несколько изображений:

Kotlin

scope.launch {
    // 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: Bitmap? = 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);

Выполнение итераций и редактирование изображений в пошаговом чате

Чтобы редактировать изображения в диалоговом режиме, используйте пошаговый чат. Это позволяет уточнять изменения, не отправляя исходное изображение повторно.

Сначала запустите чат с startChat(), при необходимости указав историю сообщений. Затем используйте sendMessage() для последующих сообщений:

Kotlin

scope.launch {
    // 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: Bitmap? = 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<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);

Ограничения и примечания

Обратите внимание на следующие ограничения и рекомендации:

  • Формат выходных данных. Изображения генерируются в формате PNG с максимальным размером 1024 пкс.
  • Типы входных данных. Модель не поддерживает аудио- и видеовходные данные для создания изображений.
  • Поддержка языков. Для оптимальной работы используйте следующие языки: английский (en), испанский (Мексика) (es-mx), японский (ja-jp), китайский (упрощенный) (zh-cn) и хинди (hi-in).
  • Проблемы с генерацией:
    • Генерация изображений может не всегда запускаться, поэтому иногда вы будете получать только текстовые ответы. Попробуйте явно попросить сгенерировать изображение (например, "создай изображение", "добавляй изображения по ходу разговора", "обнови изображение").
    • Модель может перестать генерировать текст в середине. Повторите попытку или попробуйте другой запрос.
    • Модель может сгенерировать текст в виде изображения. Попробуйте явно попросить сгенерировать текст (например, "создай повествовательный текст и иллюстрации к нему").

Подробную информацию можно найти в документации Firebase.

Дальнейшие действия

После настройки приложения выполните следующие действия: