Open In App

Flutter – Integrate Google Gemini API

Last Updated : 09 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Currently, Artificial Intelligence is blooming all around. You must have heard about the ChatGPT, Bard and now Google has come up with a very new Artificial intelligence Gemini which responds to users in a truly human-like way. You can connect Google Gemini with Flutter in a very simple and quick way. Let’s learn how to do that. A sample video is given below to get an idea about what we are going to do in this article.

Step By Step Implementation

Step 1: Create a New Project in Android Studio

To set up Flutter Development on Android Studio please refer to Android Studio Setup for Flutter Development, and then create a new project in Android Studio please refer to Creating a Simple Application in Flutter.

Step 2: Add the package in flutter

Now we will add the flutter_gemini package in this project. You can add the package using this command.

Dart




flutter pub add flutter_gemini


Step 3: Create the Google API key and store it in dotenv

To create google gemini API key Click here and You can refer this article to store keys for env file.

Step 4: We have 3 types to get the data through AI

  • Sending a question to AI so that it can answer it
  • Sending image and text to ask question
  • To do chatting with AI.

Currently we will apply 2 functionality and we can select between one of them from Radio. We will use this using the radio button and select between to search with image or not. This are function which you will be require to search with gemini

1. Asking a question from AI

Dart




gemini.text(searchedText!).then((value) {
                         // This will give the final output by Gemini
                         result = value?.content?.parts?.last.text;
                         loading = false;
                       });


2. Sending Image and asking question related to it

In this we will understand how to ask gemini with our image. From Selection Image from your device you can refer to this article Gallery Access and Camera in Flutter

Dart




gemini.textAndImage(
                    text: searchedText!, image: selectedImage!)
                            .then((value) {
                          result = value?.content?.parts?.last.text;
                     });


You can use this function in your app as per your requirement. We have make a simple project where we can search from gemini through textfield.

Brief Explanation about project:

We have added 2 RadioButton to search either through text and image or through text. After that 1 material button is there where we will show what you have searched for after that result will be shown and at bottom we have added textfield where we will type our query and button to get result from gemini and if we have selected search with image then 1 more button for selecting image from device. We have added toast for validating the text and image are empty or not and loader when user is searching for data.

Complete source code for sample project:

Dart




class MyGeminiSearchScreen extends StatefulWidget {
  const MyGeminiSearchScreen({super.key});
  
  @override
  State<MyGeminiSearchScreen> createState() => _MyGeminiSearchScreenState();
}
  
class _MyGeminiSearchScreenState extends State<MyGeminiSearchScreen> {
  final ImagePicker picker = ImagePicker();
  final controller = TextEditingController();
  final gemini = Gemini.instance;
  String? searchedText, result;
  
  bool loading = false;
  bool isTextWithImage = false;
  Uint8List? selectedImage;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter Gemini"),
      ),
      body: Column(
        children: [
          // Radio to select between different type of search
          Row(
            children: [
              Radio(
                  value: false,
                  groupValue: isTextWithImage,
                  onChanged: (val) {
                    setState(() {
                      isTextWithImage = val ?? false;
                    });
                  }),
              const Text("Search with Text"),
              Radio(
                  value: true,
                  groupValue: isTextWithImage,
                  onChanged: (val) {
                    setState(() {
                      isTextWithImage = val ?? false;
                    });
                  }),
              const Text("Search with Text and Image")
            ],
          ),
          // To show text that we have search for
          if (searchedText != null)
            MaterialButton(
                color: Colors.green.shade200,
                onPressed: () {
                  setState(() {
                    searchedText = null;
                    result = null;
                  });
                },
                child: Text(
                  'Search: $searchedText',
                  style: const TextStyle(color: Colors.white),
                )),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Expanded(
                    flex: 2,
                    // Loader when gemini is searching for result
                    child: loading
                        ? const Center(child: CircularProgressIndicator())
                        : result != null
                            ? Markdown(
                                data: result!,
                                padding:
                                    const EdgeInsets.symmetric(horizontal: 12),
                              )
                            : const Center(
                                child: Text('Search something!'),
                              ),
                  ),
                  if (selectedImage != null)
                    Expanded(
                      flex: 1,
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(32),
                        child: Image.memory(
                          selectedImage!,
                          fit: BoxFit.cover,
                        ),
                      ),
                    )
                ],
              ),
            ),
          ),
          Card(
            margin: const EdgeInsets.all(12),
            child: Row(
              children: [
                Expanded(
                    child: TextField(
                  controller: controller,
                  decoration: const InputDecoration(
                    contentPadding: EdgeInsets.symmetric(horizontal: 12),
                    hintText: 'Write Something...',
                    border: InputBorder.none,
                  ),
                  onTapOutside: (event) =>
                      FocusManager.instance.primaryFocus?.unfocus(),
                )),
                if (isTextWithImage)
                  Padding(
                    padding: const EdgeInsets.only(right: 8.0),
                    // Select image from device
                    child: IconButton(
                        onPressed: () async {
                          final ImagePicker picker =
                              ImagePicker(); // To select Image from device
                          // Capture a photo.
                          final XFile? photo = await picker.pickImage(
                              source: ImageSource.camera);
  
                          if (photo != null) {
                            photo.readAsBytes().then((value) => setState(() {
                                  selectedImage = value;
                                }));
                          }
                        },
                        icon: const Icon(Icons.file_copy_outlined)),
                  ),
                // Send the typed the search to gemini
                Padding(
                  padding: const EdgeInsets.only(right: 8.0),
                  child: IconButton(
                      onPressed: () {
                        if (controller.text.isNotEmpty) {
                          if (isTextWithImage) {
                            if (selectedImage != null) {
                              searchedText = controller.text;
                              controller.clear();
                              loading = true;
                              setState(() {});
                              gemini
                                  .textAndImage(
                                      text: searchedText!,
                                      image: selectedImage!)
                                  .then((value) {
                                result = value?.content?.parts?.last.text;
                                loading = false;
                              });
                            } else {
                              Fluttertoast.showToast(
                                  msg: "Please select picture");
                            }
                          } else {
                            searchedText = controller.text;
                            controller.clear();
                            loading = true;
                            setState(() {});
                            gemini.text(searchedText!).then((value) {
                              print(value?.content?.parts?.length.toString());
                              result = value?.content?.parts?.last.text;
                              loading = false;
                            });
                          }
                        } else {
                          Fluttertoast.showToast(msg: "Please enter something");
                        }
                      },
                      icon: const Icon(Icons.send_rounded)),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }
}


Output:

Search with Text:

Search with text and image:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads