corrigir os novos erros amnhã e adicionar qual tipo de sexo a pessoa é no register
This commit is contained in:
@@ -3,7 +3,14 @@
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@@ -2,236 +2,73 @@ package com.example.pap;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Switch;
|
||||
import android.widget.Toast;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class DefinicoesActivity extends AppCompatActivity {
|
||||
|
||||
private SwitchCompat switchDarkMode;
|
||||
private Button btnEditarNome, btnMudarEmail, btnMudarPass, btnVoltarDef;
|
||||
private SharedPreferences sharedPreferences;
|
||||
private Switch switchModoEscuro;
|
||||
private EditText etNovoNome, etNovoEmail, etNovaPassword;
|
||||
private Button btnGuardarAlteracoes;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_definicoes);
|
||||
|
||||
// Iniciar a memória local do telemóvel
|
||||
sharedPreferences = getSharedPreferences("MeusDadosApp", MODE_PRIVATE);
|
||||
switchModoEscuro = findViewById(R.id.switchModoEscuro);
|
||||
etNovoNome = findViewById(R.id.etNovoNome);
|
||||
etNovoEmail = findViewById(R.id.etNovoEmail);
|
||||
etNovaPassword = findViewById(R.id.etNovaPassword);
|
||||
btnGuardarAlteracoes = findViewById(R.id.btnGuardarAlteracoes);
|
||||
|
||||
// Ligar os elementos do design ao código
|
||||
switchDarkMode = findViewById(R.id.switchDarkMode);
|
||||
btnEditarNome = findViewById(R.id.btnEditarNome);
|
||||
btnMudarEmail = findViewById(R.id.btnMudarEmail);
|
||||
btnMudarPass = findViewById(R.id.btnMudarPass);
|
||||
btnVoltarDef = findViewById(R.id.btnVoltarDef);
|
||||
findViewById(R.id.btnVoltarDefinicoes).setOnClickListener(v -> finish());
|
||||
|
||||
// 1. Lógica do Modo Escuro
|
||||
boolean isDarkMode = sharedPreferences.getBoolean("dark_mode", false);
|
||||
switchDarkMode.setChecked(isDarkMode);
|
||||
// 1. CARREGAR E CONFIGURAR O MODO ESCURO
|
||||
SharedPreferences themePrefs = getSharedPreferences("Definicoes", MODE_PRIVATE);
|
||||
boolean isDark = themePrefs.getBoolean("dark_mode", false);
|
||||
switchModoEscuro.setChecked(isDark);
|
||||
|
||||
switchModoEscuro.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
SharedPreferences.Editor editor = themePrefs.edit();
|
||||
editor.putBoolean("dark_mode", isChecked);
|
||||
editor.apply();
|
||||
|
||||
switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
if (isChecked) {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
|
||||
} else {
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
|
||||
}
|
||||
sharedPreferences.edit().putBoolean("dark_mode", isChecked).apply();
|
||||
});
|
||||
|
||||
// Configurar os cliques nos botões
|
||||
btnEditarNome.setOnClickListener(v -> mostrarPopupNome());
|
||||
btnMudarEmail.setOnClickListener(v -> mostrarPopupEmail());
|
||||
btnMudarPass.setOnClickListener(v -> mostrarPopupPassword());
|
||||
btnVoltarDef.setOnClickListener(v -> finish());
|
||||
}
|
||||
// 2. CARREGAR O NOME E EMAIL ATUAIS PARA O CAMPO DE TEXTO
|
||||
SharedPreferences dadosPrefs = getSharedPreferences("MeusDadosApp", MODE_PRIVATE);
|
||||
etNovoNome.setText(dadosPrefs.getString("nome", ""));
|
||||
etNovoEmail.setText(dadosPrefs.getString("email", ""));
|
||||
|
||||
// --- FUNÇÕES DOS POP-UPS ---
|
||||
|
||||
private void mostrarPopupNome() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Mudar Nome");
|
||||
|
||||
final EditText input = new EditText(this);
|
||||
input.setHint("Novo nome");
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("Guardar", (dialog, which) -> {
|
||||
String novoNome = input.getText().toString().trim();
|
||||
if (!novoNome.isEmpty()) {
|
||||
sharedPreferences.edit().putString("nome", novoNome).apply();
|
||||
Toast.makeText(this, "Nome atualizado com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void mostrarPopupEmail() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Alterar Email");
|
||||
|
||||
LinearLayout layout = new LinearLayout(this);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.setPadding(50, 20, 50, 0);
|
||||
|
||||
final EditText etPassAtual = new EditText(this);
|
||||
etPassAtual.setHint("A tua Password atual");
|
||||
etPassAtual.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
layout.addView(etPassAtual);
|
||||
|
||||
final EditText etNovoEmail = new EditText(this);
|
||||
etNovoEmail.setHint("Novo Email");
|
||||
layout.addView(etNovoEmail);
|
||||
|
||||
builder.setView(layout);
|
||||
builder.setPositiveButton("Alterar", (dialog, which) -> {
|
||||
String passAtual = etPassAtual.getText().toString().trim();
|
||||
// 3. GUARDAR AS ALTERAÇÕES
|
||||
btnGuardarAlteracoes.setOnClickListener(v -> {
|
||||
String novoNome = etNovoNome.getText().toString().trim();
|
||||
String novoEmail = etNovoEmail.getText().toString().trim();
|
||||
String emailAtual = sharedPreferences.getString("email", "");
|
||||
String novaPassword = etNovaPassword.getText().toString().trim();
|
||||
|
||||
if (passAtual.isEmpty() || novoEmail.isEmpty()) {
|
||||
Toast.makeText(this, "Preenche todos os campos!", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
SharedPreferences.Editor editor = dadosPrefs.edit();
|
||||
|
||||
if (!novoNome.isEmpty()) {
|
||||
editor.putString("nome", novoNome);
|
||||
}
|
||||
if (!novoEmail.isEmpty()) {
|
||||
editor.putString("email", novoEmail);
|
||||
}
|
||||
|
||||
SupabaseApi api = SupabaseConfig.getRetrofit().create(SupabaseApi.class);
|
||||
UserCredentials creds = new UserCredentials(emailAtual, passAtual);
|
||||
editor.apply();
|
||||
|
||||
// Confirma a identidade do utilizador (Mini-login)
|
||||
api.login(SupabaseConfig.SUPABASE_KEY, creds).enqueue(new Callback<SupabaseResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<SupabaseResponse> call, Response<SupabaseResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String freshToken = response.body().access_token;
|
||||
|
||||
// Envia o pedido de alteração de email para o Supabase
|
||||
Map<String, String> updates = new HashMap<>();
|
||||
updates.put("email", novoEmail);
|
||||
|
||||
api.updateUserData(SupabaseConfig.SUPABASE_KEY, "Bearer " + freshToken, updates).enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
// Apenas avisa o utilizador. O email só muda após clicar no link!
|
||||
Toast.makeText(DefinicoesActivity.this, "Link enviado! Verifica a tua nova caixa de correio para confirmar.", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(DefinicoesActivity.this, "Erro ao tentar enviar o email de confirmação.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Void> call, Throwable t) {
|
||||
Toast.makeText(DefinicoesActivity.this, "Verifica a tua ligação à internet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(DefinicoesActivity.this, "A password atual está incorreta!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<SupabaseResponse> call, Throwable t) {
|
||||
Toast.makeText(DefinicoesActivity.this, "Verifica a tua ligação à internet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
Toast.makeText(this, "Alterações guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
finish(); // Volta ao ecrã anterior
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void mostrarPopupPassword() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Alterar Password");
|
||||
|
||||
LinearLayout layout = new LinearLayout(this);
|
||||
layout.setOrientation(LinearLayout.VERTICAL);
|
||||
layout.setPadding(50, 20, 50, 0);
|
||||
|
||||
final EditText etAntiga = new EditText(this);
|
||||
etAntiga.setHint("Password Antiga");
|
||||
etAntiga.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
layout.addView(etAntiga);
|
||||
|
||||
final EditText etNova = new EditText(this);
|
||||
etNova.setHint("Nova Password (min. 6 caracteres)");
|
||||
etNova.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
layout.addView(etNova);
|
||||
|
||||
final EditText etConfirma = new EditText(this);
|
||||
etConfirma.setHint("Confirma a Nova Password");
|
||||
etConfirma.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
|
||||
layout.addView(etConfirma);
|
||||
|
||||
builder.setView(layout);
|
||||
builder.setPositiveButton("Atualizar", (dialog, which) -> {
|
||||
String pAntiga = etAntiga.getText().toString().trim();
|
||||
String pNova = etNova.getText().toString().trim();
|
||||
String pConfirma = etConfirma.getText().toString().trim();
|
||||
String emailAtual = sharedPreferences.getString("email", "");
|
||||
|
||||
if (pAntiga.isEmpty() || pNova.isEmpty() || pConfirma.isEmpty()) {
|
||||
Toast.makeText(this, "Preenche todos os campos!", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pNova.equals(pConfirma) || pNova.length() < 6) {
|
||||
Toast.makeText(this, "As novas passwords não coincidem ou são muito curtas!", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
SupabaseApi api = SupabaseConfig.getRetrofit().create(SupabaseApi.class);
|
||||
UserCredentials creds = new UserCredentials(emailAtual, pAntiga);
|
||||
|
||||
// Confirma a identidade do utilizador (Mini-login)
|
||||
api.login(SupabaseConfig.SUPABASE_KEY, creds).enqueue(new Callback<SupabaseResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<SupabaseResponse> call, Response<SupabaseResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String freshToken = response.body().access_token;
|
||||
|
||||
// Atualiza a palavra-passe no Supabase
|
||||
Map<String, String> updates = new HashMap<>();
|
||||
updates.put("password", pNova);
|
||||
|
||||
api.updateUserData(SupabaseConfig.SUPABASE_KEY, "Bearer " + freshToken, updates).enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
Toast.makeText(DefinicoesActivity.this, "Password alterada com sucesso!", Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(DefinicoesActivity.this, "Erro no servidor ao mudar password.", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Void> call, Throwable t) {
|
||||
Toast.makeText(DefinicoesActivity.this, "Verifica a tua ligação à internet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Toast.makeText(DefinicoesActivity.this, "A password antiga está incorreta!", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<SupabaseResponse> call, Throwable t) {
|
||||
Toast.makeText(DefinicoesActivity.this, "Verifica a tua ligação à internet!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,6 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
|
||||
verificarResetMeiaNoite();
|
||||
|
||||
// Launcher da Câmara
|
||||
ActivityResultLauncher<Intent> videoLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
@@ -70,7 +69,6 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
// Configurar Botões
|
||||
btnVideoAgua.setOnClickListener(v -> { desafioAtualSendoGravado = 0; abrirCamera(videoLauncher); });
|
||||
btnVideoD1.setOnClickListener(v -> { desafioAtualSendoGravado = 1; abrirCamera(videoLauncher); });
|
||||
btnVideoD2.setOnClickListener(v -> { desafioAtualSendoGravado = 2; abrirCamera(videoLauncher); });
|
||||
@@ -91,7 +89,6 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
String dataGuardada = prefs.getString("data_5_desafios", "");
|
||||
|
||||
if (!dataHoje.equals(dataGuardada)) {
|
||||
// Limpar tudo
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putString("data_5_desafios", dataHoje);
|
||||
editor.putFloat("agua_litros", 0.0f);
|
||||
@@ -99,8 +96,10 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
editor.putBoolean("d2_concluido", false);
|
||||
editor.putBoolean("d3_concluido", false);
|
||||
editor.putBoolean("d4_concluido", false);
|
||||
// Zera a água para as estatísticas
|
||||
|
||||
// Zera a água e as calorias dos desafios diários
|
||||
editor.putInt("agua_hoje", 0);
|
||||
editor.putInt("calorias_desafios", 0);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@@ -122,10 +121,10 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
private void atualizarTextoDesafio(TextView tv, boolean concluido) {
|
||||
if (concluido) {
|
||||
tv.setText("Estado: Concluído ✅");
|
||||
tv.setTextColor(Color.parseColor("#10B981")); // Verde
|
||||
tv.setTextColor(Color.parseColor("#10B981"));
|
||||
} else {
|
||||
tv.setText("Estado: Pendente");
|
||||
tv.setTextColor(Color.parseColor("#EF4444")); // Vermelho
|
||||
tv.setTextColor(Color.parseColor("#EF4444"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +177,6 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
SharedPreferences prefs = getSharedPreferences("DadosGamificacao", MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
|
||||
// Dar pontos no perfil
|
||||
SharedPreferences perfilPrefs = getSharedPreferences("MeusDadosApp", MODE_PRIVATE);
|
||||
SharedPreferences.Editor perfilEditor = perfilPrefs.edit();
|
||||
|
||||
@@ -191,7 +189,7 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
litrosAgua += lido;
|
||||
|
||||
editor.putFloat("agua_litros", litrosAgua);
|
||||
editor.putInt("agua_hoje", (int) (litrosAgua / 0.25f)); // Atualiza Estatísticas
|
||||
editor.putInt("agua_hoje", (int) (litrosAgua / 0.25f));
|
||||
|
||||
tvStatusGeralIA.setText("IA leu: +" + lido + " Litros!");
|
||||
} catch (Exception e) {
|
||||
@@ -200,12 +198,18 @@ public class DesafiosActivity extends AppCompatActivity {
|
||||
}
|
||||
} else {
|
||||
if (texto.contains("Status: Concluido")) {
|
||||
tvStatusGeralIA.setText("IA: Desafio Validado! ✅ +50 Pontos");
|
||||
|
||||
if (desafioAtualSendoGravado == 1) editor.putBoolean("d1_concluido", true);
|
||||
if (desafioAtualSendoGravado == 2) editor.putBoolean("d2_concluido", true);
|
||||
if (desafioAtualSendoGravado == 3) editor.putBoolean("d3_concluido", true);
|
||||
if (desafioAtualSendoGravado == 4) editor.putBoolean("d4_concluido", true);
|
||||
int caloriasAQueimar = 0;
|
||||
if (desafioAtualSendoGravado == 1) { editor.putBoolean("d1_concluido", true); caloriasAQueimar = 2; }
|
||||
if (desafioAtualSendoGravado == 2) { editor.putBoolean("d2_concluido", true); caloriasAQueimar = 2; }
|
||||
if (desafioAtualSendoGravado == 3) { editor.putBoolean("d3_concluido", true); caloriasAQueimar = 2; }
|
||||
if (desafioAtualSendoGravado == 4) { editor.putBoolean("d4_concluido", true); caloriasAQueimar = 3; }
|
||||
|
||||
// Soma as calorias queimadas e atualiza a pontuação
|
||||
int caloriasTotaisQueimadas = prefs.getInt("calorias_desafios", 0) + caloriasAQueimar;
|
||||
editor.putInt("calorias_desafios", caloriasTotaisQueimadas);
|
||||
|
||||
tvStatusGeralIA.setText("IA: Desafio Validado! ✅ +50 Pontos | 🔥 +" + caloriasAQueimar + " kcal");
|
||||
|
||||
perfilEditor.putInt("pontos", perfilPrefs.getInt("pontos", 0) + 50);
|
||||
perfilEditor.putInt("desafios_concluidos", perfilPrefs.getInt("desafios_concluidos", 0) + 1);
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.Locale;
|
||||
|
||||
public class EstatisticasActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvValorIMC, tvStatusIMC, tvCaloriasMeta;
|
||||
private TextView tvValorIMC, tvStatusIMC, tvCaloriasMeta, tvDicaIA, tvCaloriasQueimadas;
|
||||
private TextView tvProtGramas, tvHidrGramas, tvGordGramas, tvComida1;
|
||||
private TextView tvAguaStats;
|
||||
private ProgressBar progressProt, progressHidr, progressGord;
|
||||
@@ -21,11 +21,13 @@ public class EstatisticasActivity extends AppCompatActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_estatisticas);
|
||||
|
||||
// Ligar o layout (XML) às variáveis do Java
|
||||
tvValorIMC = findViewById(R.id.tvValorIMC);
|
||||
tvStatusIMC = findViewById(R.id.tvStatusIMC);
|
||||
tvCaloriasMeta = findViewById(R.id.tvCaloriasMeta);
|
||||
|
||||
tvDicaIA = findViewById(R.id.tvDicaIA);
|
||||
tvCaloriasQueimadas = findViewById(R.id.tvCaloriasQueimadas);
|
||||
|
||||
tvProtGramas = findViewById(R.id.tvProtGramas);
|
||||
tvHidrGramas = findViewById(R.id.tvHidrGramas);
|
||||
tvGordGramas = findViewById(R.id.tvGordGramas);
|
||||
@@ -37,14 +39,13 @@ public class EstatisticasActivity extends AppCompatActivity {
|
||||
progressHidr = findViewById(R.id.progressHidr);
|
||||
progressGord = findViewById(R.id.progressGord);
|
||||
|
||||
// Botão voltar
|
||||
findViewById(R.id.btnVoltarStats).setOnClickListener(v -> finish());
|
||||
|
||||
// Chamar as funções que preenchem os dados
|
||||
calcularIMC();
|
||||
calcularTMB();
|
||||
carregarMacrosDaIA();
|
||||
carregarAgua();
|
||||
carregarCaloriasQueimadas();
|
||||
}
|
||||
|
||||
private void calcularIMC() {
|
||||
@@ -80,24 +81,19 @@ public class EstatisticasActivity extends AppCompatActivity {
|
||||
float peso = prefs.getFloat("peso", 0);
|
||||
float alturaMetros = prefs.getFloat("altura", 0);
|
||||
String sexo = prefs.getString("sexo", "");
|
||||
|
||||
// Puxa a idade real. Se der erro ou não existir, assume 20.
|
||||
int idade = prefs.getInt("idade", 20);
|
||||
|
||||
if (peso > 0 && alturaMetros > 0 && !sexo.isEmpty()) {
|
||||
float alturaCm = alturaMetros * 100; // Passar para centímetros
|
||||
float alturaCm = alturaMetros * 100;
|
||||
double tmb;
|
||||
|
||||
// Fórmula de Harris-Benedict
|
||||
if (sexo.equals("Masculino")) {
|
||||
tmb = (10 * peso) + (6.25 * alturaCm) - (5 * idade) + 5;
|
||||
} else {
|
||||
tmb = (10 * peso) + (6.25 * alturaCm) - (5 * idade) - 161;
|
||||
}
|
||||
|
||||
// Fator de atividade leve para dar uma meta real (1.2)
|
||||
double caloriasTotais = tmb * 1.2;
|
||||
|
||||
tvCaloriasMeta.setText(String.valueOf((int) caloriasTotais));
|
||||
} else {
|
||||
tvCaloriasMeta.setText("--");
|
||||
@@ -112,6 +108,10 @@ public class EstatisticasActivity extends AppCompatActivity {
|
||||
int gord = prefs.getInt("gord_hoje", 0);
|
||||
String ultimaComida = prefs.getString("ultimo_prato", "Ainda não leste nada hoje.");
|
||||
|
||||
// Puxa a dica extraída da foto!
|
||||
String dicaIa = prefs.getString("ultima_dica_ia", "Continua a registar as tuas refeições para ver dicas.");
|
||||
tvDicaIA.setText(dicaIa);
|
||||
|
||||
tvProtGramas.setText("Proteína: " + prot + "g");
|
||||
tvHidrGramas.setText("Hidratos: " + hidr + "g");
|
||||
tvGordGramas.setText("Gordura: " + gord + "g");
|
||||
@@ -126,9 +126,13 @@ public class EstatisticasActivity extends AppCompatActivity {
|
||||
private void carregarAgua() {
|
||||
SharedPreferences prefs = getSharedPreferences("DadosGamificacao", MODE_PRIVATE);
|
||||
int coposBebidos = prefs.getInt("agua_hoje", 0);
|
||||
|
||||
float litrosTotais = coposBebidos * 0.25f;
|
||||
|
||||
tvAguaStats.setText(String.format(Locale.getDefault(), "💧 %.2f L", litrosTotais));
|
||||
}
|
||||
|
||||
private void carregarCaloriasQueimadas() {
|
||||
SharedPreferences prefs = getSharedPreferences("DadosGamificacao", MODE_PRIVATE);
|
||||
int kcalQueimadas = prefs.getInt("calorias_desafios", 0);
|
||||
tvCaloriasQueimadas.setText(kcalQueimadas + " kcal");
|
||||
}
|
||||
}
|
||||
@@ -158,28 +158,31 @@ public class FotoActivity extends AppCompatActivity {
|
||||
});
|
||||
}
|
||||
|
||||
// Função que "lê" a resposta da IA e guarda os números
|
||||
// Função que "lê" a resposta da IA e guarda os números E A DICA
|
||||
private void extrairEGuardarDados(String texto) {
|
||||
try {
|
||||
// Apanhar o Nome do prato (tudo o que está a seguir a "Prato: " até à próxima linha)
|
||||
int indexNomeStart = texto.indexOf("Prato: ") + 7;
|
||||
int indexNomeEnd = texto.indexOf("\n", indexNomeStart);
|
||||
String nomePrato = texto.substring(indexNomeStart, indexNomeEnd).trim();
|
||||
|
||||
// Apanhar os números
|
||||
int calorias = extrairNumero(texto, "Calorias: ", " kcal");
|
||||
int proteina = extrairNumero(texto, "Macros: ", "g Proteína");
|
||||
int hidratos = extrairNumero(texto, "Proteína, ", "g Hidratos");
|
||||
int gordura = extrairNumero(texto, "Hidratos, ", "g Gordura");
|
||||
|
||||
// Abrir a memória
|
||||
// EXTRAIR A DICA DA IA
|
||||
String dicaIA = "Continua a registar refeições para ver dicas.";
|
||||
if (texto.contains("Dica: ")) {
|
||||
int indexDica = texto.indexOf("Dica: ") + 6;
|
||||
dicaIA = texto.substring(indexDica).trim();
|
||||
}
|
||||
|
||||
SharedPreferences prefs = getSharedPreferences("DadosSaude", MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = prefs.edit();
|
||||
|
||||
// Guardar nome do último prato
|
||||
editor.putString("ultimo_prato", nomePrato);
|
||||
editor.putString("ultima_dica_ia", dicaIA); // Guarda a dica
|
||||
|
||||
// Somar aos valores do dia
|
||||
editor.putInt("cal_hoje", prefs.getInt("cal_hoje", 0) + calorias);
|
||||
editor.putInt("prot_hoje", prefs.getInt("prot_hoje", 0) + proteina);
|
||||
editor.putInt("hidr_hoje", prefs.getInt("hidr_hoje", 0) + hidratos);
|
||||
@@ -191,17 +194,15 @@ public class FotoActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
// Ferramenta que corta a fatia certa de texto para tirar os números
|
||||
private int extrairNumero(String texto, String inicio, String fim) {
|
||||
try {
|
||||
int start = texto.indexOf(inicio) + inicio.length();
|
||||
int end = texto.indexOf(fim, start);
|
||||
String valorString = texto.substring(start, end).trim();
|
||||
// Limpa tudo o que não for número (caso a IA escreva mal)
|
||||
valorString = valorString.replaceAll("[^0-9]", "");
|
||||
return Integer.parseInt(valorString);
|
||||
} catch (Exception e) {
|
||||
return 0; // Se não encontrar, assume 0
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,62 +4,65 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="#F8FAFC">
|
||||
android:background="?android:attr/colorBackground"
|
||||
android:padding="24dp">
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="20dp"
|
||||
android:background="#FFFFFF"
|
||||
android:elevation="4dp">
|
||||
android:layout_marginBottom="24dp">
|
||||
<TextView
|
||||
android:id="@+id/btnVoltarDefinicoes"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Voltar"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#8E8E93"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="8dp"/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Definições"
|
||||
android:textSize="22sp"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#0F172A"/>
|
||||
</LinearLayout>
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:layout_centerInParent="true" />
|
||||
</RelativeLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="16dp">
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="APARÊNCIA"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#64748B"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginStart="8dp"/>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="12dp"
|
||||
android:layout_marginBottom="24dp">
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="#F2F2F7">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:orientation="horizontal"
|
||||
android:padding="20dp"
|
||||
android:gravity="center_vertical">
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Modo Escuro"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#0F172A"/>
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/switchDarkMode"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#1C1C1E"/>
|
||||
<Switch
|
||||
android:id="@+id/switchModoEscuro"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
@@ -68,58 +71,65 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="CONTA E SEGURANÇA"
|
||||
android:textSize="12sp"
|
||||
android:text="Dados da Conta"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#8E8E93"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#64748B"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginStart="8dp"/>
|
||||
android:layout_marginBottom="12dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnEditarNome"
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Mudar Nome"
|
||||
android:backgroundTint="#FFFFFF"
|
||||
android:textColor="#0F172A"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cornerRadius="12dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="16dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMudarEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Alterar Email"
|
||||
android:backgroundTint="#FFFFFF"
|
||||
android:textColor="#0F172A"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cornerRadius="12dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="16dp"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnMudarPass"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Alterar Palavra-Passe"
|
||||
android:backgroundTint="#FFFFFF"
|
||||
android:textColor="#0F172A"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
app:cornerRadius="12dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="16dp"/>
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="#F2F2F7">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNovoNome"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Novo Nome"
|
||||
android:background="@android:color/transparent"
|
||||
android:inputType="textPersonName"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#E5E5EA" android:layout_marginBottom="8dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNovoEmail"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Novo Email"
|
||||
android:background="@android:color/transparent"
|
||||
android:inputType="textEmailAddress"
|
||||
android:layout_marginBottom="8dp"/>
|
||||
<View android:layout_width="match_parent" android:layout_height="1dp" android:background="#E5E5EA" android:layout_marginBottom="8dp"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etNovaPassword"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:hint="Nova Password"
|
||||
android:background="@android:color/transparent"
|
||||
android:inputType="textPassword"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnVoltarDef"
|
||||
android:id="@+id/btnGuardarAlteracoes"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="55dp"
|
||||
android:text="Voltar"
|
||||
android:backgroundTint="#E2E8F0"
|
||||
android:textColor="#0F172A"
|
||||
app:cornerRadius="12dp"/>
|
||||
|
||||
android:layout_height="60dp"
|
||||
android:text="Guardar Alterações"
|
||||
android:backgroundTint="#03A9F4"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:cornerRadius="16dp"/>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
@@ -56,7 +56,7 @@
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="✨" android:textSize="24sp" android:layout_marginEnd="12dp"/>
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Insight da IA" android:textSize="12sp" android:textStyle="bold" android:textColor="#0284C7"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Continua a registar as tuas refeições para ver dicas." android:textSize="14sp" android:textColor="#334155" android:layout_marginTop="2dp"/>
|
||||
<TextView android:id="@+id/tvDicaIA" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Continua a registar as tuas refeições para ver dicas." android:textSize="14sp" android:textColor="#334155" android:layout_marginTop="2dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -147,11 +147,11 @@
|
||||
android:layout_marginStart="8dp"
|
||||
app:cardCornerRadius="20dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="#F2F2F7">
|
||||
app:cardBackgroundColor="#FEF2F2">
|
||||
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="16dp" android:gravity="center">
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="👟" android:textSize="20sp"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" android:textSize="18sp" android:textStyle="bold" android:textColor="#1C1C1E" android:layout_marginTop="4dp"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Passos" android:textSize="12sp" android:textColor="#8E8E93"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="🔥" android:textSize="20sp"/>
|
||||
<TextView android:id="@+id/tvCaloriasQueimadas" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0 kcal" android:textSize="18sp" android:textStyle="bold" android:textColor="#1C1C1E" android:layout_marginTop="4dp"/>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Desafios" android:textSize="12sp" android:textColor="#8E8E93"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:cardCornerRadius="24dp"
|
||||
app:cardElevation="0dp"
|
||||
app:cardBackgroundColor="#1C1C1E">
|
||||
app:cardBackgroundColor="#000000">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
Reference in New Issue
Block a user