API de Dropbox de Android que no guarda el inicio de sesión
Soy una especie de principiante en la programación de Android. He estado tratando de conseguir que Dropbox se integre en [los comienzos de] una aplicación que estoy escribiendo. He seguido las instrucciones y he visto el ejemplo básico DBRoulette que viene con la API de Dropbox.
El problema que me sigue corriendo es que me registro en Dropbox (a través de navegador web) y luego confirmar que la aplicación puede utilizar su carpeta de la aplicación Dropbox … Para esa sesión funciona bien, pero luego cuando cierro la aplicación totalmente y abrirlo nuevamente, me piden que vuelva a iniciar sesión! Definitivamente no quiero tener que volver a escribir todas mis cosas de inicio de sesión de dropbox de nuevo, incluso si esto es sólo para propósitos de depuración. Lo interesante es que DBRoulette funciona bien, no tengo que iniciar sesión cada vez! Y copia copié gran parte del código funcional de ese ejemplo.
- Integre Dropbox en la aplicación Android, pero sin iniciar sesión
- Cómo compartir la carpeta de aplicaciones con otro usuario de Dropbox
- Documentación de Dropbox android sdk
- Permitir que la API de Dropbox acceda a mi cuenta en el dispositivo del usuario
- Dropbox Sync API - Error de enlace no satisfecho
Mientras estamos en ello, ¿qué exactamente contienen / hacen los AccessTokens? ¿Guardan la información para crear una sesión autorizada? ¿Es esta información diferente de la clave de la aplicación / combo secreto que obtengo del sitio de desarrollo de Dropbox? Creo que aquí es donde está mi error, pero no estoy seguro.
Aquí está la actividad:
package com.JS.music; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.dropbox.client2.DropboxAPI; import com.dropbox.client2.android.AndroidAuthSession; import com.dropbox.client2.session.AccessTokenPair; import com.dropbox.client2.session.AppKeyPair; import com.dropbox.client2.session.TokenPair; import com.dropbox.client2.session.Session.AccessType; public class MainActivity extends Activity { private static String TAG = "MainActivity"; private Button gotoRecordingButton; private Button libraryButton; //Dropbox final static private String APP_KEY = "xxxxxxxxxxxxx"; final static private String APP_SECRET = "xxxxxxxxxxxxxx"; final static private AccessType ACCESS_TYPE = AccessType.APP_FOLDER; private DropboxAPI<AndroidAuthSession> mDBApi; final static public String ACCOUNT_PREFS_NAME = "MusicDBPrefs"; final static public String ACCESS_KEY_NAME = "Music_DB_ACCESS_KEY"; final static public String ACCESS_SECRET_NAME = "Music_DB_ACCESS_SECRET"; private boolean mIsLoggedIn = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gotoRecordingButton = (Button) findViewById(R.id.goto_recording_button); gotoRecordingButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, RecordActivity.class); startActivity(intent); } }); libraryButton = (Button) findViewById(R.id.library_button); libraryButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }); AndroidAuthSession session = buildSession(); mDBApi = new DropboxAPI<AndroidAuthSession>(session); mDBApi.getSession().startAuthentication(MainActivity.this); setLoggedIn(mDBApi.getSession().isLinked()); Toast msg = Toast.makeText(this, "logged in: " + isLoggedIn(), Toast.LENGTH_LONG); msg.show(); } @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; } //-------------Dropbox stuff for testing and debugging--------- @Override protected void onResume() { super.onResume(); AndroidAuthSession session = mDBApi.getSession(); // The next part must be inserted in the onResume() method of the // activity from which session.startAuthentication() was called, so // that Dropbox authentication completes properly. if (session.authenticationSuccessful()) { try { // Mandatory call to complete the auth session.finishAuthentication(); // Store it locally in our app for later use TokenPair tokens = session.getAccessTokenPair(); storeKeys(tokens.key, tokens.secret); setLoggedIn(true); } catch (IllegalStateException e) { Log.i(TAG, "Error authenticating", e); } } } //copied from dropbox API private void storeKeys(String key, String secret) { // Save the access key for later SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0); Editor edit = prefs.edit(); edit.putString(ACCESS_KEY_NAME, key); edit.putString(ACCESS_SECRET_NAME, secret); edit.commit(); } private String[] getKeys() { SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0); String key = prefs.getString(ACCESS_KEY_NAME, null); String secret = prefs.getString(ACCESS_SECRET_NAME, null); if (key != null && secret != null) { Log.i(TAG,"Got keys"); String[] ret = new String[2]; ret[0] = key; ret[1] = secret; return ret; } else { return null; } } private AndroidAuthSession buildSession() { AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET); AndroidAuthSession session; String[] stored = getKeys(); if (stored != null) { AccessTokenPair accessToken = new AccessTokenPair(stored[0], stored[1]); session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE, accessToken); } else { session = new AndroidAuthSession(appKeyPair, ACCESS_TYPE); } return session; } public void setLoggedIn(boolean loggedIn) { mIsLoggedIn = loggedIn; } public boolean isLoggedIn() { return mIsLoggedIn; } }
¡Cualquier ayuda apreciada!
- Cómo importar Dropbox Chooser SDK en Android Studio?
- Uso de los detalles de autenticación de Dropbox guardados en Android
- Uso de la API de Dropbox para cargar un archivo con Android
- Almacenamiento de claves API en Android, ¿es obfustificación suficiente?
- Gradle release build con proguard: java.lang.IncompatibleClassChangeError y java.lang.NoSuchMethodError
- Lectura del archivo .txt desde un enlace compartido desde un dropbox Android studio
- ¿Cómo puedo obtener mi APP_KEY y SECRET_KEY para la sincronización de Dropbox?
- ¿Cómo autenticar varias cuentas en Android dropbox sdk 1.5.1?
La idea principal cuando se utiliza DropboxApi es: en la 1 ª vez cuando se conectó debe obtener claves secretas, la próxima vez que debe utilizar estas teclas para el acceso sin confirmar a través del navegador.
es decir, en onResume método que debe utilizar esta línea
AccessTokenPair tokens = mDBApi.getSession().getAccessTokenPair();
donde DropboxAPI mDBApi;
A continuación, debe guardar los datos de
AccessTokenPair tokens
en sqlite o SharedPrefs.
Entonces debe usar un método como este:
private DropboxAPI <AndroidAuthSession> getDropboxAPI(){ AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET); AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE); mDBApi = new DropboxAPI<AndroidAuthSession>(session); AccessKeys keys = dm.getAccessKeys(APP_KEY); //dm is DatabaseManager of ORMLite if (keys == null) return null; AccessTokenPair access = new AccessTokenPair(keys.getAccessKey(), keys.getAccessSecret()); mDBApi.getSession().setAccessTokenPair(access); return mDBApi; }
…
AccessKeys es la clase donde almacené las claves vía ORMLite:
@DatabaseTable public class AccessKeys { ... @DatabaseField private String accessKey; @DatabaseField private String accessSecret; @DatabaseField private String appKey; @DatabaseField private String appSecret; ...}
Y una última cosa: cuando tienes todas las claves no debes correr
mDBApi.getSession().startAuthentication(MainActivity.this);
sólo usa mDBApi para tus objetivos, como "mDBApi.putFile (algunos datos)"
Nota: Sólo es necesario hacer startAuthentication () una vez, no es necesario ejecutarlo para autorizar el par de claves desde el inicio de sesión actual.
Sé que es una vieja pregunta, pero respondiéndola por si alguien tropieza con ella.
En cuanto al principal problema descrito – que tiene que iniciar sesión en Dropbox de nuevo cada vez, eso es simplemente porque tiene esta línea cerca del final de onCreate ()
mDBApi.getSession().startAuthentication(MainActivity.this);
startAuthentication () siempre inicia un nuevo flujo de "inicio de sesión", no importa si ya tiene una sesión válida o no. Por esta razón no deberías llamarlo cada vez.
La respuesta aceptada es buena, pero se puede salir con el uso de menos código, guardando el accessToken. Así que primero, en onResume () después de finishAuthentication () usted guardaría el accessToken como este
String accessToken = mDBApi.getSession().getOAuth2AccessToken(); // save accessToken to SQLite or SharedPrefs or whatever
Entonces, el método getDropboxAPI () sugerido por @Alexandr debería tener este aspecto
private DropboxAPI <AndroidAuthSession> getDropboxAPI() { AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET); AndroidAuthSession session = new AndroidAuthSession(appKeys, ACCESS_TYPE); mDBApi = new DropboxAPI<AndroidAuthSession>(session); String savedAccessToken = // get previously saved accessToken if (!TextUtils.isEmpty(savedAccessToken)) { mDBApi.getSession().setOAuth2AccessToken(savedAccessToken); } return mDBApi; }
También es una buena idea crear un método auxiliar como este para comprobar si Dropbox está correctamente inicializado antes de usarlo para trabajos reales, como subir o descargar archivos.
public boolean isDropboxLinked() { return mDBApi != null && (mDBApi.getSession().isLinked() || mDBApi.getSession().authenticationSuccessful()); }
- Cómo cambiar la forma predeterminada del icono de la aplicación en Android Studio
- Problema con gradle experimental: El plugin android debe ser aplicado al proyecto