corrige o erro da camera e da ia não funcionar e mudar o layout futuramente
This commit is contained in:
@@ -1,168 +1,87 @@
|
||||
package com.example.pap;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import org.json.JSONArray;
|
||||
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;
|
||||
import java.util.Collections;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class ChatActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvChatLog;
|
||||
private EditText etMensagem;
|
||||
private ImageButton btnEnviar;
|
||||
private LinearLayout chatLayout;
|
||||
private ScrollView chatScrollView;
|
||||
private Button btnEnviar;
|
||||
private TextView btnVoltarChat;
|
||||
|
||||
// A TUA CHAVE DA GOOGLE VEM PARA AQUI!
|
||||
private static final String GEMINI_API_KEY = "AQ.Ab8RN6IfhsFBO3UOpK3vYd7BrR2nfFb-mVE--nvqRnR46hB36A";
|
||||
|
||||
// O motor do Gemini 1.5 Flash
|
||||
private static final String GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=" + GEMINI_API_KEY;
|
||||
|
||||
private OkHttpClient client;
|
||||
// NÃO TE ESQUEÇAS DE COLAR A TUA CHAVE AQUI!
|
||||
private final String MINHA_API_KEY = "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";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_chat);
|
||||
|
||||
tvChatLog = findViewById(R.id.tvChatLog);
|
||||
etMensagem = findViewById(R.id.etMensagem);
|
||||
btnEnviar = findViewById(R.id.btnEnviar);
|
||||
chatLayout = findViewById(R.id.chatLayout);
|
||||
chatScrollView = findViewById(R.id.chatScrollView);
|
||||
btnEnviar = findViewById(R.id.btnEnviarChat);
|
||||
btnVoltarChat = findViewById(R.id.btnVoltarChat);
|
||||
|
||||
client = new OkHttpClient();
|
||||
// --- LÓGICA DO BOTÃO VOLTAR PARA O HOME ---
|
||||
btnVoltarChat.setOnClickListener(v -> {
|
||||
// Cria a intenção de ir para a MainActivity (Home)
|
||||
Intent intent = new Intent(ChatActivity.this, HomeActivity.class);
|
||||
// Esta linha garante que não ficas com mil ecrãs abertos uns por cima dos outros
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
startActivity(intent);
|
||||
finish(); // Fecha o Chat
|
||||
});
|
||||
|
||||
// Dá as boas vindas
|
||||
adicionarBalaoNoEcra("Olá! Sou o NutriChat AI 🤖. O que comeste hoje ou que dúvidas tens sobre a tua dieta?", false);
|
||||
// Receber a análise da foto se existir
|
||||
String analiseComida = getIntent().getStringExtra("analise_comida");
|
||||
if (analiseComida != null && !analiseComida.isEmpty()) {
|
||||
tvChatLog.setText("IA: Analisei o teu prato.\n" + analiseComida + "\n\nO que queres saber mais?");
|
||||
}
|
||||
|
||||
btnEnviar.setOnClickListener(v -> {
|
||||
String pergunta = etMensagem.getText().toString().trim();
|
||||
if (pergunta.isEmpty()) {
|
||||
Toast.makeText(this, "Escreve alguma merda primeiro!", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
String pergunta = etMensagem.getText().toString();
|
||||
if (!pergunta.isEmpty()) {
|
||||
tvChatLog.append("\n\nTu: " + pergunta);
|
||||
etMensagem.setText("");
|
||||
perguntarIA(pergunta);
|
||||
}
|
||||
|
||||
// 1. Mostrar a mensagem do utilizador no ecrã
|
||||
adicionarBalaoNoEcra(pergunta, true);
|
||||
etMensagem.setText(""); // Limpa a caixa de texto
|
||||
|
||||
// 2. Chamar a Inteligência Artificial
|
||||
chamarGemini(pergunta);
|
||||
});
|
||||
}
|
||||
|
||||
// Função que desenha os balões de conversa no ecrã
|
||||
private void adicionarBalaoNoEcra(String texto, boolean isUser) {
|
||||
runOnUiThread(() -> {
|
||||
TextView tv = new TextView(this);
|
||||
tv.setText(texto);
|
||||
tv.setTextSize(16f);
|
||||
tv.setPadding(30, 20, 30, 20);
|
||||
tv.setTextColor(isUser ? Color.WHITE : Color.parseColor("#1E293B"));
|
||||
private void perguntarIA(String texto) {
|
||||
tvChatLog.append("\n\nIA: A pensar... ⏳");
|
||||
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.setMargins(0, 10, 0, 10);
|
||||
AiRequest request = new AiRequest(java.util.Arrays.asList(
|
||||
new Message("system", Collections.singletonList(new ContentPart("text", "És um nutricionista de Portugal. Responde SEMPRE de forma muito curta (máximo 2 frases). Nunca uses asteriscos."))),
|
||||
new Message("user", Collections.singletonList(new ContentPart("text", texto)))
|
||||
));
|
||||
|
||||
// Se for o utilizador, o balão vai para a direita e fica azul
|
||||
if (isUser) {
|
||||
params.gravity = Gravity.END;
|
||||
tv.setBackgroundResource(R.drawable.balao_user); // Já vamos criar isto!
|
||||
} else {
|
||||
// Se for a IA, o balão vai para a esquerda e fica branco/cinza
|
||||
params.gravity = Gravity.START;
|
||||
tv.setBackgroundResource(R.drawable.balao_ai); // Já vamos criar isto!
|
||||
}
|
||||
|
||||
tv.setLayoutParams(params);
|
||||
chatLayout.addView(tv);
|
||||
|
||||
// Faz scroll automático para o fundo para ver a mensagem nova
|
||||
chatScrollView.post(() -> chatScrollView.fullScroll(ScrollView.FOCUS_DOWN));
|
||||
});
|
||||
}
|
||||
|
||||
// Função que vai à internet falar com o cérebro da Google
|
||||
private void chamarGemini(String pergunta) {
|
||||
try {
|
||||
// Instrução secreta para ele agir como Nutricionista
|
||||
String promptCompleto = "Aja como um nutricionista simpático e profissional. Responda de forma curta e direta à seguinte mensagem do utilizador: " + pergunta;
|
||||
|
||||
// Construir o JSON que o Gemini exige
|
||||
JSONObject part = new JSONObject();
|
||||
part.put("text", promptCompleto);
|
||||
JSONArray parts = new JSONArray();
|
||||
parts.put(part);
|
||||
JSONObject content = new JSONObject();
|
||||
content.put("parts", parts);
|
||||
JSONArray contents = new JSONArray();
|
||||
contents.put(content);
|
||||
JSONObject jsonBody = new JSONObject();
|
||||
jsonBody.put("contents", contents);
|
||||
|
||||
RequestBody body = RequestBody.create(jsonBody.toString(), MediaType.get("application/json; charset=utf-8"));
|
||||
Request request = new Request.Builder()
|
||||
.url(GEMINI_URL)
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
// Fazer a chamada fora da Thread principal para a app não encravar
|
||||
client.newCall(request).enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
adicionarBalaoNoEcra("Oops! Fiquei sem internet ou deu merda na ligação. 🔌", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
if (response.isSuccessful()) {
|
||||
try {
|
||||
String respostaJSON = response.body().string();
|
||||
JSONObject jsonObject = new JSONObject(respostaJSON);
|
||||
// Escarafunchar o JSON para tirar só o texto da resposta
|
||||
String respostaIA = jsonObject.getJSONArray("candidates")
|
||||
.getJSONObject(0)
|
||||
.getJSONObject("content")
|
||||
.getJSONArray("parts")
|
||||
.getJSONObject(0)
|
||||
.getString("text");
|
||||
|
||||
// Mostrar a resposta no ecrã
|
||||
adicionarBalaoNoEcra(respostaIA, false);
|
||||
|
||||
} catch (Exception e) {
|
||||
adicionarBalaoNoEcra("Deu um nó no meu cérebro ao ler os dados. 🤯", false);
|
||||
AiConfig.getRetrofit().create(AiApi.class)
|
||||
.analisarImagem("Bearer " + MINHA_API_KEY, request)
|
||||
.enqueue(new Callback<AiResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<AiResponse> call, Response<AiResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String resposta = response.body().choices.get(0).message.content;
|
||||
String limpa = resposta.replace("**", "").replace("*", "");
|
||||
String atual = tvChatLog.getText().toString();
|
||||
tvChatLog.setText(atual.replace("IA: A pensar... ⏳", "IA: " + limpa));
|
||||
}
|
||||
} else {
|
||||
adicionarBalaoNoEcra("Erro da Google: " + response.code(), false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<AiResponse> call, Throwable t) {
|
||||
String atual = tvChatLog.getText().toString();
|
||||
tvChatLog.setText(atual.replace("IA: A pensar... ⏳", "IA: Erro de rede."));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user