quero meter o gemini na app
This commit is contained in:
@@ -40,22 +40,53 @@ public class RegisterActivity extends AppCompatActivity {
|
||||
|
||||
int age = Integer.parseInt(ageStr);
|
||||
|
||||
AppDatabase db = AppDatabase.getDatabase(getApplicationContext());
|
||||
UserDao userDao = db.userDao();
|
||||
binding.registerButton.setEnabled(false);
|
||||
binding.registerButton.setText("A registar...");
|
||||
|
||||
AppDatabase.databaseWriteExecutor.execute(() -> {
|
||||
User existing = userDao.checkUser(email);
|
||||
if (existing != null) {
|
||||
runOnUiThread(() -> Toast.makeText(this, "Email já registado", Toast.LENGTH_SHORT).show());
|
||||
} else {
|
||||
User newUser = new User(name, email, password, age, utenteStr);
|
||||
userDao.insert(newUser);
|
||||
runOnUiThread(() -> {
|
||||
Toast.makeText(this, "Conta criada com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(this, LoginActivity.class));
|
||||
finish();
|
||||
com.google.firebase.auth.FirebaseAuth mAuth = com.google.firebase.auth.FirebaseAuth.getInstance();
|
||||
com.google.firebase.firestore.FirebaseFirestore db = com.google.firebase.firestore.FirebaseFirestore
|
||||
.getInstance();
|
||||
|
||||
mAuth.createUserWithEmailAndPassword(email, password)
|
||||
.addOnCompleteListener(this, task -> {
|
||||
if (task.isSuccessful()) {
|
||||
// Registration success, save additional info to Firestore
|
||||
com.google.firebase.auth.FirebaseUser firebaseUser = mAuth.getCurrentUser();
|
||||
if (firebaseUser != null) {
|
||||
String userId = firebaseUser.getUid();
|
||||
|
||||
java.util.Map<String, Object> userMap = new java.util.HashMap<>();
|
||||
userMap.put("uid", userId);
|
||||
userMap.put("name", name);
|
||||
userMap.put("email", email);
|
||||
userMap.put("age", age);
|
||||
userMap.put("utenteNumber", utenteStr);
|
||||
userMap.put("profilePictureUri", ""); // Init empty
|
||||
|
||||
db.collection("users").document(userId)
|
||||
.set(userMap)
|
||||
.addOnSuccessListener(aVoid -> {
|
||||
// Optional: Also save to local Room DB for offline cache if desired,
|
||||
// but for now we focus on Firebase as requested.
|
||||
|
||||
Toast.makeText(RegisterActivity.this, "Conta criada com sucesso!",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
|
||||
finish();
|
||||
})
|
||||
.addOnFailureListener(e -> {
|
||||
binding.registerButton.setEnabled(true);
|
||||
binding.registerButton.setText("Registar");
|
||||
Toast.makeText(RegisterActivity.this, "Erro ao salvar dados: " + e.getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
binding.registerButton.setEnabled(true);
|
||||
binding.registerButton.setText("Registar");
|
||||
Toast.makeText(RegisterActivity.this, "Falha no registo: " + task.getException().getMessage(),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
package com.example.cuida.ui.sns24;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.example.cuida.databinding.FragmentSns24Binding;
|
||||
import com.google.android.gms.location.FusedLocationProviderClient;
|
||||
import com.google.android.gms.location.LocationServices;
|
||||
|
||||
import com.google.ai.client.generativeai.GenerativeModel;
|
||||
import com.google.ai.client.generativeai.java.GenerativeModelFutures;
|
||||
import com.google.ai.client.generativeai.type.Content;
|
||||
@@ -23,110 +19,95 @@ 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 java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.example.cuida.databinding.FragmentSns24Binding;
|
||||
|
||||
public class Sns24Fragment extends Fragment {
|
||||
|
||||
private FragmentSns24Binding binding;
|
||||
private FusedLocationProviderClient fusedLocationClient;
|
||||
private GenerativeModelFutures ai; // Equivalent to 'const ai = genkit(...)'
|
||||
// API Key configurada
|
||||
private GenerativeModelFutures model;
|
||||
private static final String API_KEY = "AIzaSyBmLgn-SHaTDvAeDWsw2iTZRR9gahhOu7k";
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = FragmentSns24Binding.inflate(inflater, container, false);
|
||||
|
||||
fusedLocationClient = LocationServices.getFusedLocationProviderClient(requireActivity());
|
||||
|
||||
// Initialize Gemini (Android equivalent of Genkit gemini15Flash configuration)
|
||||
try {
|
||||
GenerativeModel gm = new GenerativeModel("gemini-1.5-flash", API_KEY);
|
||||
ai = GenerativeModelFutures.from(gm);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(getContext(), "Erro ao iniciar IA: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
binding.buttonCallSns.setOnClickListener(v -> {
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:808242424"));
|
||||
startActivity(intent);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(getContext(), "Não foi possível realizar a chamada.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
binding.buttonAiTriage.setOnClickListener(v -> performTriage());
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void performTriage() {
|
||||
if (API_KEY.equals("YOUR_API_KEY")) {
|
||||
Toast.makeText(getContext(), "Configure a API Key no ficheiro Sns24Fragment.java!", Toast.LENGTH_LONG)
|
||||
.show();
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
if (ai == null) {
|
||||
Toast.makeText(getContext(), "IA não inicializada. Verifique s Logs.", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
// 1. Inicializar o Modelo Gemini
|
||||
// NOTA: Substitua "SUA_API_KEY" pela sua chave do Google AI Studio
|
||||
GenerativeModel gm = new GenerativeModel("gemini-1.5-flash", API_KEY);
|
||||
model = GenerativeModelFutures.from(gm);
|
||||
|
||||
String symptoms = binding.inputSymptoms.getText().toString();
|
||||
if (symptoms.isEmpty()) {
|
||||
binding.inputSymptoms.setError("Por favor descreva o que sente");
|
||||
return;
|
||||
}
|
||||
// 2. Botão Ligar SNS 24
|
||||
binding.buttonCallSns.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:808242424"));
|
||||
startActivity(intent);
|
||||
});
|
||||
|
||||
// 3. Botão Triagem IA
|
||||
binding.buttonAiTriage.setOnClickListener(v -> {
|
||||
String symptoms = binding.inputSymptoms.getText().toString().trim();
|
||||
if (!symptoms.isEmpty()) {
|
||||
analyzeSymptomsWithGemini(symptoms);
|
||||
} else {
|
||||
Toast.makeText(getContext(), "Por favor, descreva os seus sintomas.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void analyzeSymptomsWithGemini(String symptoms) {
|
||||
// Feedback visual de carregamento
|
||||
binding.buttonAiTriage.setEnabled(false);
|
||||
binding.buttonAiTriage.setText("A analisar...");
|
||||
binding.textAiResult.setVisibility(View.GONE);
|
||||
binding.textAiResult.setVisibility(View.VISIBLE);
|
||||
binding.textAiResult.setText("A analisar sintomas com IA...");
|
||||
|
||||
// This prompt structure is equivalent to the flow in Genkit
|
||||
String prompt = "O utilizador está a sentir o seguinte: " + symptoms + ". " +
|
||||
"Analisa a gravidade como 'gemini-1.5-flash'. Deves recomendar uma de duas opções: 'Ir ao Hospital' ou 'Ir ao Posto Médico'. "
|
||||
+
|
||||
"Explica brevemente o porquê. Responde em Português de Portugal.";
|
||||
// Criar o prompt
|
||||
Content content = new Content.Builder()
|
||||
.addText("Atua como um assistente de triagem de saúde. O utilizador diz: \"" + symptoms + "\". " +
|
||||
"Dá uma resposta curta (máximo 4 linhas) sobre a urgência e se deve ligar para o SNS 24 (808242424). "
|
||||
+
|
||||
"Aviso: Isto não substitui aconselhamento médico.")
|
||||
.build();
|
||||
|
||||
Content content = new Content.Builder().addText(prompt).build();
|
||||
Executor executor = Executors.newSingleThreadExecutor();
|
||||
// Executar chamada assíncrona (usando Guava Futures para Java)
|
||||
ListenableFuture<GenerateContentResponse> response = model.generateContent(content);
|
||||
|
||||
// Equivalent to: const { text } = await ai.generate(...)
|
||||
ListenableFuture<GenerateContentResponse> response = ai.generateContent(content);
|
||||
// Executor para rodar a resposta na UI Thread
|
||||
// Creating a new single thread executor for the background work if needed,
|
||||
// but the callback needs to run on main thread or handle UI updates on main
|
||||
// thread.
|
||||
// We use ContextCompat.getMainExecutor to be safe on API < 28 (minSdk is 24)
|
||||
|
||||
Futures.addCallback(response, new FutureCallback<GenerateContentResponse>() {
|
||||
@Override
|
||||
public void onSuccess(GenerateContentResponse result) {
|
||||
String resultText = result.getText();
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
if (getActivity() != null) {
|
||||
binding.textAiResult.setText(result.getText());
|
||||
binding.buttonAiTriage.setEnabled(true);
|
||||
binding.buttonAiTriage.setText("Analisar Sintomas");
|
||||
binding.textAiResult.setText(resultText);
|
||||
binding.textAiResult.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
t.printStackTrace();
|
||||
requireActivity().runOnUiThread(() -> {
|
||||
if (getActivity() != null) {
|
||||
binding.textAiResult.setText("Erro ao contactar a IA: " + t.getMessage());
|
||||
binding.buttonAiTriage.setEnabled(true);
|
||||
binding.buttonAiTriage.setText("Analisar Sintomas");
|
||||
Toast.makeText(getContext(), "Erro na análise: " + t.getMessage(), Toast.LENGTH_LONG).show();
|
||||
});
|
||||
}
|
||||
}
|
||||
}, executor);
|
||||
}, androidx.core.content.ContextCompat.getMainExecutor(requireContext()));
|
||||
}
|
||||
|
||||
// AI Triage methods removed
|
||||
|
||||
// Nearest Hospital feature removed with AI Triage
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
|
||||
Reference in New Issue
Block a user