Jump to content
Sign in to follow this  
polska

Android problema com a back stack

Recommended Posts

polska

Boas pessoal, venho aqui com um problema que, pesquisando, já vi levantar muitas dúvidas (principalmente no stackoverflow) mas que ainda não o consegui resolver, tentei implementar algumas soluções apresentadas mas ainda não funcionou, mas também penso estar a fazer alguma confusão e por isso é que está a ser mais complicado.

Bem, tenho 2 actividades na aplicação, a Main Activity e a Login Activity, quando a app é iniciada, no metodo onCreate da Main Activity é chamado um método de uma classe externa que verifica se existe alguma sessão iniciada na aplicação, caso não exista, o utilizador é redireccionado para a actividade de Login para se autenticar, e é aqui que acontece o que não quero.. Uma vez na actividade de login, se o botão back for pressionado, a aplicação volta para a main activity, o que eu queria era que a aplicação fechasse ...

É através da classe SessionManager que redirecciono o utilizador, ao chamar o método checkLogin() ..


import java.util.HashMap;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;

public class SessionManager {

   // shared preferences
   SharedPreferences pref;

   // editor das shared preferences
   Editor editor;

   // contexto
   Context _context;

   // modo da shared pref (constante 0 = privado)
   int MODE_PRIVATE = 0;

   // nome do ficheiro da shared pref
   private static final String PREF_NAME = "EsdahConnectPref";

   // Todas as shared preferences keys
   private static final String IS_LOGIN = "estaLogado";
   public static final String KEY_NAME = "nome";

   /**
    * Construtor
    * */
   @SuppressLint("CommitPrefEdits")
   public SessionManager(Context context) {
       this._context = context;
       pref = _context.getSharedPreferences(PREF_NAME, MODE_PRIVATE);
       editor = pref.edit();
   }

   /**
    * Criar sessão de login
    * */
   public void createLoginSession(String nome) {
       // colocar key de login a TRUE
       editor.putBoolean(IS_LOGIN, true);

       // colocar nome na pref
       editor.putString(KEY_NAME, nome);

       // efectuar alterações
       editor.commit();
   }

   /**
    * Verifica estado de login
    * Se falso o utilizador é redirecionado para a actividade de login
    * Caso contrário não faz nada
    * */
   public void checkLogin() {
       if(!this.isLoggedIn()) {
           // redireciona utilizador para a actividade login
           Intent i = new Intent(_context, LoginActivity.class);

           // fecha todas as actividades
           i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

           // adiciona flag para começar nova actividade
           i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

           // começa actividade de login
           _context.startActivity(i);
       }
   }

   /**
    * Obtem dados guardados da sessão
    * */
   public HashMap<String, String> getUserDetails() {
       HashMap<String, String> utilizador = new HashMap<String, String>();

       // nome utilizador
       utilizador.put(KEY_NAME, pref.getString(KEY_NAME, null));

       return utilizador;
   }

   /**
    * Apagar detalhes da sessão
    * */
   public void logoutUser() {
       // apagar dados da sharedPreferences
       editor.clear();
       editor.commit();

       // redirecionar utilizador para a actividade de login
       Intent i = new Intent(_context, LoginActivity.class);

       // fecha todas as actividades
       i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

       // adiciona flag para começar nova actividade
       i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

       // começa actividade de login
       _context.startActivity(i);
   }

   /**
    * Verificação rápida de login
    * */
   public boolean isLoggedIn() {
       return pref.getBoolean(IS_LOGIN, false);
   }
}

Eu sei que, provavelmente, não estou a utilizar bem as flags dos intents, mas estou um bocado confuso, também por culpa das soluções que fui lendo.. Alguém me pode dar uma ajuda ?


Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
polska

Não estou a implementar esse método, já o tentei utilizar para chamar o finish() nas actividades mas não resultou.. No método onCreate() da main activity chamo o checkLogin() para verificar a sessão, o logoutUser() é chamado quando o utilizador carrega num botão na main activity..

Edit:

MainActivity:


import java.util.HashMap;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

   // session manager
   SessionManager session;

   // button logout
   Button logout;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_main);

       // session manager
       session = new SessionManager(getApplicationContext());

       // conecta button view à variável
       logout = (Button) findViewById(R.id.buttonLogout);

       // verifica login
       session.checkLogin();

       // obtem dados de utilizador
       HashMap<String, String> utilizador = session.getUserDetails();

       // nome
       String nome = utilizador.get(SessionManager.KEY_NAME);

       // mensagem de boas vindas
       Toast.makeText(getApplicationContext(), "Bem Vindo/a " + nome, Toast.LENGTH_SHORT).show();

       // acção de click no botão de logout
       logout.setonclickListener(new View.onclickListener() {

           @Override
           public void onclick(View arg0) {
               // TODO Auto-generated method stub
               session.logoutUser();
           }
       });
   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
       // Inflate the menu; this adds items to the action bar if it is present.
       getMenuInflater().inflate(R.menu.main, menu);
       return true;
   }

}

LoginActivity:


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class LoginActivity extends Activity {

   // editText do código e password de utilizador
   EditText txtUtilizador, txtPassword;

   // button de login
   Button login;

   // alert dialog
   AlertDialogManager alertDialog = new AlertDialogManager();

   // session manager
   SessionManager session;

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

       // session manager
       session = new SessionManager(getApplicationContext());

       // conecta EditText views às variáveis
       txtUtilizador = (EditText) findViewById(R.id.editTextCodigoUtilizador);
       txtPassword = (EditText) findViewById(R.id.editTextPasswordUtilizador);

       // conecta button view à variável
       login = (Button) findViewById(R.id.buttonLogin);

       // acção de click no botão de login
       login.setonclickListener(new View.onclickListener() {

           @Override
           public void onclick(View v) {
               // TODO Auto-generated method stub
               String utilizador = txtUtilizador.getText().toString();
               String password = txtPassword.getText().toString();

               if(utilizador.trim().length() > 0 && password.trim().length() > 0){
                   // For testing puspose utilizador, password is checked with sample data
                   // utilizador = a-3219
                   // password = 0000
                   if(utilizador.equals("a-3219") && password.equals("0000")) {

                       // cria sessão de login
                       session.createLoginSession("Polska");

                       // MainActivity
                       Intent i = new Intent(getApplicationContext(), MainActivity.class);
                       i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                       i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                       startActivity(i);
                       //finish();

                   }else{
                       // utilizador/ password estão errados
                       alertDialog.showAlertDialog(LoginActivity.this, "Login Falhado..", "Utilizador/Password estão errados");
                   }               
               }else{
                   // utilizador não introduziu a password ou utilizador
                   alertDialog.showAlertDialog(LoginActivity.this, "Login Falhado..", "Por favor introduza o utilizador/password");
               }
           }
       });

   }

   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
       // Inflate the menu; this adds items to the action bar if it is present.
       getMenuInflater().inflate(R.menu.login, menu);
       return true;
   }

}

Edited by polska

Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
bioshock

Se não o tens implementado, como é que esperas detectar o click do botão voltar para trás?

No actividade LoginActivity, implementa esse método e lês uma variável da classe que dita se pode ou não voltar para trás. Eventualmente, nem precisavas de colocar essa variável na classe, podias passar pelas sharedpreferences ou pelos bundles, dependendo do método implementado.

Share this post


Link to post
Share on other sites
polska

E como é que fecho a aplicação quando não posso voltar para trás ? Se chamar o finish() só estou a terminar a actividade de login, mas como ainda tenho a actividade principal na back stack acaba sempre por voltar lá .. e uma vez nesta actividade, como é a única na back stack se fizer back já termina a app..

Edited by polska

Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
HappyHippyHippo

se queres usar um SessionManager podes fazer algo como :

      Main Activity          |          LoginActivity
------------------------------+------------------------------
         |
    (On create)
     save pref:
    authenticating
         |
         +---------------------------->   is back button ?
                                            |           |
                                          yes          no
                                            |           |
                                        save pref:      |
                                           fail         |
                                            |           |
         +<---------------------------------+           |
         |                                          save pref:
         |                                        success | fail
         |                                              |
         |<---------------------------------------------+
         |
     (On resume)
     is pref fail ?
     |          |
    no         yes
     |          |
     v          +----> finalize()

nota : sim, eu sei que náo é exactamente assim, mas andar aqui a fazer ascii art é uma seca do camandro, mas dá para perceber o conceito


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
polska

se queres usar um SessionManager podes fazer algo como :

      Main Activity          |          LoginActivity
------------------------------+------------------------------
         |
    (On create)
     save pref:
    authenticating
         |
         +---------------------------->   is back button ?
                                            |           |
                                          yes          no
                                            |           |
                                        save pref:      |
                                           fail         |
                                            |           |
         +<---------------------------------+           |
         |                                          save pref:
         |                                        success | fail
         |                                              |
         |<---------------------------------------------+
         |
     (On resume)
     is pref fail ?
     |          |
    no         yes
     |          |
     v          +----> finalize()

Eu percebi o que me queres mostrar, mas digo o mesmo que na minha resposta anterior, quando chego a parte do finalize(), não tenho nenhuma instrução que me permita fechar a app, tenho que apagar todas as actividades que estão na stack, e como tenho a main activity antes da login activity chamar o finish() não vai resultar porque só estou a terminar a login activity da stack, voltando então para a main activity e aí sim, se clicar no back já vai fechar a app porque esta era a única entrada da stack no momento..


Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
HappyHippyHippo

Eu percebi o que me queres mostrar, mas digo o mesmo que na minha resposta anterior, quando chego a parte do finalize(), não tenho nenhuma instrução que me permita fechar a app, tenho que apagar todas as actividades que estão na stack, e como tenho a main activity antes da login activity chamar o finish() não vai resultar porque só estou a terminar a login activity da stack, voltando então para a main activity e aí sim, se clicar no back já vai fechar a app porque esta era a única entrada da stack no momento..

com o modelo que te apresentei, o finish é executado na MainActivity depois da LoginActivity já ter sido terminada/retornada


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
polska

com o modelo que te apresentei, o finish é executado na MainActivity depois da LoginActivity já ter sido terminada/retornada

Tens razão, distracção, então aqui o que sugeres é guardar um valor de autentificação na minha pref e quando faço back na login activity ele volta (como já o faz) para a main activity mas faz logo uma verificação da pref e termina caso tenha que o fazer, certo ? Se sim, então esta verificação da pref também tem que ser feita no onCreate da main activity não? Porque se for no onresume o utilizador vai conseguir ver o layout da main activity de qualquer das maneiras..

Edited by polska

Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
bioshock

Não vai ser no OnCreate() porque não vais criar outra actividade MainActivity, vais voltar para uma que já está aberta.

activity_lifecycle.png

Share this post


Link to post
Share on other sites
polska

Não preciso então das flags quando começo novos intents certo ?


Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites
polska

Obrigado, penso que resolvi o problema :)


Corrige um sábio e ele mais sábio ficará. Corrige um ignorante e um inimigo ganharás.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.