Guys following this issue,

I found the ultimate cause of the error and found a workaround that
will allow you to work on a Droid.

One thing that's helpful is building yourself an Eclair 2.1 SDK so you
can use an emulator (2.1) that includes the "Accounts & Sync" settings
option we need in working with accounts:

-------------------------------------
>From the the root of the android source tree:
. build/envsetup.sh
lunch sdk-eng
make sdk (may want to use -j<something> based on your number of cores)

find the SDK in out/host/linux/sdk/...

>From the SDK, copy platforms/android-#.# into your SDK/platform on
your destination pc.

If that's running windows, copy platforms/android-2.0/tools/* into
your newly created platforms tools folder.

Use the AVD Manager to create an AVD for this new platform.
-----------------------------------------------


The crash is caused by an undocumented assumption in the Android code
that handles accounts and sync.  They are *very* closely related.  It
turns out that the "Accounts and Sync" settings plugin after getting
the accounts on the system, uses the content service to scan for
services on the system that implement the intent
"android.content.SyncAdapter".

Since our code doesn't implement this, the search came up empty handed
and since the code assumed this would never happen, BAM, null pointer
exception and crash.

It turns out that the solution is to have your application (or
something on the system) implement a service that catches the intent
"android.content.SyncAdapter" that returns an IBinder to an object
that extends AbstractThreadedSyncAdapter (just like we did for our
AbstractAccountAuthenticator).

I took examples from the source code for the Email application in
android, but here are the relevant bits to setup an empty sync adapter
for contacts that does nothing but gets you past the exception:

AndroidManifest.xml:
----------------------------------------------------------------------------
<!--Required stanza to register the ContactsSyncAdapterService with
SyncManager -->
<service
android:name="com.YOURDOMAIN.YOURAPP.ContactsSyncAdapterService"
             android:exported="true">
    <intent-filter>
        <action android:name="android.content.SyncAdapter" />
    </intent-filter>
        <meta-data android:name="android.content.SyncAdapter"
                   android:resource="@xml/syncadapter_contacts" />
</service>

xml/syncadapter_contacts - :
--------------------------------------------------------------------------------
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/
android"
    android:contentAuthority="com.android.contacts"
    android:accountType="com.YOURDOMAIN.YOURAPP"
/>

ContactSyncAdapter:
=====================================
public class ContactsSyncAdapterService extends Service {
        private static final String TAG = "ContactsSyncAdapterService";
        private static SyncAdapterImpl sSyncAdapter = null;
        private static final Object sSyncAdapterLock = new Object();

        public ContactsSyncAdapterService() {
                super();
        }

    private static class SyncAdapterImpl extends
AbstractThreadedSyncAdapter {
        private Context mContext;

        public SyncAdapterImpl(Context context) {
                super(context, true /* autoInitialize */);
                mContext = context;
        }

        @Override
        public void onPerformSync(Account account, Bundle extras,
                        String authority, ContentProviderClient provider,
SyncResult syncResult) {
                try {
                        ContactsSyncAdapterService.performSync(mContext, 
account,
extras,
                                authority, provider, syncResult);
                } catch (OperationCanceledException e) {
                }
        }
        }

