Gemini API 키를 발급받기 위해선 프로젝트를 생성해야 한다. Google Cloud 사이트에 접속한 뒤, 프로젝트 선택을 선택한다.

이후 새 프로젝트 버튼을 누른 후, 아래와 같이 프로젝트를 생성한다.

이제 키를 발급받기 위해서 Google AI Studio 사이트에 들어가고, API 키 만들기 > 프로젝트 가져오기 > 생성한 프로젝트 클릭한 후, 키 만들기를 클릭한다.


키를 생성하면 아래 버튼을 통해 키를 복사/붙여넣기 할 수 있다.

gemini를 사용하기 위해서는 다음의 모듈을 implementation 해줘야 한다.
dependencies {
...
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
}
또한, Gemini와 인터넷 통신을 진행해야 하므로, 인터넷 접속 권한을 아래와 같이 부여해야 한다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
Gemini API 문서 를 살펴보면 다음과 같이 Gemini에게 요청을 보내고, 응답을 받아올 수 있다.
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts": [{"text": "Find the race condition in this multi-threaded C++ snippet: [code here]"}]
}]
}'
Gemini에게 요청을 보낼 때 api key가 필요한 것을 확인할 수 있다. 따라서 아까 발급 받았던 api key를 앱 전반에 적용시키는 작업을 수행해줘야 한다. local.properties 파일 제일 아래에 api key를 입력한다.
...
GEMINI_API_KEY=YOUR-API-KEY
이후 앱 수준의 build.gradle에 아래 코드를 작성한다.
def localProperties = new Properties()
def localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.withInputStream { stream ->
localProperties.load(stream)
}
}
def geminiApiKey = localProperties.getProperty("GEMINI_API_KEY", "")
android {
...
buildFeatures {
buildConfig true
}
...
defaultConfig {
...
buildConfigField "String", "GEMINI_API_KEY", "\"${geminiApiKey}\""
}
}
Gemini에게 요청을 보내고, 응답을 받기까지 시간이 걸린다. 이 처리를 호출하는 Activity에서 관리할 경우, 코드의 길이가 불필요하게 증가할 수 있으며, Gemini를 여러 번 호출할 경우 코드 가독성이 떨어진다.
따라서 Gemini에게 통신을 보내고 받아오는 것을 별도의 class로 관리하며, Gemini의 응답을 받아올 경우 callback 함수를 호출하여 Activity로 전달하는 형태로 구현한다.
AskGemini.java 파일을 생성하고, 아래와 같이 기초 코드를 작성한다.
public class AskGemini {
public interface GeminiCallback {
void onSuccess(String response);
void onError(String errorMessage, int httpCode);
}
private String ENDPOINT = "https://generativelanguage.googleapis.com";
private MediaType JSON = MediaType.get("application/json; charset=utf-8");
private OkHttpClient http = new OkHttpClient.Builder()
.connectTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.writeTimeout(120, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(180, java.util.concurrent.TimeUnit.SECONDS)
.callTimeout(240, java.util.concurrent.TimeUnit.SECONDS)
.build();
private String apiKey = BuildConfig.GEMINI_API_KEY;
public AskGemini() { }
// 여기에 함수 추가
}
API 문서에 따르면, 아래와 같이 요청을 보낸다.
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-preview:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
-X POST \
-d '{
"contents": [{
"parts": [{"text": "How does AI work?"}]
}],
"generationConfig": {
"thinkingConfig": {
"thinkingLevel": "low"
}
}
}'
이 요청에 맞추어서 응답을 보내고 받아오는 코드는 아래와 같다.
public class AskGemini {
...
public void askText(String prompt, GeminiCallback callback) {
ENDPOINT += "/v1beta/models/gemini-3-flash-preview:generateContent";
try {
String body = String.format("{\n" +
" \"contents\": [\n" +
" {\n" +
" \"parts\": [\n" +
" { \"text\": %s }\n" +
" ]\n" +
" }\n" +
" ],\n" +
" \"generationConfig\": {\n" +
" \"thinkingConfig\": {\n" +
" \"thinkingLevel\": \"low\"\n" + // 원하는 성능에 맞추어 minimal, low, medium, high 선택
" }\n" +
" }\n" +
"}", JSONObject.quote(prompt));
Request req = new Request.Builder()
.url(ENDPOINT)
.addHeader("x-goog-api-key", apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, JSON))
.build();
http.newCall(req).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onError("Network failure: " + e.getMessage(), -1);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String raw = response.body() != null ? response.body().string() : "";
if (!response.isSuccessful()) {
callback.onError(raw, response.code());
return;
}
String text = "";
try {
text = parseResponse(raw);
callback.onSuccess(text);
} catch (Exception e) {
callback.onError("Response parsing error: " + e.getMessage(), response.code());
}
}
});
} catch (Exception e) {
callback.onError("Build request error: " + e.getMessage(), -1);
}
}
private String parseResponse(String raw) throws Exception {
JSONObject json = new JSONObject(raw);
return json
.getJSONArray("candidates")
.getJSONObject(0)
.getJSONObject("content")
.getJSONArray("parts")
.getJSONObject(0)
.getString("text");
}
}
사용법은 아래와 같다.
public class MainActivity extends AppCompatActivity {
AskGemini askGemini = new AskGemini();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
askGemini.askText("Hello, Gemini!", new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String response) {
System.out.println("Gemini Response: " + response);
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
}
파일을 Gemini에게 전달하기 위해선 Base64 방식의 인코딩을 사용해야 하며, 다음의 과정을 거친다.
Uri → InputStream → byte[] → Base64
따라서 Uri를 전달받으면 Base64로 바꾼 후, 프롬프트에 넣는 함수를 아래와 같이 작성할 수 있다.
public class AskGemini {
...
public void askTextWithUri(String prompt, Uri uri, String mimeType, Context context, GeminiCallback callback) {
ENDPOINT += "/v1beta/models/gemini-3-flash-preview:generateContent";
try {
InputStream is = context.getContentResolver().openInputStream(uri);
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (is == null) throw new IllegalStateException("Cannot open input stream");
byte[] buf = new byte[8192];
int n;
while ((n = is.read(buf)) >= 0) {
os.write(buf, 0, n);
}
byte[] bytes = os.toByteArray();
String b64 = Base64.getEncoder().encodeToString(bytes);
String body = String.format("{\n" +
" \"contents\": [\n" +
" {\n" +
" \"parts\": [{\"text\": %s}]\n" +
" },\n" +
" {\n" +
" \"parts\": [\n" +
" {\"inlineData\": {\"mimeType\": %s, \"data\": %s}}\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}",
JSONObject.quote(prompt),
JSONObject.quote(mimeType),
JSONObject.quote(b64)
);
Request req = new Request.Builder()
.url(ENDPOINT)
.addHeader("x-goog-api-key", apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, MediaType.get("application/json; charset=utf-8")))
.build();
http.newCall(req).enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callback.onError("Network failure: " + e.getMessage(), -1);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String raw = response.body() != null ? response.body().string() : "";
if (!response.isSuccessful()) {
callback.onError(raw, response.code());
return;
}
try {
callback.onSuccess(parseResponse(raw));
} catch (Exception e) {
callback.onError("Response parsing error: " + e.getMessage(), response.code());
}
}
});
} catch (Exception e) {
callback.onError("Request build error: " + e.getMessage(), -1);
}
}
}
사용법은 아래와 같다.
public class MainActivity extends AppCompatActivity {
AskGemini askGemini = new AskGemini();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ActivityResultLauncher<Intent> pickFileLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
Uri uri = result.getData().getData();
if (uri != null) {
askGemini.askTextWithUri("What animal appears in this recording?", uri, "audio/mpeg",
getApplicationContext(), new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String response) {
System.out.println("Gemini Response: " + response);
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
}
}
);
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
pickFileLauncher.launch(intent);
});
}
}
만약 갤러리에서 사진을 가져오는 등의 작업으로 수정하고 싶으면, button.setOnClickListener 부분을 아래와 같이 수정하면 된다.
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
pickImageLauncher.launch(intent);
});
우선 카메라를 사용하고, 임시 파일을 저장하기 위해서는 아래 권한이 필요하다. AndroidManifest.xml 파일에 아래 권한을 추가한다.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
...
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
...
</manifest>
버튼을 눌러 카메라를 열고, 카메라에서 찍은 사진을 Gemini에게 물어보기 위해선 추가 작업이 필요하다. 카메라 앱은 찍은 사진을 Intent 데이터로 주는 것이 아니기 때문에 getData() 결과가 null 이 나올 수 있다. 따라서 Uri를 생성해 해당 Uri에 저장하도록 카메라 앱에 전달해줘야 한다. 코드는 아래와 같다.
5-2에서 만들었던 askTextWithUri 함수를 이용한다.
public class MainActivity extends AppCompatActivity {
...
AskGemini askGemini = new AskGemini();
Uri cameraImageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ActivityResultLauncher<Intent> takePhotoLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == RESULT_OK) {
askGemini.askTextWithUri("What's in this image?", cameraImageUri, "image/jpeg",
getApplicationContext(), new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String response) {
System.out.println("Gemini Response: " + response);
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
}
);
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, "cam_" + System.currentTimeMillis() + ".jpg");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/Gemini");
}
cameraImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);
takePhotoLauncher.launch(intent);
});
}
}
이미지 생성 기능을 사용하기 위해서는 Google AI Studio에서 결제 설정을 해줘야 한다.
아래 화면에서 결제 설정을 누른 후,

