package com.example.lifegrid; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.util.Log; import com.google.ai.client.generativeai.GenerativeModel; import com.google.ai.client.generativeai.java.GenerativeModelFutures; import com.google.ai.client.generativeai.type.Content; import com.google.ai.client.generativeai.type.GenerateContentResponse; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import org.json.JSONException; import org.json.JSONObject; import java.io.InputStream; import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class InvoiceScannerHelper { private static final String API_KEY = "AIzaSyCoUZSXfEk43LfPtkCCjsnQ_ZMWX7NG1xQ"; // Substitua pela sua chave API private static final String PROMPT = "Analisa esta fatura. Devolve APENAS um objeto JSON com os campos: 'valor' (Double, apenas números e ponto decimal), 'descricao' (String curta, nome do estabelecimento ou produto), 'categoria' (String, ex: Alimentação, Transporte, Lazer, Saúde, Casa, Educação, Outros), e 'data' (String formato DD/MM/AAAA). Se não conseguires ler algum, coloca valor padrão ou string vazia."; public interface ScanCallback { void onSuccess(double valor, String descricao, String categoria, String data); void onError(String error); } public static void scanInvoice(Context context, Uri imageUri, ScanCallback callback) { if (API_KEY == null || API_KEY.isEmpty() || API_KEY.contains("YOUR_GEMINI_API_KEY")) { callback.onError("Chave API do Gemini não configurada."); return; } Executor executor = Executors.newSingleThreadExecutor(); try (InputStream imageStream = context.getContentResolver().openInputStream(imageUri)) { Bitmap bitmap = BitmapFactory.decodeStream(imageStream); if (bitmap == null) { callback.onError("Não foi possível carregar a imagem da fatura."); return; } GenerativeModel gm = new GenerativeModel( "gemini-1.5-flash", API_KEY ); GenerativeModelFutures model = GenerativeModelFutures.from(gm); Content content = new Content.Builder() .addText(PROMPT) .addImage(bitmap) .build(); ListenableFuture response = model.generateContent(content); Futures.addCallback(response, new FutureCallback() { @Override public void onSuccess(GenerateContentResponse result) { try { String textResponse = result.getText(); if (textResponse != null) { textResponse = textResponse.replace("```json", "").replace("```", "").trim(); JSONObject json = new JSONObject(textResponse); double valor = json.optDouble("valor", 0.0); String descricao = json.optString("descricao", ""); String categoria = json.optString("categoria", "Outros"); String data = json.optString("data", ""); callback.onSuccess(valor, descricao, categoria, data); } else { callback.onError("Resposta vazia da IA."); } } catch (JSONException e) { Log.e("InvoiceScanner", "Erro ao fazer parse do JSON: " + result.getText(), e); callback.onError("Erro ao ler dados da fatura."); } finally { if (executor instanceof java.util.concurrent.ExecutorService) { ((java.util.concurrent.ExecutorService) executor).shutdown(); } } } @Override public void onFailure(Throwable t) { Log.e("InvoiceScanner", "Falha na API do Gemini", t); callback.onError("Falha ao comunicar com a IA: " + t.getMessage()); if (executor instanceof java.util.concurrent.ExecutorService) { ((java.util.concurrent.ExecutorService) executor).shutdown(); } } }, executor); } catch (Exception e) { Log.e("InvoiceScanner", "Erro geral", e); callback.onError("Erro ao processar imagem: " + e.getMessage()); if (executor instanceof java.util.concurrent.ExecutorService) { ((java.util.concurrent.ExecutorService) executor).shutdown(); } } } }