    @Override
    public void onCreate() {
        super.onCreate();
        synchronized (sSyncAdapterLock) {
            if (sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapterImpl
(getApplicationContext());
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return sSyncAdapter.getSyncAdapterBinder();
    }

    private static void performSync(Context context, Account account,
Bundle extras,
            String authority, ContentProviderClient provider,
SyncResult syncResult)
            throws OperationCanceledException {
        ContentResolver cr = context.getContentResolver();
        Log.i(TAG, "performSync: " + account.toString());
    }
}

On Nov 23, 8:46 pm, Dan Dumont <[email protected]> wrote:
> Nice, thanks for doing that!    I'll star it, I hope we get a response soon.
>
>
>
> On Mon, Nov 23, 2009 at 5:32 PM, Jerry Brady <[email protected]> wrote:
> > Just filed a case for this:
>
> >http://code.google.com/p/android/issues/detail?id=5009
>
> > On Nov 23, 1:47 pm, Jerry Brady <[email protected]> wrote:
> > > Dan,
>
> > > My code and yours both work on the Droid, but there are some nasty
> > > side-effects.  After adding an account with your application (or mine)
> > > whenever you visit the "Accounts & Sync" settings screen, the system
> > > crashes hard and reboots.
>
> > > 11-23 13:21:34.863: WARN/dalvikvm(1011): threadid=13: thread exiting
> > > with uncaught exception (group=0x4001b180)
> > > 11-23 13:21:34.863: ERROR/AndroidRuntime(1011): Uncaught handler:
> > > thread android.server.ServerThread exiting due to uncaught exception
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011): *** EXCEPTION IN
> > > SYSTEM PROCESS.  System will crash.
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):
> > > java.lang.NullPointerException
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > com.android.settings.ManageAccountsSettings.onSyncStateUpdated
> > > (ManageAccountsSettings.java:187)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > com.android.settings.ManageAccountsSettings.onAccountsUpdated
> > > (ManageAccountsSettings.java:244)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > android.accounts.AccountManager$10.run(AccountManager.java:389)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > android.os.Handler.handleCallback(Handler.java:587)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > android.os.Handler.dispatchMessage(Handler.java:92)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > android.os.Looper.loop(Looper.java:123)
> > > 11-23 13:21:34.879: ERROR/AndroidRuntime(1011):     at
> > > com.android.server.ServerThread.run(SystemServer.java:428)
>
> > > I'm looking at the source now to see if I can figure out what's going
> > > on.  If necessary, I'll file a case with the project if I find a bug
> > > in the Android source.
>
> > > Cheers,
> > > Jerry
>
> > > On Nov 23, 8:18 am, Jerry Brady <[email protected]> wrote:
>
> > > > I'm going to be trying it on a Droid this morning.
>
> > > > On Nov 21, 10:07 pm, Dan Dumont <[email protected]> wrote:
>
> > > > > I get that exception in the emulator ( doesn't reboot though )
>
> > > > > I thought it was due to missing pieces of the emulator...
>
> > > > >  does logcat output anything?
>
> > > > > On Sat, Nov 21, 2009 at 7:07 PM, NitroDesk <[email protected]>
> > wrote:
> > > > > > Any of you folks tried this on a Droid?
> > > > > > Simply installing the project that contains an Authenticator in the
> > > > > > manfest and the other related items seems to cause the "Add
> > Account"
> > > > > > option in the account list on te droid to simply reoot the phone
> > with
> > > > > > an exception.
> > > > > > Anyone else seen this or find a way to avoid this ?
> > > > > > -g
>
> > > > > > On Nov 21, 9:04 am, Jerry Brady <[email protected]> wrote:
> > > > > > > Dan,
>
> > > > > > > Now I see what you are doing in your code and found the reference
> > to
> > > > > > > AddAccountExplicitly().   I want to skip returning an intent to
> > fire
> > > > > > > the an AccountAuthenticatorActivity and instead to return
> > > > > > > KEY_ACCOUNT_NAME and KEY_ACCOUNT_TYPE directly from my
> > > > > > > AbstractAccountAuthenticator's addAccount method whereas your
> > code
> > > > > > > returns an intent that fires your authentication activity.
>
> > > > > > > The main issue for me so far is that I don't see that my
> > > > > > > AbstractAccountAuthenticator is ever being instantiated.
>
> > > > > > > Cheers,
> > > > > > > Jerry
>
> > > > > > > On Nov 20, 7:53 am, Dan Dumont <[email protected]> wrote:
>
> > > > > > > > Yes.   But I make the AddAccountExplicitly call in my
> > Authenticator.
> > > > > >  You
> > > > > > > > use theAccountManagerto create accounts.
> > > > > > > > If you call AddAccountExplicitly from a non-authenticator
> > class, I
> > > > > > guess it
> > > > > > > > will work...  But I think the security behind it will mean that
> > only
> > > > > > the
> > > > > > > > class that created the account will be able to ever modify it
> > or
> > > > > > extract the
> > > > > > > > password.
>
> > > > > > > > This is why they have a framework for you to get an authtoken
> > returned
> > > > > > via
> > > > > > > > the authenticator... the logic for authenticating should be
> > buried
> > > > > > within
> > > > > > > > there, because it will be the only class allowed to peak at the
> > > > > > password and
> > > > > > > > send it wherever you are authenticating.
>
> > > > > > > > On Fri, Nov 20, 2009 at 2:16 AM, sukumar bhashyam <
>
> > > > > > > > [email protected]> wrote:
> > > > > > > > > AddAccountExplicitly() would need Authenticator of same type.
>
> > > > > > > > > I created an Authenticator and called AddAccountExplicitly()
> > for the
> > > > > > same
> > > > > > > > > type which created an account ( Could verify it from
> > > > > > > > >AccountManager.getAccounts())
>
> > > > > > > > > One strange thing I observer is none of the  implementation
> > class
> > > > > > functions
> > > > > > > > > of AbstractAccountAuthenticator is being called. I followed
> > the exact
> > > > > > steps
> > > > > > > > > in documentation. Not even onCreate or onBind function is
> > called.
> > > > > > Anyone
> > > > > > > > > seen this problem?. Is your AbstractAccountAuthenticator
> > > > > > implemetation class
> > > > > > > > > being invoked?.
> > > > > > > > > Thanks.
>
> > > > > > > > > On Thu, Nov 19, 2009 at 8:26 PM, Jerry Brady <
> > [email protected]
> > > > > > >wrote:
>
> > > > > > > > >> Dan,
>
> > > > > > > > >> Thanks for all of this.  I just returned to the office and
> > will be
> > > > > > > > >> taking a look to see how much further I can get and I will
> > certainly
> > > > > > > > >> be interested in helping with your accounts project.
>
> > > > > > > > >> I got as far as getting my account to show up in the list of
> > > > > > accounts
> > > > > > > > >> along with Google, Facebook and Exchange, but my service
> > never gets
> > > > > > > > >> called.  My addAccount() method doesn't return an intent,
> > but rather
> > > > > > > > >> KEY_ACCOUNT_NAME and KEY_ACCOUNT_TYPE in it's bundle to let
> > the
> > > > > > > > >> account request succeed.
>
> > > > > > > > >> My goal is to create an account that will only be used by my
> > > > > > > > >> application and does not need to have any features to enable
> > > > > > external
> > > > > > > > >> authentication or account configuration.
>
> > > > > > > > >> I've also tried AddAccountExplicitly() but I can't seem to
> > get
> > > > > > around
> > > > > > > > >> its UID restrictions.  The calling activity and the
> > authenticator
> > > > > > > > >> service all belong to the same application so I'm not sure
> > why the
> > > > > > > > >> system still throws an error about the UID not being
> > correct.
>
> > > > > > > > >> Cheers,
> > > > > > > > >> Jerry
>
> > > > > > > > >> On Nov 13, 11:54 pm, Dan Dumont <[email protected]> wrote:
> > > > > > > > >> > For anyone still interested.    I've made a bit of
> > progress.   The
> > > > > > > > >> google
> > > > > > > > >> > project below now creates and lists accounts of the type
> > for the
> > > > > > > > >> project!
>
> > > > > > > > >> > On Fri, Nov 13, 2009 at 9:39 PM, Dan Dumont <
> > [email protected]>
> > > > > > wrote:
> > > > > > > > >> > > To facilitate the discussion around this topic, I've
> > started up
> > > > > > a
> > > > > > > > >> project
> > > > > > > > >> > > over here:
> > > > > > > > >> > >http://code.google.com/p/androidaccounts/
>
> > > > > > > > >> > > <http://code.google.com/p/androidaccounts/>If anyone is
> > > > > > interested in
> > > > > > > > >> > > pitching in and writing some examples, let me know so I
> > can add
> > > > > > you.
> > > > > > > > >> > > The current state of the project is as far as I've
> > gotten to
> > > > > > > > >> understanding
> > > > > > > > >> > > what is available so far... and I'm stumped as to why
> > new
> > > > > > accounts
> > > > > > > > >> don't
> > > > > > > > >> > > seem to persist after their creation ( as far as the
> > > > > > AccountsTester
> > > > > > > > >> app is
> > > > > > > > >> > > concerned ).
>
> > > > > > > > >> > > On Fri, Nov 13, 2009 at 7:40 PM, Dan Dumont <
> > [email protected]>
> > > > > > > > >> wrote:
>
> > > > > > > > >> > >> I've gotten a bit further than you.
>
> > > > > > > > >> > >> The account manager seems to want to store
> > AccountName+Type
> > > > > > pairs,
> > > > > > > > >> and
> > > > > > > > >> > >> have anAccountAuthenticatorhandle the storage and dirty
> > bits of
> > > > > > the
> > > > > > > > >> actual
> > > > > > > > >> > >> authentication and credential storage.
>
> > > > > > > > >> > >> You will need to create anAccountAuthenticatorfrom the
> > > > > > > > >> > >> AbstractAccountAuthenticator class.
> > > > > > > > >> > >> You will also need to define a Service in your app.
> > See
>
> >http://developer.android.com/reference/android/accounts/AbstractAccou...
> > > > > > > > >> > >> This service must be set up in the Manifest like so:
> >  (ripped
> > > > > > from
> > > > > > > > >> link
> > > > > > > > >> > >> above)
>
> > > > > > > > >> > >>  <intent-filter>
> > > > > > > > >> > >>      <action
> > > > > > android:name="android.accounts.AccountAuthenticator" />
> > > > > > > > >> > >>    </intent-filter>
> > > > > > > > >> > >>    <meta-data
> > > > > > android:name="android.accounts.AccountAuthenticator"
> > > > > > > > >> > >>              android:resource="@xml/authenticator" />
>
> > > > > > > > >> > >> You can take a look at the link for what the resource
> > must
> > > > > > be...
>
> > > > > > > > >> > >> After you end up hooking all that crap up, you can do
> > this in...
>
> read more »

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to