결제 계정 관리를 누르고

계정이 없는 경우에만 계정 만들기를 선택한다.

카드를 등록하고 계정을 만들면 된다. 이후 다시 Google AI Studio에서 결제 설정 버튼을 클릭 후 결제 계정을 연결해주면 된다. 최종 화면이 아래와 같으면 성공이다.

추가로, 요청을 보내면 다음과 같이 Base64로 인코딩된 이미지를 받기 때문에, 이미지를 bitmap 형식으로 변환하여 imageView에 띄워줘야 한다.
{
"candidates": [
{
"content": {
"parts": [
{
"text": "Okay, here's a banana riding a skateboard! "
},
{
"inlineData": {
"mimeType": "image/png",
"data": "iVBORw0KGgoAAAANSUhEU..."
}
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 7,
"candidatesTokenCount": 1302,
"totalTokenCount": 1309,
"promptTokensDetails": [
{
"modality": "TEXT",
"tokenCount": 7
}
],
"candidatesTokensDetails": [
{
"modality": "IMAGE",
"tokenCount": 1290
}
]
},
"modelVersion": "gemini-2.5-flash-image",
"responseId": "_YRxafaUCdnP2roPrOGC6Qc"
}
AskGemini 코드는 아래와 같이 구성한다.
public class AskGemini {
...
public void generateImage(String prompt, GeminiCallback callback) {
ENDPOINT += "/v1beta/models/gemini-2.5-flash-image:generateContent";
try {
String body = String.format("{\n" +
" \"contents\": [\n" +
" {\n" +
" \"parts\": [\n" +
" { \"text\": %s }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}", JSONObject.quote(prompt));
Request req = new Request.Builder()
.url(ENDPOINT)
.addHeader("x-goog-api-key", apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, JSON))
.build();
http.newCall(req).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onError("Network failure: " + e.getMessage(), -1);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String raw = response.body() != null ? response.body().string() : "";
if (!response.isSuccessful()) {
callback.onError(raw, response.code());
return;
}
String text = "";
try {
text = parseImageResponse(raw);
callback.onSuccess(text);
} catch (Exception e) {
callback.onError("Response parsing error: " + e.getMessage(), response.code());
}
}
});
} catch (Exception e) {
callback.onError("Build request error: " + e.getMessage(), -1);
}
}
private String parseImageResponse(String raw) throws Exception {
JSONObject json = new JSONObject(raw);
JSONArray parts = json
.optJSONArray("candidates")
.getJSONObject(0)
.optJSONObject("content")
.optJSONArray("parts");
for (int i = 0; i < parts.length(); i++) {
JSONObject part = parts.optJSONObject(i);
if (part == null) continue;
JSONObject inlineData = part.optJSONObject("inlineData");
if (inlineData == null) continue;
String data = inlineData.optString("data", null);
if (data != null && !data.isEmpty()) {
return data;
}
}
throw new IllegalStateException("No inlineData found in parts");
}
}
사용법은 아래와 같다.
public class MainActivity extends AppCompatActivity {
AskGemini askGemini = new AskGemini();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = findViewById(R.id.imageView);
askGemini.generateImage("Create a banana riding a skateboard.", new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String imageB64) {
byte[] decodedBytes = Base64.decode(imageB64, android.util.Base64.DEFAULT);
Bitmap bitmap = decodeByteArray(decodedBytes, 0, decodedBytes.length);
runOnUiThread(() -> {
imageView.setImageBitmap(bitmap);
});
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
}
Gemini는 주어진 이미지를 바탕으로 편집하는 기술을 지원한다. 기본이 되는 이미지를 갤러리에서 선택한 후, 프롬프트와 함께 Gemini에게 요청하면 된다. 만약 카메라에서 사진을 찍은 후 편집을 원한다면 4-3번을 참고해서 코딩하자.
public class AskGemini {
...
public void editImageWithText(String prompt, Uri baseImg, Context context, GeminiCallback callback) {
ENDPOINT += "/v1beta/models/gemini-2.5-flash-image:generateContent";
try {
InputStream is = context.getContentResolver().openInputStream(baseImg);
ByteArrayOutputStream os = new ByteArrayOutputStream();
if (is == null) throw new IllegalStateException("Cannot open input stream");
byte[] buf = new byte[8192];
int n;
while ((n = is.read(buf)) >= 0) {
os.write(buf, 0, n);
}
byte[] bytes = os.toByteArray();
String b64 = Base64.getEncoder().encodeToString(bytes);
String body = String.format("{\n" +
" \"contents\": [\n" +
" {\n" +
" \"parts\": [\n" +
" { \"text\": %s },\n" +
" {\n" +
" \"inlineData\": {\n" +
" \"mimeType\": \"image/jpeg\",\n" +
" \"data\": %s\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}",
JSONObject.quote(prompt),
JSONObject.quote(b64));
Request req = new Request.Builder()
.url(ENDPOINT)
.addHeader("x-goog-api-key", apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, JSON))
.build();
http.newCall(req).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onError("Network failure: " + e.getMessage(), -1);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String raw = response.body() != null ? response.body().string() : "";
if (!response.isSuccessful()) {
callback.onError(raw, response.code());
return;
}
String text = "";
try {
text = parseImageResponse(raw);
callback.onSuccess(text);
} catch (Exception e) {
callback.onError("Response parsing error: " + e.getMessage(), response.code());
}
}
});
} catch (Exception e) {
callback.onError("Build request error: " + e.getMessage(), -1);
}
}
}
사용법은 아래와 같다.
public class MainActivity extends AppCompatActivity {
AskGemini askGemini = new AskGemini();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = findViewById(R.id.imageView);
ActivityResultLauncher<Intent> pickImageLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == RESULT_OK && result.getData() != null) {
Uri uri = result.getData().getData();
if (uri != null) {
askGemini.editImageWithText("Turn the dog into a cat", uri,
getApplicationContext(), new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String imageB64) {
byte[] decodedBytes = Base64.decode(imageB64, android.util.Base64.DEFAULT);
Bitmap bitmap = decodeByteArray(decodedBytes, 0, decodedBytes.length);
runOnUiThread(() -> {
imageView.setImageBitmap(bitmap);
});
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
}
}
);
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
pickImageLauncher.launch(intent);
});
}
}
아래 두 이미지로부터

