Pregunta

Estoy implementando un sistema de inicio de sesión para una aplicación Android que utiliza el sistema de cuentas incorporado (con las API de AccountManager).

Todo está bien en Android 2.2+, pero en Android 2.1 sin incluir un SyncAdapter causa reinicios en la pantalla de configuración de la cuenta (ver http://code.google.com/p/android/issues/detail?id=5009 y AccountManager sin un SyncAdapter?)

Para evitar esto, implementé un syncAdapter, que solo devuelve null de IBinder onBind(Intent intent), y agregó las cosas relevantes al manifiesto. Esto resuelve el problema de reinicio en Android 2.1.

Sin embargo, introduce un problema adicional: después de agregar una cuenta, el sistema Android, algún tiempo después, iniciará una sincronización de cuenta. Aunque no ocurren errores (de hecho, mi syncAdapter no hace nada, no tiene forma de causar errores a menos que regrese null), el icono de sincronización permanece atascado en la barra de notificaciones en la parte superior. Esto da como resultado que el sistema de sincronización de Android mantenga un Lock de estela permanente, evitando que el dispositivo duerma.

La cuenta no enumera ningún componente sincronizable en la pantalla de configuración de la cuenta (en el encabezado de 'datos y sincronización'), y siempre muestra 'sincronización' para el estado de sincronización en la lista de cuentas (incluso mientras el icono de sincronización es visible en La barra de notificaciones). Desactivar la sincronización de la cuenta no elimina el problema. Eliminar la cuenta detiene el problema.

Supongo que no debería regresar nulo. ¿Debería devolver una implementación básica de ThreadedSynCadapter? Cualquier ayuda para obtener un sistema de cuenta sin una sincronización asociada que funcione correctamente en 2.1 y 2.2+ es muy apreciada.

¿Fue útil?

Solución 2

Resolví mi propio problema: no puedes regresar null desde el onBind Método de su servicio: debe devolver el IBinder de una AbstractThreadedSyncAdapter.

Esto tiene el efecto no deseado de agregar una entrada a la sección de datos y sincronización de la página de configuración de la cuenta, a pesar de que mi implementación de AbstractThreadedSyncAdapter no hace nada; Esperaba evitar esto.

Para resumir, para utilizar el sistema de cuentas en Android debe:

  • Implementar un servicio que tenga un IntentFilter por android.content.SyncAdapter.
  • Este servicio debe devolver el IBinder de una AbstractThreadedSyncAdapter Implementación de IT es onBind método.
  • Esto luego requiere que tengas un ContentProvider (puede ser solo una implementación de stub) que se conoce como el contentAuthority En su archivo XML SyncAdapter.
  • Esto tiene la desventaja de que su ContentProvider se enumera en el encabezado de datos y sincronización en la página de configuración de su cuenta.

Otros consejos

Dado que esta es la única pregunta que he visto relacionada con este problema, aquí hay una respuesta de año tardío. También me encontré con el problema permanente de bloqueo de wake debido al sistema de Android que sincroniza mi cuenta personalizada automáticamente.

La mejor manera de manejar esto, que requiere un código mínimo y en realidad lo hace para que la cuenta nunca se sincronice a menos que se llame específicamente para sincronizar en el código:

ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);

Ahora esto requiere que en el momento en que cree su cuenta llame a este método estático. Mientras que el primer parámetro es la cuenta para establecer esta configuración, el segundo parámetro es la autoridad de ContentProvider usado, y el tercero es el entero que cuando se establece en un número positivo permite sincronizar, cuando se establece en 0 deshabilitados y cuando se establece en cualquier otra cosa lo hace desconocido. La autoridad para usar se puede encontrar dentro de su "sync_something.xml" bajo el atributo ContentAuthority, que utiliza su syncAdapter:

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts" 
android:accountType="com.myapp.account"/> <!-- This being your own account type-->

El archivo XML anterior se especifica dentro de la parte del servicio de su AndroidManifest.xml:

<service android:name=".DummySyncAdapterService"
        exported="true"
        android:process=":contacts">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter" 
            android:resource="@xml/sync_something" /> <!--This points to your SyncAdapter XML-->
    </service>

Este es el fragmento de código que uso para crear mi cuenta personalizada dentro de mi LoginActivity:

Account account = new Account("John Doe", "com.myapp.account");
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);
AccountManager am = AccountManager.get(LoginActivity.this);
boolean accountCreated = am.addAccountExplicitly(account, "Password", null);
Bundle extras = LoginActivity.this.getIntent().getExtras();
if(extras != null){
    if (accountCreated) { 
        AccountAuthenticatorResponse response = extras.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
        Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, "John Doe");
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, "com.myapp.account");
        response.onResult(result);
    }
}

La gran parte de esto es que cuando el sistema intenta sincronizar el servicio, verifica si el servicio es sincronizado primero, si se establece en falso, cancela la sincronización. Ahora no tienes que crear el tuyo ContentProvider Tampoco tu ContentProvider Se muestre bajo datos y sincronización. Sin embargo, debe tener una implementación de Stub de AbstractThreadedSyncAdapter que devuelve un Ibinder dentro de su método de Onbind. Y por último, pero no menos importante, hace que un usuario no pueda habilitar la sincronización o usar el botón "Sync Now" para esta cuenta a menos que haya agregado la funcionalidad dentro de su aplicación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top