Question

I've been developing for Android for some time now and currently working with syncing with my server.
Quick introduction: I've read about Sync Adapter and do know its role but I just want to know if it's my best option.

In my app user can click on a button to notify something is important to him. On click I'd like to update the server to keep the data, as well as notify his relatives. My problem comes as follows: The user can click that said button several times switching it on and off so in that case I don't want to open communication with the server each time the user clicks a button, it might not even change state from its previous state.

So my question is: Is sync adapter the right thing for me or should I build my own class to talk to the server that will check that, as well as receive urgent\non-urgent like Volley's. If someone could clarify the exact work of Sync Adapter I'd really appreciate it (Does it do what I stated?)

If something isn't clear i'd be happy to clarify. Thanks in advance.

No correct solution

OTHER TIPS

Android sync framework should be pretty good for your use. If you mark a sync as needed, the system will not launch it right now, but delay it for a small time. This way, if the user switch back the button, you'll be able to notice that no value has changed. Sidenote: if you use a ContentProvider, it notifies the SyncAdapter automagically when data changes. You can also trigger a sync manually if needed.

What the sync framework do is just calling a method (onPerformSync). You're free to implement it as you want. You can skip a sync if you think the last one was too close, or find if data has really changed, or it's back to original value (you can for example keep the "last synced" value in your database, then you can compare it to the current value in your onPerformSync method. If it's the same, no change).

Bonus: you'll save battery power, as the sync framework run multiple syncs in sequence as much as possible, your users will be able to manage their accounts in a centralized place (Android settings), disable sync system-wide (think about Sony's stamina-mode, setting every SyncAdapter in pause while active).

You could also take another approach, pushing from your server to the device, your app does not have to ask from time to time for updates, instead its the server that should tell "hey, i've got something for you".

Have a look at Google Cloud Messaging. On the other hand, if you prefer the approach that the user should specifically ask for his updates then you don't really need to bother if sync adapters - ofcourse, this depends on your app's requirements.

Still, I'd recommend you have a look at GCM, it's cleaner and more elegant for the server to notify then to keep asking.

Run a sync adapter when data changes on the device. This option allows you to send modified data from the device to a server, and is especially useful if you need to ensure that the server always has the latest device data. This option is straightforward to implement if you actually store data in your content provider. If you're using a stub content provider, detecting data changes may be more difficult.

Run the sync adapter in response to a user action. However, to provide the best user experience you should rely primarily on one of the more automated options.

You can run your sync adapter periodically by setting a period of time to wait between runs, or by running it at certain times of the day, or both. Running your sync adapter periodically allows you to roughly match the update interval of your server.

Run the Sync Adapter When Content Provider Data Changes

public class MainActivity extends FragmentActivity {
...
// Constants
// Content provider scheme
public static final String SCHEME = "content://";
// Content provider authority
public static final String AUTHORITY = "com.example.android.datasync.provider";
// Path for the content provider table
public static final String TABLE_PATH = "data_table";
// Account
public static final String ACCOUNT = "default_account";
// Global variables
// A content URI for the content provider's data table
Uri mUri;
// A content resolver for accessing the provider
ContentResolver mResolver;
...
public class TableObserver extends ContentObserver {
    /*
     * Define a method that's called when data in the
     * observed content provider changes.
     * This method signature is provided for compatibility with
     * older platforms.
     */
    @Override
    public void onChange(boolean selfChange) {
        /*
         * Invoke the method signature available as of
         * Android platform version 4.1, with a null URI.
         */
        onChange(selfChange, null);
    }
    /*
     * Define a method that's called when data in the
     * observed content provider changes.
     */
    @Override
    public void onChange(boolean selfChange, Uri changeUri) {
        /*
         * Ask the framework to run your sync adapter.
         * To maintain backward compatibility, assume that
         * changeUri is null.
        ContentResolver.requestSync(ACCOUNT, AUTHORITY, null);
    }
    ...
}
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    // Get the content resolver object for your app
    mResolver = getContentResolver();
    // Construct a URI that points to the content provider data table
    mUri = new Uri.Builder()
              .scheme(SCHEME)
              .authority(AUTHORITY)
              .path(TABLE_PATH)
              .build();
    /*
     * Create a content observer object.
     * Its code does not mutate the provider, so set
     * selfChange to "false"
     */
    TableObserver observer = new TableObserver(false);
    /*
     * Register the observer for the data table. The table's path
     * and any of its subpaths trigger the observer.
     */
    mResolver.registerContentObserver(mUri, true, observer);
    ...
}
...

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top