adicao de botao de terminar sessao
parent
81eb71bd46
commit
460b719785
|
|
@ -1,8 +1,12 @@
|
|||
package com.example.vdcscore;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.Menu;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.snackbar.Snackbar;
|
||||
import com.google.android.material.navigation.NavigationView;
|
||||
|
|
@ -15,6 +19,10 @@ import androidx.drawerlayout.widget.DrawerLayout;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.example.vdcscore.databinding.ActivityMainBinding;
|
||||
import com.google.firebase.auth.FirebaseAuth;
|
||||
import com.google.firebase.auth.FirebaseUser;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
|
|
@ -48,6 +56,88 @@ public class MainActivity extends AppCompatActivity {
|
|||
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
|
||||
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
|
||||
NavigationUI.setupWithNavController(navigationView, navController);
|
||||
|
||||
// Carregar dados do utilizador no menu lateral
|
||||
loadUserDataInNavHeader();
|
||||
}
|
||||
|
||||
private void loadUserDataInNavHeader() {
|
||||
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||
if (user == null) return;
|
||||
|
||||
View headerView = binding.navView.getHeaderView(0);
|
||||
TextView textViewName = headerView.findViewById(R.id.textViewName);
|
||||
TextView textViewEmail = headerView.findViewById(R.id.textView);
|
||||
ImageView imageView = headerView.findViewById(R.id.imageView);
|
||||
|
||||
// Carregar nome
|
||||
if (textViewName != null) {
|
||||
if (user.getDisplayName() != null && !user.getDisplayName().isEmpty()) {
|
||||
textViewName.setText(user.getDisplayName());
|
||||
} else {
|
||||
textViewName.setText("Utilizador");
|
||||
}
|
||||
}
|
||||
|
||||
// Carregar email
|
||||
if (textViewEmail != null && user.getEmail() != null) {
|
||||
textViewEmail.setText(user.getEmail());
|
||||
}
|
||||
|
||||
// Carregar foto de perfil
|
||||
if (imageView != null && user.getPhotoUrl() != null) {
|
||||
loadProfileImageInNavHeader(user.getPhotoUrl().toString(), imageView);
|
||||
} else {
|
||||
// Tentar carregar do Storage
|
||||
loadProfileImageFromStorage(imageView);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadProfileImageInNavHeader(String imageUrl, ImageView imageView) {
|
||||
new Thread(() -> {
|
||||
InputStream input = null;
|
||||
try {
|
||||
java.net.URL url = new java.net.URL(imageUrl);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
|
||||
connection.setDoInput(true);
|
||||
connection.connect();
|
||||
input = connection.getInputStream();
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(input);
|
||||
runOnUiThread(() -> {
|
||||
if (bitmap != null && imageView != null) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
imageView.setScaleType(android.widget.ImageView.ScaleType.CENTER_CROP);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
// Se falhar, tentar carregar do Storage
|
||||
runOnUiThread(() -> loadProfileImageFromStorage(imageView));
|
||||
} finally {
|
||||
if (input != null) {
|
||||
try {
|
||||
input.close();
|
||||
} catch (Exception e) {
|
||||
// Ignorar erro ao fechar
|
||||
}
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void loadProfileImageFromStorage(ImageView imageView) {
|
||||
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
|
||||
if (user == null || imageView == null) return;
|
||||
|
||||
com.google.firebase.storage.FirebaseStorage.getInstance()
|
||||
.getReference()
|
||||
.child("profile_images/" + user.getUid() + ".jpg")
|
||||
.getDownloadUrl()
|
||||
.addOnSuccessListener(uri -> {
|
||||
loadProfileImageInNavHeader(uri.toString(), imageView);
|
||||
})
|
||||
.addOnFailureListener(e -> {
|
||||
// Manter imagem padrão
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -63,4 +153,11 @@ public class MainActivity extends AppCompatActivity {
|
|||
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|
||||
|| super.onSupportNavigateUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Atualizar dados do utilizador quando voltar à activity
|
||||
loadUserDataInNavHeader();
|
||||
}
|
||||
}
|
||||
|
|
@ -44,8 +44,11 @@ public class ContaActivity extends AppCompatActivity {
|
|||
|
||||
private ImageView imageProfile;
|
||||
private TextInputEditText editName;
|
||||
private TextInputEditText editImageUrl;
|
||||
private TextView textEmail;
|
||||
private Button btnSaveName;
|
||||
private Button btnLoadImageUrl;
|
||||
private Button btnLogout;
|
||||
private View btnChangePhoto;
|
||||
private View cardImageContainer;
|
||||
|
||||
|
|
@ -58,6 +61,8 @@ public class ContaActivity extends AppCompatActivity {
|
|||
private ActivityResultLauncher<String> permissionLauncher;
|
||||
private Uri selectedImageUri;
|
||||
|
||||
private static final String PREFS_NAME = "LoginPrefs";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
@ -88,8 +93,10 @@ public class ContaActivity extends AppCompatActivity {
|
|||
|
||||
imageProfile = findViewById(R.id.imageProfile);
|
||||
editName = findViewById(R.id.editName);
|
||||
editImageUrl = findViewById(R.id.editImageUrl);
|
||||
textEmail = findViewById(R.id.textEmail);
|
||||
btnSaveName = findViewById(R.id.btnSaveName);
|
||||
btnLoadImageUrl = findViewById(R.id.btnLoadImageUrl);
|
||||
btnLogout = findViewById(R.id.btnLogout);
|
||||
btnChangePhoto = findViewById(R.id.btnChangePhoto);
|
||||
cardImageContainer = findViewById(R.id.cardImageContainer);
|
||||
|
|
@ -226,11 +233,121 @@ public class ContaActivity extends AppCompatActivity {
|
|||
if (btnSaveName != null) {
|
||||
btnSaveName.setOnClickListener(v -> saveUserName());
|
||||
}
|
||||
if (btnLoadImageUrl != null) {
|
||||
btnLoadImageUrl.setOnClickListener(v -> loadImageFromUrl());
|
||||
}
|
||||
if (btnLogout != null) {
|
||||
btnLogout.setOnClickListener(v -> logoutUser());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadImageFromUrl() {
|
||||
if (editImageUrl == null) return;
|
||||
|
||||
String imageUrl = editImageUrl.getText().toString().trim();
|
||||
|
||||
if (imageUrl.isEmpty()) {
|
||||
Toast.makeText(this, "Por favor, insira uma URL válida", 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);
|
||||
// Converter bitmap para URI e fazer upload
|
||||
uploadImageFromBitmap(bitmap);
|
||||
} 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 uploadImageFromBitmap(Bitmap bitmap) {
|
||||
FirebaseUser user = mAuth.getCurrentUser();
|
||||
if (user == null) return;
|
||||
|
||||
progressDialog.show();
|
||||
|
||||
try {
|
||||
// Redimensionar se muito grande
|
||||
int maxSize = 1024;
|
||||
if (bitmap.getWidth() > maxSize || bitmap.getHeight() > maxSize) {
|
||||
float scale = Math.min((float) maxSize / bitmap.getWidth(), (float) maxSize / bitmap.getHeight());
|
||||
int newWidth = Math.round(bitmap.getWidth() * scale);
|
||||
int newHeight = Math.round(bitmap.getHeight() * scale);
|
||||
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
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();
|
||||
|
||||
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(uri.toString());
|
||||
} else {
|
||||
Toast.makeText(this, "Erro ao atualizar foto: " +
|
||||
(task.getException() != null ? task.getException().getMessage() : "Erro desconhecido"),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}).addOnFailureListener(e -> {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao obter URL da imagem: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}).addOnFailureListener(e -> {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao fazer upload: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
progressDialog.dismiss();
|
||||
Toast.makeText(this, "Erro ao processar imagem: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void logoutUser() {
|
||||
// Limpar credenciais guardadas
|
||||
SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="Alterar Foto"
|
||||
android:text="Alterar Foto (Galeria)"
|
||||
android:textColor="#616161"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
|
|
@ -116,6 +116,50 @@
|
|||
android:padding="12dp"
|
||||
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="#BDBDBD"
|
||||
app:startIconDrawable="@android:drawable/ic_menu_view"
|
||||
app:startIconTint="#616161"
|
||||
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="#212121"
|
||||
android:textColorHint="#9E9E9E"
|
||||
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="48dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:backgroundTint="#616161"
|
||||
android:text="Carregar Imagem da URL"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:elevation="2dp"
|
||||
android:stateListAnimator="@null" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
|
|||
|
|
@ -14,22 +14,29 @@
|
|||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="80dp"
|
||||
android:layout_height="80dp"
|
||||
android:contentDescription="@string/nav_header_desc"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:scaleType="centerCrop"
|
||||
android:background="#E0E0E0"
|
||||
app:srcCompat="@mipmap/ic_launcher_round" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textViewName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:text="@string/nav_header_title"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/nav_header_subtitle" />
|
||||
android:text="@string/nav_header_subtitle"
|
||||
android:textColor="#FFFFFF"
|
||||
android:alpha="0.9" />
|
||||
</LinearLayout>
|
||||
Loading…
Reference in New Issue