Compare commits

...

2 Commits

Author SHA1 Message Date
53f77a852e a acabar 2026-06-15 15:20:40 +01:00
21c1e472ba Revert "a acabar"
This reverts commit 533f164b0f.
2026-06-15 15:19:12 +01:00
6 changed files with 42 additions and 239 deletions

View File

@@ -16,24 +16,9 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import androidx.credentials.Credential;
import androidx.credentials.CustomCredential;
import androidx.credentials.GetCredentialRequest;
import androidx.credentials.GetCredentialResponse;
import androidx.credentials.exceptions.GetCredentialException;
import androidx.credentials.exceptions.NoCredentialException;
import androidx.credentials.CredentialManager;
import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException;
import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.GoogleAuthProvider;
/** /**
* CriarContaActivity é a atividade responsável por gerir o registo de novos utilizadores na aplicação LifeGrid. * CriarContaActivity é a atividade responsável por gerir o registo de novos utilizadores na aplicação LifeGrid.
@@ -47,10 +32,8 @@ public class CriarContaActivity extends AppCompatActivity {
private EditText passwordEditText3; private EditText passwordEditText3;
private EditText passwordEditText2; private EditText passwordEditText2;
private Button loginButton2; private Button loginButton2;
private Button googleButton2;
private ProgressBar loadingProgressBar; private ProgressBar loadingProgressBar;
private FirebaseAuth firebaseAuth; private FirebaseAuth firebaseAuth;
private CredentialManager credentialManager;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -68,12 +51,10 @@ public class CriarContaActivity extends AppCompatActivity {
passwordEditText3 = findViewById(R.id.passwordEditText3); passwordEditText3 = findViewById(R.id.passwordEditText3);
passwordEditText2 = findViewById(R.id.passwordEditText2); passwordEditText2 = findViewById(R.id.passwordEditText2);
loginButton2 = findViewById(R.id.loginButton2); loginButton2 = findViewById(R.id.loginButton2);
googleButton2 = findViewById(R.id.googleButton2);
loadingProgressBar = findViewById(R.id.loadingProgressBar); loadingProgressBar = findViewById(R.id.loadingProgressBar);
FirebaseApp.initializeApp(this); FirebaseApp.initializeApp(this);
firebaseAuth = FirebaseAuth.getInstance(); firebaseAuth = FirebaseAuth.getInstance();
credentialManager = CredentialManager.create(this);
// Configura o botão de registo para acionar a validação e criação de conta // Configura o botão de registo para acionar a validação e criação de conta
loginButton2.setOnClickListener(v -> criarConta()); loginButton2.setOnClickListener(v -> criarConta());
@@ -191,35 +172,9 @@ public class CriarContaActivity extends AppCompatActivity {
return true; return true;
} }
private void firebaseAuthWithGoogle(String idToken) {
AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, task -> {
toggleLoading(false);
if (task.isSuccessful()) {
FirebaseUser user = firebaseAuth.getCurrentUser();
String welcome = user != null && !TextUtils.isEmpty(user.getDisplayName())
? "Conta criada com sucesso! Bem-vindo, " + user.getDisplayName()
: "Conta criada com Google com sucesso!";
Toast.makeText(this, welcome, Toast.LENGTH_SHORT).show();
// Redirecionar para TelaInicialActivity após criação bem-sucedida
Intent intent = new Intent(CriarContaActivity.this, TelaInicialActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
} else {
Toast.makeText(this,
task.getException() != null ? task.getException().getMessage() : "Falha ao criar conta com Google",
Toast.LENGTH_LONG).show();
}
});
}
private void toggleLoading(boolean show) { private void toggleLoading(boolean show) {
loadingProgressBar.setVisibility(show ? View.VISIBLE : View.GONE); loadingProgressBar.setVisibility(show ? View.VISIBLE : View.GONE);
loginButton2.setEnabled(!show); loginButton2.setEnabled(!show);
googleButton2.setEnabled(!show);
nomeEditText.setEnabled(!show); nomeEditText.setEnabled(!show);
emailEditText2.setEnabled(!show); emailEditText2.setEnabled(!show);
passwordEditText3.setEnabled(!show); passwordEditText3.setEnabled(!show);

View File

@@ -22,28 +22,9 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import androidx.credentials.ClearCredentialStateRequest;
import androidx.credentials.CredentialManager;
import androidx.credentials.Credential;
import androidx.credentials.CredentialManagerCallback;
import androidx.credentials.CustomCredential;
import androidx.credentials.GetCredentialRequest;
import androidx.credentials.GetCredentialResponse;
import androidx.credentials.exceptions.ClearCredentialException;
import androidx.credentials.exceptions.GetCredentialException;
import androidx.credentials.exceptions.NoCredentialException;
import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
import com.google.android.libraries.identity.googleid.GoogleIdTokenParsingException;
import com.google.firebase.FirebaseApp; import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import java.util.concurrent.Executors;
/** /**
* LoginActivity é o ecrã inicial da aplicação onde o utilizador fornece as suas credenciais. * LoginActivity é o ecrã inicial da aplicação onde o utilizador fornece as suas credenciais.
@@ -61,16 +42,10 @@ public class LoginActivity extends AppCompatActivity {
private EditText passwordEditText; private EditText passwordEditText;
private TextView passesquecerTextView; private TextView passesquecerTextView;
private Button loginButton; private Button loginButton;
private Button googleButton;
private TextView ouTextView;
private ProgressBar loadingProgressBar; private ProgressBar loadingProgressBar;
private FirebaseAuth firebaseAuth; private FirebaseAuth firebaseAuth;
private CredentialManager credentialManager;
private FirebaseAuth mAuth; private FirebaseAuth mAuth;
private static final String TAG = "LoginActivity - Google Sign In";
private static final String GOOGLE_ID_TOKEN_CREDENTIAL = "1019731295596-i3q6aprqj6s55g6s97tpopbk4foutold.apps.googleusercontent.com";
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -91,17 +66,13 @@ public class LoginActivity extends AppCompatActivity {
passwordEditText = findViewById(R.id.passwordEditText); passwordEditText = findViewById(R.id.passwordEditText);
passesquecerTextView = findViewById(R.id.passesquecerTextView); passesquecerTextView = findViewById(R.id.passesquecerTextView);
loginButton = findViewById(R.id.loginButton); loginButton = findViewById(R.id.loginButton);
googleButton = findViewById(R.id.googleButton);
ouTextView = findViewById(R.id.ouTextView);
loadingProgressBar = findViewById(R.id.loadingProgressBar); loadingProgressBar = findViewById(R.id.loadingProgressBar);
FirebaseApp.initializeApp(this); FirebaseApp.initializeApp(this);
firebaseAuth = FirebaseAuth.getInstance(); firebaseAuth = FirebaseAuth.getInstance();
mAuth = FirebaseAuth.getInstance(); mAuth = FirebaseAuth.getInstance();
credentialManager = CredentialManager.create(getBaseContext());
loginButton.setOnClickListener(v -> validarLogin()); loginButton.setOnClickListener(v -> validarLogin());
googleButton.setOnClickListener(v -> launchCredentialManager());
criarContaTextView.setOnClickListener(new View.OnClickListener() { criarContaTextView.setOnClickListener(new View.OnClickListener() {
@Override @Override
@@ -111,17 +82,45 @@ public class LoginActivity extends AppCompatActivity {
} }
}); });
// Inicialmente desabilitar o TextView de recuperar palavra-passe
passesquecerTextView.setEnabled(false);
passesquecerTextView.setAlpha(0.5f); // Visualmente mais claro quando desabilitado
passesquecerTextView.setOnClickListener(new View.OnClickListener() { passesquecerTextView.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
String email = emailEditText.getText().toString().trim(); String email = emailEditText.getText().toString().trim();
Intent intent = new Intent(LoginActivity.this, RecupearPasswordActivity.class);
if (!TextUtils.isEmpty(email)) { // Validar se tem e-mail antes de abrir a atividade de recuperação
intent.putExtra("email", email); if (TextUtils.isEmpty(email)) {
emailEditText.setError("Por favor, digite o seu e-mail primeiro.");
emailEditText.requestFocus();
Toast.makeText(LoginActivity.this, "Digite o seu e-mail para recuperar a palavra-passe.", Toast.LENGTH_SHORT).show();
return;
} }
Intent intent = new Intent(LoginActivity.this, RecupearPasswordActivity.class);
intent.putExtra("email", email);
startActivity(intent); startActivity(intent);
} }
}); });
// Adicionar TextWatcher para habilitar/desabilitar o TextView dinamicamente
emailEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String email = s.toString().trim();
boolean hasEmail = !TextUtils.isEmpty(email);
passesquecerTextView.setEnabled(hasEmail);
passesquecerTextView.setAlpha(hasEmail ? 1.0f : 0.5f);
}
@Override
public void afterTextChanged(Editable s) {}
});
} }
/** /**
@@ -214,113 +213,13 @@ public class LoginActivity extends AppCompatActivity {
} }
private void firebaseAuthWithGoogle(String idToken) {
AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
firebaseAuth.signInWithCredential(credential)
.addOnCompleteListener(this, task -> {
toggleLoading(false);
if (task.isSuccessful()) {
FirebaseUser user = firebaseAuth.getCurrentUser();
String welcome = user != null && !TextUtils.isEmpty(user.getDisplayName())
? "Bem-vindo, " + user.getDisplayName()
: "Login com Google realizado com sucesso!";
Toast.makeText(this, welcome, Toast.LENGTH_SHORT).show();
// Redirecionar para TelaInicialActivity após login bem-sucedido
Intent intent = new Intent(LoginActivity.this, TelaInicialActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
} else {
Toast.makeText(this,
task.getException() != null ? task.getException().getMessage() : "Falha no login com Google",
Toast.LENGTH_LONG).show();
}
});
}
private void toggleLoading(boolean show) { private void toggleLoading(boolean show) {
loadingProgressBar.setVisibility(show ? View.VISIBLE : View.GONE); loadingProgressBar.setVisibility(show ? View.VISIBLE : View.GONE);
loginButton.setEnabled(!show); loginButton.setEnabled(!show);
googleButton.setEnabled(!show);
criarContaTextView.setEnabled(!show); criarContaTextView.setEnabled(!show);
passesquecerTextView.setEnabled(!show); passesquecerTextView.setEnabled(!show);
} }
private void launchCredentialManager() {
// [START create_credential_manager_request]
// Instancia um pedido de início de sessão do Google
GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
.setFilterByAuthorizedAccounts(false)
.setServerClientId(getString(R.string.default_web_client_id))
.build();
// Cria o pedido do Gestor de Credenciais
GetCredentialRequest request = new GetCredentialRequest.Builder()
.addCredentialOption(googleIdOption)
.build();
// [END create_credential_manager_request]
// Lança a interface do Gestor de Credenciais
credentialManager.getCredentialAsync(
LoginActivity.this,
request,
new CancellationSignal(),
androidx.core.content.ContextCompat.getMainExecutor(LoginActivity.this),
new CredentialManagerCallback<GetCredentialResponse, GetCredentialException>() {
@Override
public void onResult(GetCredentialResponse result) {
// Extrai a credencial do resultado devolvido pelo Gestor de Credenciais
handleSignIn(result.getCredential());
}
@Override
public void onError(GetCredentialException e) {
Log.e(TAG, "Couldn't retrieve user's credentials: " + e.getLocalizedMessage());
Toast.makeText(LoginActivity.this, "Falha ao abrir Google Sign In.", Toast.LENGTH_SHORT).show();
}
}
);
}
private void handleSignIn(Credential credential) {
// Verifica se a credencial é do tipo Google ID
if (credential instanceof CustomCredential customCredential
&& credential.getType().equals(GOOGLE_ID_TOKEN_CREDENTIAL)) {
// Cria o token do Google ID
Bundle credentialData = customCredential.getData();
GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credentialData);
// Inicia a sessão no Firebase usando o token
firebaseAuthWithGoogle(googleIdTokenCredential.getIdToken());
} else {
Log.w(TAG, "Credential is not of type Google ID!");
}
}
private void signOut() {
// Termina a sessão no Firebase
mAuth.signOut();
// Quando o utilizador termina a sessão, limpa o estado atual da credencial do utilizador de todos os provedores de credenciais.
ClearCredentialStateRequest clearRequest = new ClearCredentialStateRequest();
credentialManager.clearCredentialStateAsync(
clearRequest,
new CancellationSignal(),
Executors.newSingleThreadExecutor(),
new CredentialManagerCallback<>() {
@Override
public void onResult(@NonNull Void result) {
//updateUI(null);
}
@Override
public void onError(@NonNull ClearCredentialException e) {
Log.e(TAG, "Couldn't clear user credentials: " + e.getLocalizedMessage());
}
});
}
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();

View File

@@ -51,6 +51,10 @@ public class RecupearPasswordActivity extends AppCompatActivity {
String emailPassado = getIntent().getStringExtra("email"); String emailPassado = getIntent().getStringExtra("email");
if (!TextUtils.isEmpty(emailPassado)) { if (!TextUtils.isEmpty(emailPassado)) {
emailEditText4.setText(emailPassado); emailEditText4.setText(emailPassado);
// Tornar o campo não editável quando vier do login
emailEditText4.setEnabled(false);
emailEditText4.setFocusable(false);
emailEditText4.setClickable(false);
} }
loginButton3.setOnClickListener(v -> recuperarPassword()); loginButton3.setOnClickListener(v -> recuperarPassword());
@@ -91,8 +95,8 @@ public class RecupearPasswordActivity extends AppCompatActivity {
Toast.makeText(this, Toast.makeText(this,
"Email de recuperação enviado para " + email + "\nVerifique sua caixa de entrada.", "Email de recuperação enviado para " + email + "\nVerifique sua caixa de entrada.",
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG).show();
// Fechar atividade para voltar ao Login após sucesso // Limpar o campo após sucesso
finish(); emailEditText4.setText("");
} else { } else {
// Erro ao enviar email // Erro ao enviar email
String errorMessage = "Erro ao enviar email de recuperação."; String errorMessage = "Erro ao enviar email de recuperação.";

View File

@@ -119,31 +119,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passwordEditText2" /> app:layout_constraintTop_toBottomOf="@+id/passwordEditText2" />
<TextView
android:id="@+id/ouTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="22dp"
android:text="_____________________ OU _____________________"
android:textColor="@color/cinzaescuro"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginButton2" />
<Button
android:id="@+id/googleButton2"
android:layout_width="316dp"
android:layout_height="49dp"
android:layout_marginTop="14dp"
android:backgroundTint="#FFFFFF"
android:text="Continuar com o Google"
android:textColor="#0F0E0E"
app:cornerRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ouTextView2"
app:strokeColor="@color/cinza"
app:strokeWidth="1sp" />
<TextView <TextView
android:id="@+id/textView" android:id="@+id/textView"
@@ -205,6 +181,6 @@
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/googleButton2" /> app:layout_constraintTop_toBottomOf="@+id/loginButton2" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -62,33 +62,7 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/passesquecerTextView" /> app:layout_constraintTop_toBottomOf="@+id/passesquecerTextView" />
<Button
android:id="@+id/googleButton"
android:layout_width="316dp"
android:layout_height="49dp"
android:layout_marginTop="8dp"
android:backgroundTint="#FFFFFF"
android:text="Continuar com o Google"
android:textColor="#0F0E0E"
app:cornerRadius="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.483"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/loginButton"
app:strokeColor="@color/cinza"
app:strokeWidth="1sp" />
<TextView
android:id="@+id/ouTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="_____________________ OU _____________________"
android:textColor="@color/cinzaescuro"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.492"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/googleButton" />
<EditText <EditText
android:id="@+id/passwordEditText" android:id="@+id/passwordEditText"
@@ -156,7 +130,7 @@
android:textColor="#121111" android:textColor="#121111"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ouTextView" /> app:layout_constraintTop_toBottomOf="@+id/loginButton" />
<ProgressBar <ProgressBar
android:id="@+id/loadingProgressBar" android:id="@+id/loadingProgressBar"

View File

@@ -26,7 +26,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" android:layout_marginTop="40dp"
android:text="Email" android:text="Email"
android:textColor="@color/preto"
android:textSize="12sp" android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.104" app:layout_constraintHorizontal_bias="0.104"
@@ -42,9 +41,7 @@
android:ems="10" android:ems="10"
android:hint="seu@email.com" android:hint="seu@email.com"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:textColor="@color/preto" android:textSize="15dp"
android:textColorHint="@color/cinzaescuro"
android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.493" app:layout_constraintHorizontal_bias="0.493"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -67,8 +64,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:text="Recuperar password" android:text="Recuperar password"
android:textColor="@color/preto" android:textSize="26dp"
android:textSize="26sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.23" app:layout_constraintHorizontal_bias="0.23"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@@ -80,8 +76,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:text="Insira o seu email para recuperar a password" android:text="Insira o seu email para recuperar a password"
android:textColor="@color/preto" android:textSize="16dp"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.425" app:layout_constraintHorizontal_bias="0.425"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"