이런 이미지를 생성하고자 한다면,

두 이미지와 프롬프트를 Gemini에 함께 전달하면 된다. 이를 위한 코드를 AskGemini에 아래와 같이 작성하면 된다.
public class AskGemini {
...
public void editImageWithImages(String prompt, List<Uri> uris, Context context, GeminiCallback callback) {
ENDPOINT += "/v1beta/models/gemini-2.5-flash-image:generateContent";
try {
String body = String.format("{\n" +
" \"contents\": [\n" +
" {\n" +
" \"parts\": [\n" +
" { \"text\": %s },\n",
JSONObject.quote(prompt));
for (Uri uri : uris) {
byte[] bytes;
try (InputStream is = context.getContentResolver().openInputStream(uri);
ByteArrayOutputStream os = new ByteArrayOutputStream()) {
if (is == null) {
callback.onError("Cannot open input stream: " + uri, -1);
return;
}
byte[] buf = new byte[8192];
int n;
while ((n = is.read(buf)) >= 0) os.write(buf, 0, n);
bytes = os.toByteArray();
}
String mime = context.getContentResolver().getType(uri);
if (mime == null || mime.isEmpty()) {
mime = "image/png";
}
String b64 = encodeToString(bytes, android.util.Base64.NO_WRAP);
String body_ = String.format(
" {\n" +
" \"inlineData\": {\n" +
" \"mimeType\": %s,\n" +
" \"data\": %s\n" +
" }\n" +
" },\n",
JSONObject.quote(mime),
JSONObject.quote(b64));
body += body_;
}
body += " ]\n" +
" }\n" +
" ]\n" +
"}";
Request req = new Request.Builder()
.url(ENDPOINT)
.addHeader("x-goog-api-key", apiKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, JSON))
.build();
http.newCall(req).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onError("Network failure: " + e.getMessage(), -1);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String raw = (response.body() != null) ? response.body().string() : "";
System.out.println(raw);
if (!response.isSuccessful()) {
callback.onError(raw, response.code());
return;
}
try {
String imageB64 = parseImageResponse(raw);
callback.onSuccess(imageB64);
} catch (Exception e) {
callback.onError("Response parsing error: " + e.getMessage(), response.code());
}
}
});
} catch (Exception e) {
callback.onError("Build request error: " + e.getMessage(), -1);
}
}
}
사용법은 아래와 같다.
public class MainActivity extends AppCompatActivity {
AskGemini askGemini = new AskGemini();
@Override
protected void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = findViewById(R.id.imageView);
ActivityResultLauncher<Intent> pickImagesLauncher =
registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() != RESULT_OK || result.getData() == null) return;
Intent data = result.getData();
List<Uri> uris = new ArrayList<>();
ClipData clipData = data.getClipData();
if (clipData != null) {
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
Uri uri = item.getUri();
if (uri != null) uris.add(uri);
}
} else {
Uri uri = data.getData();
if (uri != null) uris.add(uri);
}
askGemini.editImageWithImages("Combine the two images", uris,
getApplicationContext(), new AskGemini.GeminiCallback() {
@Override
public void onSuccess(String imageB64) {
byte[] decodedBytes = android.util.Base64.decode(imageB64, android.util.Base64.DEFAULT);
Bitmap bitmap = decodeByteArray(decodedBytes, 0, decodedBytes.length);
runOnUiThread(() -> {
imageView.setImageBitmap(bitmap);
});
}
@Override
public void onError(String errorMessage, int httpCode) {
System.out.println(errorMessage);
}
});
}
);
Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
pickImagesLauncher.launch(intent);
});
}
}
위에 나열된 기술 말고도 Gemini를 더 잘 활용하고 싶다면, Gemini API docs 를 읽어보자. Gemini API 호출을 어떻게 하느냐보단, callback 함수를 이용해서 코드를 간소화하기, 함수를 어떻게 응용하는지에 대해 조금 더 초점을 맞추어 공부하면 좋을 것 같다.
<AskGemini.java Libraries>
import org.json.JSONObject;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;