1 /* 2 * Copyright 2013 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.basicsyncadapter; 18 19 import android.accounts.Account; 20 import android.accounts.AccountManager; 21 import android.annotation.TargetApi; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.os.Build; 25 import android.os.Bundle; 26 import android.preference.PreferenceManager; 27 28 import com.example.android.common.accounts.GenericAccountService; 29 import com.example.android.basicsyncadapter.provider.FeedContract; 30 31 /** 32 * Static helper methods for working with the sync framework. 33 */ 34 public class SyncUtils { 35 private static final long SYNC_FREQUENCY = 60 * 60; // 1 hour (in seconds) 36 private static final String CONTENT_AUTHORITY = FeedContract.CONTENT_AUTHORITY; 37 private static final String PREF_SETUP_COMPLETE = "setup_complete"; 38 // Value below must match the account type specified in res/xml/syncadapter.xml 39 public static final String ACCOUNT_TYPE = "com.example.android.basicsyncadapter.account"; 40 41 /** 42 * Create an entry for this application in the system account list, if it isn't already there. 43 * 44 * @param context Context 45 */ 46 @TargetApi(Build.VERSION_CODES.FROYO) 47 public static void CreateSyncAccount(Context context) { 48 boolean newAccount = false; 49 boolean setupComplete = PreferenceManager 50 .getDefaultSharedPreferences(context).getBoolean(PREF_SETUP_COMPLETE, false); 51 52 // Create account, if it's missing. (Either first run, or user has deleted account.) 53 Account account = GenericAccountService.GetAccount(ACCOUNT_TYPE); 54 AccountManager accountManager = 55 (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); 56 if (accountManager.addAccountExplicitly(account, null, null)) { 57 // Inform the system that this account supports sync 58 ContentResolver.setIsSyncable(account, CONTENT_AUTHORITY, 1); 59 // Inform the system that this account is eligible for auto sync when the network is up 60 ContentResolver.setSyncAutomatically(account, CONTENT_AUTHORITY, true); 61 // Recommend a schedule for automatic synchronization. The system may modify this based 62 // on other scheduled syncs and network utilization. 63 ContentResolver.addPeriodicSync( 64 account, CONTENT_AUTHORITY, new Bundle(),SYNC_FREQUENCY); 65 newAccount = true; 66 } 67 68 // Schedule an initial sync if we detect problems with either our account or our local 69 // data has been deleted. (Note that it's possible to clear app data WITHOUT affecting 70 // the account list, so wee need to check both.) 71 if (newAccount || !setupComplete) { 72 TriggerRefresh(); 73 PreferenceManager.getDefaultSharedPreferences(context).edit() 74 .putBoolean(PREF_SETUP_COMPLETE, true).commit(); 75 } 76 } 77 78 /** 79 * Helper method to trigger an immediate sync ("refresh"). 80 * 81 * <p>This should only be used when we need to preempt the normal sync schedule. Typically, this 82 * means the user has pressed the "refresh" button. 83 * 84 * Note that SYNC_EXTRAS_MANUAL will cause an immediate sync, without any optimization to 85 * preserve battery life. If you know new data is available (perhaps via a GCM notification), 86 * but the user is not actively waiting for that data, you should omit this flag; this will give 87 * the OS additional freedom in scheduling your sync request. 88 */ 89 public static void TriggerRefresh() { 90 Bundle b = new Bundle(); 91 // Disable sync backoff and ignore sync preferences. In other words...perform sync NOW! 92 b.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true); 93 b.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true); 94 ContentResolver.requestSync( 95 GenericAccountService.GetAccount(ACCOUNT_TYPE), // Sync account 96 FeedContract.CONTENT_AUTHORITY, // Content authority 97 b); // Extras 98 } 99 }