11.17: Un “blog” personale per Android sfruttando Firebase: aggiungere una foto profilo, il setup

Condividi su:

Nello scorso articolo ci siamo soffermati sulla creazione di un account, per permettere a qualsiasi utente di autenticarsi e iniziare così a salvare i propri post nel cloud di Firebase. Tra i dati salvati ce n’è anche uno chiamato “avatar”, di cui però non ci siamo occupati. Iniziamo a farlo.





Vogliamo che un utente, oltre a memorizzare nome e cognome, al netto delle credenziali, possa scegliere anche un’immagine profilo, un avatar. Per permetterglielo dobbiamo per prima cosa modificare il layout dell’activity CreateAccountActivity.
È necessario aggiungere un ImageButton in modo tale che l’utente, cliccando su questo, possa scegliere il proprio avatar dalla galleria e salvarlo, prima di procedere all’effettiva creazione dell’account. Il procedimento è simile a quanto visto con l’aggiunta dell’immagine del post.
Approfitteremo comunque della cosa per introdurre qualcosa di nuovo, daremo all’utente la possibilità di effettuare il crop dell’immagine, così come avviene per la maggior parte delle procedure di questo tipo.

In questo articolo ci limiteremo al setup del tutto, in modo da dedicare un post solo per la novità. Una volta che avrete aggiunto l’ImageButton nel layout, con relativa immagine di default settata, possiamo passare al codice dell’activity:

public class CreateAccountActivity extends AppCompatActivity {
    private ImageButton avatarPic;
    private EditText firstNameET;
    private EditText lastNameET;
    private EditText emailET;
    private EditText passwordET;
    private Button createActBT;
    private FirebaseDatabase DB;
    private DatabaseReference DBRef;
    private FirebaseAuth mAuth;
    private final static int GALLERY_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_account);

        /*
         * Recupero di istanze e riferimenti necessari da Firebase
         */
        DB = FirebaseDatabase.getInstance();
        DBRef = DB.getReference().child("Users");
        mAuth = FirebaseAuth.getInstance();

        /*
         * Istanziazione di tutti i widget presenti all'interno del layout
         */
        firstNameET = (EditText) findViewById(R.id.firstNameAct);
        lastNameET = (EditText) findViewById(R.id.lastNameAct);
        emailET = (EditText) findViewById(R.id.emailAct);
        passwordET = (EditText) findViewById(R.id.passwordAct);
        createActBT = (Button) findViewById(R.id.createAccountAct);
        avatarPic = (ImageButton) findViewById(R.id.avatarAct);

        avatarPic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Cliccando sull'ImageButton richiamiamo il metodo per l'aggiunta di un avatar
                addAvatar();
            }
        });

        //Setting del listener sul pulsante  per avviare la procedura di creazione account
        createActBT.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                createnewAct();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        /*
         * Metodo invocato quando l'utente ha selezionato l'immagine profilo dalla galleria.
         * Qui dobbiamo prelevare l'immagine e utilizzarla
         */
        super.onActivityResult(requestCode, resultCode, data);
        //Controlliamo che la richiesta sia andata a buon fine
        if (requestCode == GALLERY_CODE && resultCode == RESULT_OK){
            //Preleviamo l'URI dell'immagine dai dati ricevuti
            Uri mImageUri = data.getData();
            //ToDo: permettere il crop dell'immagine prima del salvataggio
        }
    }

    private void addAvatar() {
        /*
         * Confezioniamo l'intent per poter aprire la galleria e permettere la selezione di un immagine
         */
        Intent galleryIntent = new Intent();
        galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
        galleryIntent.setType("image/*");
        //Predisponiamo l'activity a ricevere dei dati da quella chiamata
        startActivityForResult(galleryIntent, GALLERY_CODE);
    }

    private void createnewAct() {
        /*
         * Recupero delle informazioni inserite all'interno delle EditText
         */
        final String name = firstNameET.getText().toString().trim();
        final String lName = lastNameET.getText().toString().trim();
        String eMail = emailET.getText().toString().trim();
        String pwd = passwordET.getText().toString().trim();

        //Controllo che tutti i campi siano stati compilati
        if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(lName)
                && !TextUtils.isEmpty(eMail) && !TextUtils.isEmpty(pwd)){
            //Creazione dell'account tramite apposito metodo, con listener sull'esito
            mAuth.createUserWithEmailAndPassword(eMail, pwd).addOnSuccessListener(new OnSuccessListener<AuthResult>() {
                @Override
                public void onSuccess(AuthResult authResult) {
                    if (authResult != null){
                        /*
                         * Se la creazione dell'account ha avuto successo, si memorizzano tutti i
                         * dati dell'utente all'interno del database e si direziona l'utente
                         * verso l'activity con la lista di post
                         */
                        String userID = mAuth.getCurrentUser().getUid();
                        DatabaseReference currentUserDBRef = DBRef.child(userID);
                        currentUserDBRef.child("firstName").setValue(name);
                        currentUserDBRef.child("lastName").setValue(lName);
                        currentUserDBRef.child("avatar").setValue("none");
                        Intent intent = new Intent(CreateAccountActivity.this, PostListActivity.class);
                        //Aggiungiamo un flag all'intent che non fa altro che porre l'activity
                        //destinataria nuovamente in cima allo stack, se già avviata, piuttosto che
                        //avviarne un'altra istanza, terminando contestualmente tutte le altre activity
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(intent);
                    }
                }
            });
        }else{
            //ToDo: codice per gestire il mancato inserimento di tutti i dati
        }
    }
}

Al codice che già avevamo abbiamo fatto delle aggiunte. Per prima cosa i due field, uno per l’ImageButton, che abbiamo provveduto anche ad istanziare collegandolo al relativo widget del layout; l’altro per la costante che conterrà il request code necessario ad avviare una nuova activity aspettandosi dei dati di ritorno.

All’ImageButton è stato ovviamente collegato un listener per catturare l’evento click su questa. Per la gestione del click richiamiamo un metodo creato appositamente: “addAvatar()”.

In questo metodo non facciamo altro che aggiungere le istruzioni necessarie a confezionare un intent implicito, col quale richiediamo di poter permettere all’utente di prelevare un contenuto, specificando poi il tipo di contenuto: tutti i tipi di immagine. Passando questo come parametro al metodo “startActivityForResult()”, insieme al request code otteniamo di aprire l’activity della galleria di default per poter selezionare un’immagine da ricevere poi come dato.
Con questo metodo abbiamo praticamente finito.

La nostra activity deve essere in grado di ricevere l’immagine dalla galleria, quindi effettuiamo l’override del metodo “onActivityResult()”, che verrà invocato nel momento in cui la galleria ritorna l’immagine.
Qui per il momento ci limitiamo a controllare che la richiesta sia andata a buon fine, controllando i valori di resultCode e requestCode, e inseriamo l’URI dell’immagine in un oggetto apposito.


Conclusioni

Non abbiamo fatto nulla di nuovo, se non servirci nuovamente di un intent implicito per poter prelevare un’immagine dalla memoria del dispositivo senza scrivere una riga di codice, ma sfruttando un altro componente dell’ecosistema Android.
Per il momento ci fermiamo qui, vogliamo permettere all’utente di effettuare il crop dell’immagine selezionata, quindi vedremo come sfruttare una libreria apposita per raggiungere lo scopo. Al prossimo articolo.

Condividi su:

label, , ,

About the author