Esta es la Parte 3 del tutorial «Crear una aplicación de redes sociales en Android Studio» , y cubriremos las siguientes funcionalidades en este artículo:
- Vamos a editar los datos de nuestro perfil, como cambiar el nombre, cambiar la contraseña del usuario y cambiar la foto del perfil.
- El cambio de contraseña es una característica muy importante porque puede suceder que a veces alguien sepa nuestra contraseña y, en ese caso, necesitamos cambiar nuestra contraseña.
- Cambiamos nuestra foto de perfil seleccionando una imagen de la galería o haciendo clic en una imagen de la cámara.
Implementación paso a paso
Paso 1: Agregar dependencia a build.gradle (Módulo: aplicación)
Navegue a Gradle Scripts > build. gradle (Módulo: aplicación) y agregue la dependencia a continuación en la sección de dependencias.
implementation "androidx.recyclerview:recyclerview:1.1.0" implementation 'de.hdodenhof:circleimageview:3.1.0' implementation 'com.github.bumptech.glide:glide:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
Ahora sincronice el proyecto desde la opción de la esquina superior derecha de Sincronizar ahora.
Paso 2: agregue permiso de lectura, escritura y cámara en el archivo AndroidManifest.xml
Navegue hasta el archivo AndroidManifest.xml y agregue el siguiente permiso para obtener permiso de lectura, escritura y cámara en la aplicación.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.CAMERA" />
Paso 3: Cree una nueva actividad vacía y nombre la actividad como EditProfilePage
Trabajar con el archivo activity_edit_profile_page.xml . En esta página se cambiará el correo electrónico, el nombre y la foto de perfil del usuario. Vaya a la aplicación > res > diseño > actividad_editar_perfil_página.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_edit_profile_page.xml .
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".EditProfilePage"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:text="Edit Profile Data" android:textAlignment="center" android:textColor="@android:color/black" android:textSize="26sp" /> <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/setting_profile_image" android:layout_width="130dp" android:layout_height="130dp" android:layout_marginStart="140dp" android:layout_marginTop="40dp" android:src="@drawable/ic_users" /> <TextView android:id="@+id/profilepic" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="Update Profile Pic" android:textAlignment="center" android:textColor="@android:color/black" android:textSize="20sp" /> <TextView android:id="@+id/editname" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="Update Name" android:textAlignment="center" android:textColor="@android:color/black" android:textSize="20sp" /> <TextView android:id="@+id/changepassword" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="Change Password " android:textAlignment="center" android:textColor="@android:color/black" android:textSize="20sp" /> </LinearLayout>
Paso 4: Cree un nuevo archivo de recursos de diseño
Vaya a la aplicación > res > diseño > Nuevo > Archivo de recursos de diseño y nombre el archivo como dialog_update_password. Vaya a la aplicación > res > diseño > dialog_update_password.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo dialog_update_password.xml .
XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="20dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Update Password" android:textAlignment="center" android:textColor="@color/colorBlack" android:textSize="16sp" android:textStyle="bold" /> <com.google.android.material.textfield.TextInputLayout android:id="@+id/oldpass" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" app:passwordToggleEnabled="true"> <EditText android:id="@+id/oldpasslog" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Old Password" android:inputType="textPassword" /> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputLayout android:id="@+id/newpass" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/oldpasslog" android:layout_centerHorizontal="true" android:layout_centerVertical="true" app:passwordToggleEnabled="true"> <EditText android:id="@+id/newpasslog" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="New Password" android:inputType="textPassword" /> </com.google.android.material.textfield.TextInputLayout> <Button android:id="@+id/updatepass" style="@style/Widget.AppCompat.Button.Colored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="Update Password" /> </LinearLayout>
Paso 5: trabajar con el archivo EditProfilePage.java
Vaya al archivo EditProfilePage.java y consulte el siguiente código. A continuación se muestra el código para el archivo EditProfilePage.java . Se agregan comentarios dentro del código para comprender el código con más detalle.
Java
package com.example.socialmediaapp; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.ContentValues; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import com.bumptech.glide.Glide; import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.EmailAuthProvider; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.Query; import com.google.firebase.database.ValueEventListener; import com.google.firebase.storage.FirebaseStorage; import com.google.firebase.storage.StorageReference; import com.google.firebase.storage.UploadTask; import java.util.HashMap; public class EditProfilePage extends AppCompatActivity { private FirebaseAuth firebaseAuth; FirebaseUser firebaseUser; FirebaseDatabase firebaseDatabase; DatabaseReference databaseReference; StorageReference storageReference; String storagepath = "Users_Profile_Cover_image/"; String uid; ImageView set; TextView profilepic, editname, editpassword; ProgressDialog pd; private static final int CAMERA_REQUEST = 100; private static final int STORAGE_REQUEST = 200; private static final int IMAGEPICK_GALLERY_REQUEST = 300; private static final int IMAGE_PICKCAMERA_REQUEST = 400; String cameraPermission[]; String storagePermission[]; Uri imageuri; String profileOrCoverPhoto; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_edit_profile_page); profilepic = findViewById(R.id.profilepic); editname = findViewById(R.id.editname); set = findViewById(R.id.setting_profile_image); pd = new ProgressDialog(this); pd.setCanceledOnTouchOutside(false); editpassword = findViewById(R.id.changepassword); firebaseAuth = FirebaseAuth.getInstance(); firebaseUser = firebaseAuth.getCurrentUser(); firebaseDatabase = FirebaseDatabase.getInstance(); storageReference = FirebaseStorage.getInstance().getReference(); databaseReference = firebaseDatabase.getReference("Users"); cameraPermission = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}; storagePermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}; Query query = databaseReference.orderByChild("email").equalTo(firebaseUser.getEmail()); query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { String image = "" + dataSnapshot1.child("image").getValue(); try { Glide.with(EditProfilePage.this).load(image).into(set); } catch (Exception e) { } } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); editpassword.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pd.setMessage("Changing Password"); showPasswordChangeDailog(); } }); profilepic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pd.setMessage("Updating Profile Picture"); profileOrCoverPhoto = "image"; showImagePicDialog(); } }); editname.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pd.setMessage("Updating Name"); showNamephoneupdate("name"); } }); } @Override protected void onPause() { super.onPause(); Query query = databaseReference.orderByChild("email").equalTo(firebaseUser.getEmail()); query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { String image = "" + dataSnapshot1.child("image").getValue(); try { Glide.with(EditProfilePage.this).load(image).into(set); } catch (Exception e) { } } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); editpassword.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pd.setMessage("Changing Password"); showPasswordChangeDailog(); } }); } @Override protected void onStart() { super.onStart(); Query query = databaseReference.orderByChild("email").equalTo(firebaseUser.getEmail()); query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { String image = "" + dataSnapshot1.child("image").getValue(); try { Glide.with(EditProfilePage.this).load(image).into(set); } catch (Exception e) { } } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); editpassword.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { pd.setMessage("Changing Password"); showPasswordChangeDailog(); } }); } // checking storage permission ,if given then we can add something in our storage private Boolean checkStoragePermission() { boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED); return result; } // requesting for storage permission private void requestStoragePermission() { requestPermissions(storagePermission, STORAGE_REQUEST); } // checking camera permission ,if given then we can click image using our camera private Boolean checkCameraPermission() { boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == (PackageManager.PERMISSION_GRANTED); boolean result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED); return result && result1; } // requesting for camera permission if not given private void requestCameraPermission() { requestPermissions(cameraPermission, CAMERA_REQUEST); } // We will show an alert box where we will write our old and new password private void showPasswordChangeDailog() { View view = LayoutInflater.from(this).inflate(R.layout.dialog_update_password, null); final EditText oldpass = view.findViewById(R.id.oldpasslog); final EditText newpass = view.findViewById(R.id.newpasslog); Button editpass = view.findViewById(R.id.updatepass); AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setView(view); final AlertDialog dialog = builder.create(); dialog.show(); editpass.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String oldp = oldpass.getText().toString().trim(); String newp = newpass.getText().toString().trim(); if (TextUtils.isEmpty(oldp)) { Toast.makeText(EditProfilePage.this, "Current Password cant be empty", Toast.LENGTH_LONG).show(); return; } if (TextUtils.isEmpty(newp)) { Toast.makeText(EditProfilePage.this, "New Password cant be empty", Toast.LENGTH_LONG).show(); return; } dialog.dismiss(); updatePassword(oldp, newp); } }); } // Now we will check that if old password was authenticated // correctly then we will update the new password private void updatePassword(String oldp, final String newp) { pd.show(); final FirebaseUser user = firebaseAuth.getCurrentUser(); AuthCredential authCredential = EmailAuthProvider.getCredential(user.getEmail(), oldp); user.reauthenticate(authCredential) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { user.updatePassword(newp) .addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Changed Password", Toast.LENGTH_LONG).show(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Failed", Toast.LENGTH_LONG).show(); } }); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Failed", Toast.LENGTH_LONG).show(); } }); } // Updating name private void showNamephoneupdate(final String key) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Update" + key); // creating a layout to write the new name LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); layout.setPadding(10, 10, 10, 10); final EditText editText = new EditText(this); editText.setHint("Enter" + key); layout.addView(editText); builder.setView(layout); builder.setPositiveButton("Update", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final String value = editText.getText().toString().trim(); if (!TextUtils.isEmpty(value)) { pd.show(); // Here we are updating the new name HashMap<String, Object> result = new HashMap<>(); result.put(key, value); databaseReference.child(firebaseUser.getUid()).updateChildren(result).addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { pd.dismiss(); // after updated we will show updated Toast.makeText(EditProfilePage.this, " updated ", Toast.LENGTH_LONG).show(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Unable to update", Toast.LENGTH_LONG).show(); } }); if (key.equals("name")) { final DatabaseReference databaser = FirebaseDatabase.getInstance().getReference("Posts"); Query query = databaser.orderByChild("uid").equalTo(uid); query.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) { String child = databaser.getKey(); dataSnapshot1.getRef().child("uname").setValue(value); } } @Override public void onCancelled(@NonNull DatabaseError databaseError) { } }); } } else { Toast.makeText(EditProfilePage.this, "Unable to update", Toast.LENGTH_LONG).show(); } } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { pd.dismiss(); } }); builder.create().show(); } // Here we are showing image pic dialog where we will select // and image either from camera or gallery private void showImagePicDialog() { String options[] = {"Camera", "Gallery"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick Image From"); builder.setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // if access is not given then we will request for permission if (which == 0) { if (!checkCameraPermission()) { requestCameraPermission(); } else { pickFromCamera(); } } else if (which == 1) { if (!checkStoragePermission()) { requestStoragePermission(); } else { pickFromGallery(); } } } }); builder.create().show(); } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { if (resultCode == Activity.RESULT_OK) { if (requestCode == IMAGEPICK_GALLERY_REQUEST) { imageuri = data.getData(); uploadProfileCoverPhoto(imageuri); } if (requestCode == IMAGE_PICKCAMERA_REQUEST) { uploadProfileCoverPhoto(imageuri); } } super.onActivityResult(requestCode, resultCode, data); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case CAMERA_REQUEST: { if (grantResults.length > 0) { boolean camera_accepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; boolean writeStorageaccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED; if (camera_accepted && writeStorageaccepted) { pickFromCamera(); } else { Toast.makeText(this, "Please Enable Camera and Storage Permissions", Toast.LENGTH_LONG).show(); } } } break; case STORAGE_REQUEST: { if (grantResults.length > 0) { boolean writeStorageaccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; if (writeStorageaccepted) { pickFromGallery(); } else { Toast.makeText(this, "Please Enable Storage Permissions", Toast.LENGTH_LONG).show(); } } } break; } } // Here we will click a photo and then go to startactivityforresult for updating data private void pickFromCamera() { ContentValues contentValues = new ContentValues(); contentValues.put(MediaStore.Images.Media.TITLE, "Temp_pic"); contentValues.put(MediaStore.Images.Media.DESCRIPTION, "Temp Description"); imageuri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues); Intent camerIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); camerIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageuri); startActivityForResult(camerIntent, IMAGE_PICKCAMERA_REQUEST); } // We will select an image from gallery private void pickFromGallery() { Intent galleryIntent = new Intent(Intent.ACTION_PICK); galleryIntent.setType("image/*"); startActivityForResult(galleryIntent, IMAGEPICK_GALLERY_REQUEST); } // We will upload the image from here. private void uploadProfileCoverPhoto(final Uri uri) { pd.show(); // We are taking the filepath as storagepath + firebaseauth.getUid()+".png" String filepathname = storagepath + "" + profileOrCoverPhoto + "_" + firebaseUser.getUid(); StorageReference storageReference1 = storageReference.child(filepathname); storageReference1.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl(); while (!uriTask.isSuccessful()) ; // We will get the url of our image using uritask final Uri downloadUri = uriTask.getResult(); if (uriTask.isSuccessful()) { // updating our image url into the realtime database HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put(profileOrCoverPhoto, downloadUri.toString()); databaseReference.child(firebaseUser.getUid()).updateChildren(hashMap).addOnSuccessListener(new OnSuccessListener<Void>() { @Override public void onSuccess(Void aVoid) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Updated", Toast.LENGTH_LONG).show(); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Error Updating ", Toast.LENGTH_LONG).show(); } }); } else { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Error", Toast.LENGTH_LONG).show(); } } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { pd.dismiss(); Toast.makeText(EditProfilePage.this, "Error", Toast.LENGTH_LONG).show(); } }); } }
Paso 6: Cree una base de datos en tiempo real dentro de la consola de base de fuego
Vaya a firebase console > Realtime Database y cree su base de datos.
Luego comience en modo de prueba y habilite la base de datos en tiempo real.
Producción:
Cuando actualiza los datos, los datos se almacenan de la siguiente manera
Para ver todos los archivos dibujables utilizados en este artículo, consulte este enlace: https://drive.google.com/drive/folders/1M_knOH_ugCuwSP5nkYzeD4dRp-Honzbe?usp=sharing
A continuación se muestra la estructura de archivos después de realizar estas operaciones: