2015-01-13 26 views
5

Cerco di implementare un gestore account nella mia app per evitare che l'utente debba accedere ogni volta che apre l'app.Come implementare AccountManager nella mia app

Fondamentalmente, ho già la mia attività di autenticazione in cui l'utente può inserire il suo login e password e dove riceviamo un token dal server (l'autenticazione è di base per ora). Ora voglio aggiungere l'account manager ma non capisco veramente quale parte andrebbe dove.

cosa ho bisogno è piuttosto semplice:

  • aggiungere un account se non ho mai collegato prima
  • registro automaticamente se il mio account è
  • se l'autenticazione automatica non funziona ottenere un nuovo token sul server

Ecco il mio codice:

AuthenticationActivity.java

public class AuthenticationActivity extends Activity { 

    private EditText editTextUsername; 
    private EditText editTextPassword; 
    private Button buttonLogin; 
    private ProgressBar spinner; 
    private TextView error; 
    private TextView register; 

    private boolean accountRegistred; 

    AccountManager accountManager; 

    public static final String AUTHENTICATION = "authentication"; //action 

    private ConnectionSuccessReceiver connectionSuccessReceiver = new ConnectionSuccessReceiver(); 

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

     accountManager = AccountManager.get(this); 
     Account[] accounts = accountManager.getAccountsByType("login"); 

     if (accounts.length > 0) { 
      //If there is an account 
     } else { 
      accountRegistred = false; 
      editTextUsername = (EditText) findViewById(R.id.editText_login); 
      editTextUsername.setVisibility(View.VISIBLE); 
      editTextPassword = (EditText) findViewById(R.id.editText_password); 
      editTextPassword.setVisibility(View.VISIBLE); 
      buttonLogin = (Button) findViewById(R.id.button_connection); 
      buttonLogin.setVisibility(View.VISIBLE); 
      error = (TextView) findViewById(R.id.textView_error); 
      register = (TextView) findViewById(R.id.textView_register); 
      register.setVisibility(View.VISIBLE); 
      spinner = (ProgressBar) findViewById(R.id.progressBar); 

      buttonLogin.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        //Here we start the service which will reach the server 
        Intent i = new Intent(getApplicationContext(), AuthenticationService.class); 
        i.putExtra("username", editTextUsername.getText().toString()); 
        i.putExtra("password", editTextPassword.getText().toString()); 
        getApplication().startService(i); 
        spinner.setVisibility(View.VISIBLE); 
        error.setVisibility(View.INVISIBLE); 
       } 
      }); 

      register.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        startActivity(new Intent(AuthenticationActivity.this, RegisterActivity.class)); 
       } 
      }); 
     } 
     registerReceiver(connectionSuccessReceiver, new IntentFilter(AUTHENTICATION)); 
    } 

    private class ConnectionSuccessReceiver extends BroadcastReceiver { 
     //Called when the server returns success after authentication, we get the TOKEN here 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getStringExtra("STATE").equals("CONNECTED")) { 
       Intent i = new Intent(AuthenticationActivity.this, MainActivity.class); 
       i.putExtra("TOKEN", intent.getStringExtra("TOKEN")); 
       startActivity(i); 
      } else { 
       spinner.setVisibility(View.INVISIBLE); 
       error.setVisibility(View.VISIBLE); 
      } 
      finish(); 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     unregisterReceiver(connectionSuccessReceiver); 
    } 
} 

AuthenticatorService.java

public class AuthenticatorService extends Service { 

    /** 
    * The implementation of the class |AccountAuthenticatorImpl|. 
    * It is implemented as a singleton 
    */ 
    private static AccountAuthenticator accountAuthenticator = null; 

    /** 
    * The main constructor. 
    */ 
    public AuthenticatorService() { 
     super(); 
    } 

    /** 
    * The bind method of the service. 
    * @param intent The intent used to invoke the service 
    * @return The binder of the class which has implemented |AbstractAccountAuthenticator| 
    */ 
    @Override 
    public IBinder onBind(Intent intent) { 
     IBinder ret = null; 
     if (intent.getAction().equals(android.accounts.AccountManager.ACTION_AUTHENTICATOR_INTENT)) { 
      ret = getAuthenticator().getIBinder(); 
     } 
     return ret; 
    } 

