Let's take a look at what it will take
to implement a very basic SyncAdapter.
We're going to write two services.
Each service serves the primary purpose
of delivering an object that represents
an Android Binder interface to one of the system frameworks.
A Binder is actually the low-level glue
that implements cross process cross process communication in Android.
You've been using Binders every time you talk
to an Android system service.
Intents and content providers are just high-level abstractions
on top of the Binder interface.
There's a whole language known as AIDL to help define these interfaces.
We're not going to cover all this here,
but there's a lot more you can do with services and Binders.
One more thing before we start, we're going to define
an Authenticator Service and an Authenticator.
But it will only be used by the Android accounts framework
to allow us to create an account. SyncAdaptor's need an account.
And the account framework requires
that there be an authenticator delivered by an authenticator Service.
You'll see that our authenticator is just a series of stubs,
with exceptions that get thrown
for each call just to prove that it isn't really used.
One final note. This section approximately
follows the online training at developer.android.com
around sync adapters.
Feel free to look there if you have
any more questions.
We're going to create a new package, sync, to house all of this goodness.
And a new class file for our authenticator.
This code that we're about to paste in really just comes
from the developer.android.com website,
and as I mentioned earlier, it's just a stub.
You can tell because we throw exceptions for calling
any of the functions except for the constructor.
And one more file. Create SunshineAuthenticatorService.
This is more code that is written for us.
It allows the account manager to access the empty authenticator
that we just pasted in.
Now we add the account type in our strings.xml.
The account type string suggests that it is specific to our app.
If we had many applications using the same account,
we might want to create just an example.com account.
We'll also begin to clean things up and add a content authority string.
Note that this matches our content provider string.
We'll fix the XML file later so they both use this same string.
We create a new XML resource file, filename authenticator.xml,
with root element account-authenticator.
And you probably noticed that SunshineAuthenticatorService
is actually a service that needs to be registered
with a package manager in AndroidManifest.xml.
Here's some more pastey goodness that does just that.
Now be very, very careful.
These strings all have to match precisely.
The error messages that the system gives for having incorrect accounts
are not necessarily intuitive. And with that,
you should be able to create valid accounts.
Once again, this is all just so that the SyncAdapter
can be tied to an account.
You don't actually use this at all.
All right, let's tweak our provider tag in the manifest.
We're going to add the syncable attribute.
This just let's Android know that we're planning to synchronize
the content provider with the server.
Also, we'll set android:exported equals false.
We had it at the default setting,
which means that other apps could see our content.
Finally, let's change the authority to use our new string.
Now, for some additional permissions.
We need to be able to read and write sync settings.
That makes sense.
We also have to authenticate accounts, even though we're not really using them
for anything.
None of these permissions are ones users
should be concerned about.
But as developers, we always want
to be careful when we have to add new permissions.
Let's create the SunshineSyncAdapter file itself inside of sync,
which extends the abstract threaded sync adapter class.
Hit Ctrl+I and then Ctrl+O
to implement the necessary abstract methods in constructor.
We'll use the first constructor. We'll fill this out later.
As you may recall, the sync adaptor pattern requires yet another service.
So we're going to create another Java class
called SunshineSyncService.
This class is used to deliver the sync adapter Binder to the sync manager.
The Binder is implemented for us by the abstract threaded sync adapter class.
And returned in the getSyncAdapterBinder method.
And now, we need one more XML file.
Create syncadapter.xml with root element sync-adapter.
Once again, this XML file defines the settings associated with our sync-adapter,
including it's content authority. The account type that it syncs.
Whether or not it's user visible. Whether it supports uploading,
which changes the way the content provider
interacts with the sync adapter.
Allowing parallel syncs and is always syncable.
These settings make sense for this particular application,
and I bet you know what comes next.
You're right.
You have to register the sync adapter service
with the package manager.
And therefore we have to create
more manifest entries, containing some important metadata.
Most importantly, links to the file we just created.
All right, now we're getting close.
Let's start working on the sync adapter, itself.
We'll start with a helper function to get the dummy sync account
and make sure that it has been created.
Then, we'll add another helper function to our sync adaptor,
to make it easier to test our sync adaptor.