alteracoes precisas na app
This commit is contained in:
@@ -46,6 +46,18 @@ public class MainActivity extends AppCompatActivity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Carregar preferência do Dark Mode
|
||||
android.content.SharedPreferences prefs = getSharedPreferences("SettingsPrefs",
|
||||
android.content.Context.MODE_PRIVATE);
|
||||
boolean isDarkMode = prefs.getBoolean("dark_mode", false);
|
||||
if (isDarkMode) {
|
||||
androidx.appcompat.app.AppCompatDelegate
|
||||
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES);
|
||||
} else {
|
||||
androidx.appcompat.app.AppCompatDelegate
|
||||
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO);
|
||||
}
|
||||
|
||||
binding = ActivityMainBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
|
||||
@@ -155,37 +167,7 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
|
||||
private void showChangeProfilePhotoDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Alterar Foto de Perfil");
|
||||
String[] options = { "Escolher da Galeria", "Inserir URL" };
|
||||
builder.setItems(options, (dialog, which) -> {
|
||||
if (which == 0) {
|
||||
mGetContent.launch("image/*");
|
||||
} else {
|
||||
showUrlDialog();
|
||||
}
|
||||
});
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void showUrlDialog() {
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle("Inserir URL da Imagem");
|
||||
|
||||
final EditText input = new EditText(this);
|
||||
input.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
|
||||
input.setHint("https://exemplo.com/foto.jpg");
|
||||
builder.setView(input);
|
||||
|
||||
builder.setPositiveButton("OK", (dialog, which) -> {
|
||||
String url = input.getText().toString();
|
||||
if (!url.isEmpty()) {
|
||||
updateUserProfile(Uri.parse(url));
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("Cancelar", (dialog, which) -> dialog.cancel());
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
private void uploadImageToStorage(Uri imageUri) {
|
||||
|
||||
@@ -46,10 +46,8 @@ public class ContaActivity extends AppCompatActivity {
|
||||
|
||||
private ImageView imageProfile;
|
||||
private TextInputEditText editName;
|
||||
private TextInputEditText editImageUrl;
|
||||
private TextView textEmail;
|
||||
private Button btnSaveAll;
|
||||
private Button btnLoadImageUrl;
|
||||
private Button btnChangeEmail;
|
||||
private Button btnChangePassword;
|
||||
private Button btnLogout;
|
||||
@@ -64,7 +62,6 @@ public class ContaActivity extends AppCompatActivity {
|
||||
private ActivityResultLauncher<Intent> imagePickerLauncher;
|
||||
private ActivityResultLauncher<String> permissionLauncher;
|
||||
private Uri selectedImageUri;
|
||||
private String imageUrlFromGoogle;
|
||||
|
||||
private static final String PREFS_NAME = "LoginPrefs";
|
||||
|
||||
@@ -98,13 +95,10 @@ public class ContaActivity extends AppCompatActivity {
|
||||
|
||||
imageProfile = findViewById(R.id.imageProfile);
|
||||
editName = findViewById(R.id.editName);
|
||||
editImageUrl = findViewById(R.id.editImageUrl);
|
||||
// textEmail removed from class fields if not used, or kept if used.
|
||||
// In XML it is present as @+id/textEmail inside cardSecurity.
|
||||
textEmail = findViewById(R.id.textEmail);
|
||||
|
||||
btnSaveAll = findViewById(R.id.btnSaveAll);
|
||||
btnLoadImageUrl = findViewById(R.id.btnLoadImageUrl);
|
||||
btnChangeEmail = findViewById(R.id.btnChangeEmail);
|
||||
btnChangePassword = findViewById(R.id.btnChangePassword);
|
||||
btnLogout = findViewById(R.id.btnLogout);
|
||||
@@ -146,7 +140,7 @@ public class ContaActivity extends AppCompatActivity {
|
||||
inputStream.close();
|
||||
if (bitmap != null) {
|
||||
imageProfile.setImageBitmap(bitmap);
|
||||
uploadProfileImage();
|
||||
// Não fazemos upload até clicar em Gravar
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao carregar imagem", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
@@ -250,9 +244,6 @@ public class ContaActivity extends AppCompatActivity {
|
||||
if (btnSaveAll != null) {
|
||||
btnSaveAll.setOnClickListener(v -> saveAllChanges());
|
||||
}
|
||||
if (btnLoadImageUrl != null) {
|
||||
btnLoadImageUrl.setOnClickListener(v -> loadImageFromUrl());
|
||||
}
|
||||
if (btnChangeEmail != null) {
|
||||
btnChangeEmail.setOnClickListener(v -> sendEmailVerificationForEmailChange());
|
||||
}
|
||||
@@ -279,100 +270,57 @@ public class ContaActivity extends AppCompatActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void loadImageFromUrl() {
|
||||
if (editImageUrl == null)
|
||||
private void saveAllChanges() {
|
||||
if (editName == null)
|
||||
return;
|
||||
|
||||
String imageUrl = editImageUrl.getText().toString().trim();
|
||||
String newName = editName.getText().toString().trim();
|
||||
|
||||
if (imageUrl.isEmpty()) {
|
||||
Toast.makeText(this, "Por favor, insira uma URL válida", Toast.LENGTH_SHORT).show();
|
||||
if (newName.isEmpty() && selectedImageUri == null) {
|
||||
Toast.makeText(this, "Nenhuma alteração a guardar", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!imageUrl.startsWith("http://") && !imageUrl.startsWith("https://")) {
|
||||
Toast.makeText(this, "URL inválida. Deve começar com http:// ou https://", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog.show();
|
||||
|
||||
// Carregar imagem da URL
|
||||
new Thread(() -> {
|
||||
try {
|
||||
java.net.URL url = new java.net.URL(imageUrl);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
connection.setDoInput(true);
|
||||
connection.connect();
|
||||
InputStream input = connection.getInputStream();
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(input);
|
||||
|
||||
runOnUiThread(() -> {
|
||||
progressDialog.dismiss();
|
||||
if (bitmap != null && imageProfile != null) {
|
||||
imageProfile.setImageBitmap(bitmap);
|
||||
// Guardar URL para usar diretamente no perfil
|
||||
imageUrlFromGoogle = imageUrl;
|
||||
// Atualizar perfil com a URL diretamente
|
||||
updateProfileWithImageUrl(imageUrl);
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao carregar imagem da URL", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
|
||||
if (input != null) {
|
||||
input.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
runOnUiThread(() -> {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao carregar imagem: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void updateProfileWithImageUrl(String imageUrl) {
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user == null)
|
||||
if (user == null) {
|
||||
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog.show();
|
||||
|
||||
try {
|
||||
Uri imageUri = Uri.parse(imageUrl);
|
||||
// Se tiver foto nova, primeiro faz upload
|
||||
if (selectedImageUri != null) {
|
||||
uploadNewProfileImageAndSaveName(user, newName);
|
||||
} else {
|
||||
// Só muda o nome
|
||||
saveNameOnly(user, newName);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveNameOnly(FirebaseUser user, String newName) {
|
||||
if (newName.isEmpty()) {
|
||||
progressDialog.dismiss();
|
||||
return; // Se não houver nome para trocar nem imagem, já barrámos em saveAllChanges.
|
||||
}
|
||||
|
||||
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
|
||||
.setPhotoUri(imageUri)
|
||||
.setDisplayName(newName)
|
||||
.build();
|
||||
|
||||
user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
|
||||
progressDialog.dismiss();
|
||||
if (task.isSuccessful()) {
|
||||
Toast.makeText(this, "Foto de perfil atualizada com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
editImageUrl.setText("");
|
||||
loadProfileImage(imageUrl);
|
||||
Toast.makeText(this, "Alterações guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao atualizar foto: " +
|
||||
Toast.makeText(this, "Erro ao guardar alterações: " +
|
||||
(task.getException() != null ? task.getException().getMessage() : "Erro desconhecido"),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao processar URL: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadProfileImage() {
|
||||
if (selectedImageUri == null)
|
||||
return;
|
||||
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user == null)
|
||||
return;
|
||||
|
||||
progressDialog.show();
|
||||
|
||||
private void uploadNewProfileImageAndSaveName(FirebaseUser user, String newName) {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = getContentResolver().openInputStream(selectedImageUri);
|
||||
@@ -389,7 +337,7 @@ public class ContaActivity extends AppCompatActivity {
|
||||
return;
|
||||
}
|
||||
|
||||
// Redimensionar se muito grande
|
||||
// Redimensionar
|
||||
int maxSize = 1024;
|
||||
if (bitmap.getWidth() > maxSize || bitmap.getHeight() > maxSize) {
|
||||
float scale = Math.min((float) maxSize / bitmap.getWidth(), (float) maxSize / bitmap.getHeight());
|
||||
@@ -402,31 +350,32 @@ public class ContaActivity extends AppCompatActivity {
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
|
||||
byte[] imageData = baos.toByteArray();
|
||||
|
||||
// Upload para Firebase Storage
|
||||
StorageReference profileImageRef = storageRef.child("profile_images/" + user.getUid() + ".jpg");
|
||||
UploadTask uploadTask = profileImageRef.putBytes(imageData);
|
||||
|
||||
uploadTask.addOnSuccessListener(taskSnapshot -> {
|
||||
profileImageRef.getDownloadUrl().addOnSuccessListener(uri -> {
|
||||
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
|
||||
.setPhotoUri(uri)
|
||||
.build();
|
||||
|
||||
UserProfileChangeRequest.Builder builder = new UserProfileChangeRequest.Builder();
|
||||
builder.setPhotoUri(uri);
|
||||
if (!newName.isEmpty()) {
|
||||
builder.setDisplayName(newName);
|
||||
}
|
||||
UserProfileChangeRequest profileUpdates = builder.build();
|
||||
|
||||
user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
|
||||
progressDialog.dismiss();
|
||||
if (task.isSuccessful()) {
|
||||
Toast.makeText(this, "Foto de perfil atualizada com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, "As definições foram guardadas!", Toast.LENGTH_SHORT).show();
|
||||
loadProfileImage(uri.toString());
|
||||
selectedImageUri = null; // reset
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao atualizar foto: " +
|
||||
(task.getException() != null ? task.getException().getMessage()
|
||||
: "Erro desconhecido"),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, "Erro ao atualizar perfil", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}).addOnFailureListener(e -> {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao obter URL da imagem: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, "Erro ao obter URL: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}).addOnFailureListener(e -> {
|
||||
progressDialog.dismiss();
|
||||
@@ -435,53 +384,17 @@ public class ContaActivity extends AppCompatActivity {
|
||||
|
||||
} catch (Exception e) {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao processar imagem: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
Toast.makeText(this, "Erro: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (Exception e) {
|
||||
// Ignorar erro ao fechar
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAllChanges() {
|
||||
if (editName == null)
|
||||
return;
|
||||
|
||||
String newName = editName.getText().toString().trim();
|
||||
|
||||
if (newName.isEmpty()) {
|
||||
Toast.makeText(this, "Por favor, insira um nome", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user == null) {
|
||||
Toast.makeText(this, "Utilizador não autenticado", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
progressDialog.show();
|
||||
|
||||
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
|
||||
.setDisplayName(newName)
|
||||
.build();
|
||||
|
||||
user.updateProfile(profileUpdates).addOnCompleteListener(task -> {
|
||||
progressDialog.dismiss();
|
||||
if (task.isSuccessful()) {
|
||||
Toast.makeText(this, "Alterações guardadas com sucesso!", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao guardar alterações: " +
|
||||
(task.getException() != null ? task.getException().getMessage() : "Erro desconhecido"),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sendPasswordResetEmail() {
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user == null || user.getEmail() == null) {
|
||||
|
||||
@@ -30,7 +30,8 @@ public class DefinicoesFragment extends Fragment {
|
||||
setupUi();
|
||||
return binding.getRoot();
|
||||
}
|
||||
//teste
|
||||
|
||||
// teste
|
||||
private void setupUi() {
|
||||
binding.cardConta.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
@@ -44,14 +45,35 @@ public class DefinicoesFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
binding.switchNotifications.setOnCheckedChangeListener((buttonView, isChecked) ->
|
||||
binding.textNotificationsStatus.setText(
|
||||
binding.switchNotifications
|
||||
.setOnCheckedChangeListener((buttonView, isChecked) -> binding.textNotificationsStatus.setText(
|
||||
isChecked ? "Ativadas" : "Desativadas"));
|
||||
|
||||
binding.switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) ->
|
||||
binding.textDarkModeStatus.setText(
|
||||
isChecked ? "Ativo" : "Inativo"));
|
||||
// Obter SharedPreferences
|
||||
android.content.SharedPreferences prefs = requireActivity().getSharedPreferences("SettingsPrefs",
|
||||
android.content.Context.MODE_PRIVATE);
|
||||
boolean isDarkMode = prefs.getBoolean("dark_mode", false);
|
||||
|
||||
binding.switchDarkMode.setChecked(isDarkMode);
|
||||
binding.textDarkModeStatus.setText(isDarkMode ? "Ativo" : "Inativo");
|
||||
|
||||
binding.switchDarkMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
binding.textDarkModeStatus.setText(isChecked ? "Ativo" : "Inativo");
|
||||
|
||||
// Guardar preferência
|
||||
android.content.SharedPreferences.Editor editor = prefs.edit();
|
||||
editor.putBoolean("dark_mode", isChecked);
|
||||
editor.apply();
|
||||
|
||||
// Aplicar modo escuro
|
||||
if (isChecked) {
|
||||
androidx.appcompat.app.AppCompatDelegate
|
||||
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES);
|
||||
} else {
|
||||
androidx.appcompat.app.AppCompatDelegate
|
||||
.setDefaultNightMode(androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO);
|
||||
}
|
||||
});
|
||||
|
||||
binding.btnOpenSystemSettings.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(Settings.ACTION_SETTINGS);
|
||||
@@ -66,4 +88,3 @@ public class DefinicoesFragment extends Fragment {
|
||||
binding = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,48 +121,6 @@
|
||||
android:padding="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless" />
|
||||
|
||||
<!-- URL Input Section -->
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:hint="URL da Imagem (Google)"
|
||||
app:boxCornerRadiusTopStart="12dp"
|
||||
app:boxCornerRadiusTopEnd="12dp"
|
||||
app:boxCornerRadiusBottomStart="12dp"
|
||||
app:boxCornerRadiusBottomEnd="12dp"
|
||||
app:boxStrokeWidth="1dp"
|
||||
app:boxStrokeColor="@color/divider"
|
||||
app:startIconDrawable="@android:drawable/ic_menu_view"
|
||||
app:startIconTint="@color/text_secondary"
|
||||
app:boxBackgroundMode="outline"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/editImageUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textUri"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textColorHint="@color/text_secondary"
|
||||
android:textSize="14sp"
|
||||
android:padding="14dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:hint="https://..." />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnLoadImageUrl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:backgroundTint="@color/primary_light"
|
||||
android:text="Carregar Imagem da URL"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
Reference in New Issue
Block a user