    /** 
    * The method used to obtain the authenticator. It is implemented as a singleton 
    * @return The implementation of the class |AbstractAccountAuthenticator| 
    */ 
    private AccountAuthenticator getAuthenticator() { 
     if (AuthenticatorService.accountAuthenticator == null) { 
      AuthenticatorService.accountAuthenticator = new AccountAuthenticator(this); 
     } 

     return AuthenticatorService.accountAuthenticator; 
    } 

    public class AccountAuthenticator extends AbstractAccountAuthenticator { 
     private Context context; 

     public AccountAuthenticator(Context context) { 
      super(context); 
      this.context = context; 
     } 

     @Override 
     public Bundle editProperties(AccountAuthenticatorResponse accountAuthenticatorResponse, String s) { 
      return null; 
     } 

     @Override 
     public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { 

      Bundle reply = new Bundle(); 

      Intent i = new Intent(context, AuthenticationActivity.class); 
      i.setAction("com.readyo.app.authentication.addnewaccount"); 
      i.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response); 
      i.putExtra("AuthTokenType", authTokenType); 

      reply.putParcelable(AccountManager.KEY_INTENT, i); 

      return reply; 
     } 

     @Override 
     public Bundle confirmCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, Bundle bundle) throws NetworkErrorException { 
      return null; 
     } 

     @Override 
     public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException { 
      return null; 
     } 

     @Override 
     public String getAuthTokenLabel(String s) { 
      return null; 
     } 

     @Override 
     public Bundle updateCredentials(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String s, Bundle bundle) throws NetworkErrorException { 
      return null; 
     } 

     @Override 
     public Bundle hasFeatures(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account, String[] strings) throws NetworkErrorException { 
      return null; 
     } 
    } 
} 

devo anche il codice per raggiungere il server via HTTP, ma io non sono sicuro che sarebbe stato importante.

Grazie per il vostro tempo.

risposta

2

E 'una risposta tardiva po' ma forse questo campione potrebbe aiutare: https://github.com/dawidgdanski/AccountAuthenticatorExample

ho creato qualche tempo fa, ma la logica con la firma/login può essere utile

add an account if I never logged in before: 
  1. Se il flusso dell'app richiede che l'utente effettui l'accesso per accedere ai dati, dichiara semplicemente che LoginActivity è quello principale da visualizzare.

Una volta convalidate e verificate le credenziali dell'utente, chiamate il metodo AccountManager.addAccountExcplicitly().

  1. D'altra parte, se si espongono alcune schermate per gli utenti anonimi, nella parte dell'applicazione (impostazioni o qualsiasi altra) in cui si fornisce la funzionalità di accesso/registrazione, chiamare AccountManager. Aggiungi account(). Questa chiamata attiva il tuo AccountAuthenticator che elabora la tua richiesta in YourAccountAuthenticator.addAccount() e può visualizzare LoginActivity/SignUpActivity in base alle tue esigenze.

Si prega di tenere presente che è possibile creare un account specifico dell'app anche da Impostazioni di sistema.

log automatically if my account exists 

Beh, non sono sicuro di aver compreso correttamente la richiesta. Una volta archiviato l'account nei metadati di AccountManager, è disponibile una volta chiamato AccountManager.getAccountsByType ("my.account.type"). Se si desidera effettuare l'accesso automaticamente, è necessario memorizzare le credenziali in un luogo che è ovviamente minacciato da perdite di dati sensibili.

if the auto authentication doesn't work get a new token on the server 

esiste un metodo AccountManager.invalidateAuthToken() che rimuove attualmente memorizzati authToken e chiede un altro.

È possibile avviare l'esempio app, penso che potrebbe risolvere almeno alcuni dei vostri problemi perché copre la seguente logica:

  • login/registrazione
  • autenticazione invalidazione gettone
  • visualizzazione attualmente connesso conti
  • Logout

Acclamazioni

Problemi correlati