Android Open Source - sunshine Sunshine Sync Adapter






From Project

Back to project page sunshine.

License

The source code is released under:

Apache License

If you think the Android project sunshine listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.zmb.sunshine.sync;
//from  ww w . ja  v  a 2s  .  c om
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncRequest;
import android.content.SyncResult;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;

import com.zmb.sunshine.R;
import com.zmb.sunshine.Sunshine;
import com.zmb.sunshine.data.IWeatherDataParser;
import com.zmb.sunshine.data.db.WeatherContract;
import com.zmb.sunshine.data.openweathermap.OpenWeatherMapParser;
import com.zmb.sunshine.data.worldweatheronline.WorldWeatherOnlineParser;
import com.zmb.sunshine.widget.SunshineWidget;
import com.zmb.utils.IoUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;

public class SunshineSyncAdapter extends AbstractThreadedSyncAdapter {

    private static final String TAG = SunshineSyncAdapter.class.getSimpleName();
    private static final int DAYS_TO_FETCH = 14;

    public static final int SYNC_INTERVAL_SECONDS = 60 * 60 * 3;
    public static final int SYNC_FLEXTIME = SYNC_INTERVAL_SECONDS / 3;

    public SunshineSyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority,
            ContentProviderClient provider, SyncResult syncResult) {
        String location = Sunshine.getPreferredLocation(getContext());
        HttpURLConnection connection = null;
        IWeatherDataParser parser = getParser();
        try {
            removeOldWeatherData();

            URL url = parser.buildUrl(location, DAYS_TO_FETCH);
            Log.v(TAG, "Querying " + url.toString());

            connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            InputStream inputStream = connection.getInputStream();
            String response = IoUtils.readAll(inputStream);
            parser.parse(getContext(), response, DAYS_TO_FETCH);

            // update any widgets with the new data
            SunshineWidget.updateAllWidgets(getContext());

        } catch (IOException e) {
            Log.e(TAG, "Failed to fetch weather", e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    private IWeatherDataParser getParser() {
        Context c = getContext();
        String provider = PreferenceManager.getDefaultSharedPreferences(c)
                .getString(c.getString(R.string.pref_weather_provider_key),
                        c.getString(R.string.pref_weather_provider_default));
        if (provider.equals(c.getString(R.string.pref_weather_provider_openweathermap))) {
            return new OpenWeatherMapParser();
        } else {
            return new WorldWeatherOnlineParser();
        }
    }


    /**
     * A helper to get the fake account used with the SyncAdapter.
     * @param context
     * @return
     */
    static Account getSyncAccount(Context context) {
        AccountManager accountManager = AccountManager.get(context);
        Account account = new Account(context.getString(R.string.app_name),
                context.getString(R.string.sync_account_type));

        // if we don't have a password associated with the account, then the account doesn't exist yet
        if (accountManager.getPassword(account) == null) {
            // create the account (empty password and no user data)
            if (!accountManager.addAccountExplicitly(account, "", null)) {
                return null;
            }
            onAccountCreated(account, context);
        }
        return account;
    }

    static void configurePeriodicSync(Context context, int intervalSeconds, int flexTime) {
        Account acct = getSyncAccount(context);
        String authority = context.getString(R.string.content_authority);
        Bundle extras = new Bundle();
        // in kitkat (API 19) and up, we can use inexact repeating alarms
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            SyncRequest request = new SyncRequest.Builder()
                    .setExtras(extras) // shouldn't have to do this - Android 5.0 bug
                    .syncPeriodic(intervalSeconds, flexTime)
                    .setSyncAdapter(acct, authority).build();
            ContentResolver.requestSync(request);
        } else {
            ContentResolver.addPeriodicSync(acct, authority, extras, intervalSeconds);
        }
    }

    public static void initialize(Context context) {
        // just make sure that an account has been created
        getSyncAccount(context);
    }

    /**
     * A helper method to start a sync immediately.
     * @param context used to access the account service
     */
    public static void syncNow(Context context) {
        Bundle bundle = new Bundle();
        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
        bundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
        ContentResolver.requestSync(getSyncAccount(context),
                context.getString(R.string.content_authority), bundle);
    }

    /**
     * Initial setup that we run when an acount is created.
     * @param newAccount
     * @param context
     */
    private static void onAccountCreated(Account newAccount, Context context) {
        SunshineSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL_SECONDS, SYNC_FLEXTIME);
        ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);
    }

    private void removeOldWeatherData() {
        String today = WeatherContract.convertDateToString(new Date());
        String where = WeatherContract.WeatherEntry.COLUMN_DATETEXT + " < ?";
        getContext().getContentResolver().delete(
                WeatherContract.WeatherEntry.CONTENT_URI, where, new String[] { today });
    }
}




Java Source Code List

com.zmb.sunshine.ApplicationTest.java
com.zmb.sunshine.DetailActivity.java
com.zmb.sunshine.DetailFragment.java
com.zmb.sunshine.ForecastAdapter.java
com.zmb.sunshine.ForecastFragment.java
com.zmb.sunshine.MainActivity.java
com.zmb.sunshine.SettingsActivity.java
com.zmb.sunshine.SettingsFragment.java
com.zmb.sunshine.Sunshine.java
com.zmb.sunshine.data.AWeatherDataParser.java
com.zmb.sunshine.data.Convert.java
com.zmb.sunshine.data.DayForecast.java
com.zmb.sunshine.data.DayOfWeek.java
com.zmb.sunshine.data.IWeatherDataParser.java
com.zmb.sunshine.data.WeatherParseException.java
com.zmb.sunshine.data.WeatherProvider.java
com.zmb.sunshine.data.db.AndroidDatabaseManager.java
com.zmb.sunshine.data.db.WeatherContract.java
com.zmb.sunshine.data.db.WeatherDbHelper.java
com.zmb.sunshine.data.openweathermap.OpenWeatherMapParser.java
com.zmb.sunshine.data.worldweatheronline.WorldWeatherOnlineParser.java
com.zmb.sunshine.sync.DummyAuthenticatorService.java
com.zmb.sunshine.sync.DummyAuthenticator.java
com.zmb.sunshine.sync.SunshineSyncAdapter.java
com.zmb.sunshine.sync.SunshineSyncService.java
com.zmb.sunshine.widget.SunshineWidget.java
com.zmb.utils.IoUtils.java