定期运行同步适配器

时间:2016-02-25 07:24:10

标签: android

我已在我的应用程序中实现了同步适配器功能。我允许用户在离线模式下使用该应用程序,并且在该离线模式期间数据库中的任何更改都保存在表中,并且我希望根据定期同步功能将该表的数据同步到服务器。 我已经在设置中给出了每小时,每日和每周同步的选项。 我面临的问题是,尽管用户选择了同步频率,但只要有可用的互联网连接,表的数据就会同步。请帮我解决这个问题

4 个答案:

答案 0 :(得分:0)

看看这个简单的代码

public class TimerReceiverSyncInterval extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Log.d("TAG", "Sync OnReceive--");


    scheduleAlarms(context);
    context.startService(new Intent(context, NotificationServiceSyncInterval.class));

}

public static void scheduleAlarms(Context paramContext) {

    Calendar calendar = Calendar.getInstance();

    String[] splited = mPrefs.getSyncTime().split("\\s+");
    if (mPrefs.getSyncTime().contains("Minute")) {

        calendar.set(Calendar.MINUTE, Integer.parseInt(splited[0]));
    } else if (mPrefs.getSyncTime().contains("Hour")) {
        calendar.set(Calendar.HOUR, Integer.parseInt(splited[0]));
    }

    AlarmManager localAlarmManager = (AlarmManager) paramContext.getSystemService(Context.ALARM_SERVICE);
    PendingIntent localPendingIntent = PendingIntent.getService(paramContext, 0,
            new Intent(paramContext, NotificationServiceSyncInterval.class), PendingIntent.FLAG_UPDATE_CURRENT);

    if (mPrefs.getSyncTime().contains("Minute")) {

        localAlarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
                Integer.parseInt(splited[0]) * (60 * 1000), localPendingIntent);

    } else if (mPrefs.getSyncTime().contains("Hour")) {

        localAlarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
                Integer.parseInt(splited[0]) * (60 * 60 * 1000), localPendingIntent);

    }

    Log.d("TAG", "Sync------");

}

这里我分小时,分钟,因为我的设置包含15分钟,1小时等等,你可以根据你的要求设置它,如日,周等等。

public class NotificationServiceSyncInterval extends IntentService {

public NotificationServiceSyncInterval() {
    super("Sync Tracker Online");

}

public NotificationServiceSyncInterval(String paramString) {
    super(paramString);

}

@Override
protected void onHandleIntent(Intent intent) {


    Log.d("TAG", "Sync Handler call");
    // todo
    callSync();

}

public static void callSync() {

    try {
        //Your Sync Code here

    } catch (Exception e) {
        e.printStackTrace();
    }

}

上述课程的清单输入

    <receiver
        android:name="com.yourpackage.TimerReceiverSyncInterval"
        android:enabled="true" >
        <intent-filter android:priority="999" >
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.QUICKBOOT_POWERON" />
        </intent-filter>
    </receiver>

    <service android:name="com.yourpackage.NotificationServiceSyncInterval" >
    </service>

最后在用户选择时间间隔时分配上下文,即TimerReceiverSyncInterval.scheduleAlarms(this);

答案 1 :(得分:0)

我不知道最好的方法是什么。但您可以制作一个SharedPreference变量,例如LastSyncTime,其中包含同步时间,并且每次您在实际同步数据的onPerformSync()中进行同步时都会更新此值。

下次调用onPerformSync()时,您可以将LastSyncTime值与当前时间值进行比较。如果已经过了一周,那么执行同步并更新LastSyncTime's值,否则不执行同步,即退出onPerformSync()方法而不执行任何操作。

答案 2 :(得分:0)

android:isAlwaysSyncable="false"中使用syncadapter.xml之后,它会按预期工作(当互联网可用时不会自动同步)。

android:isAlwaysSyncable向同步适配器框架表明它可以在您指定的任何时间运行同步适配器。如果要以编程方式控制同步适配器何时可以运行,请将此标志设置为false,然后调用requestSync()以运行同步适配器。

阅读documentation

答案 3 :(得分:0)

要定期运行同步适配器,请调用addPeriodicSync()。这会安排您的同步适配器在经过一定时间后运行。

public class MainActivity extends FragmentActivity {
... 
// Constants 
// Content provider authority 
public static final String AUTHORITY = "com.example.android.datasync.provider";
// Account 
public static final String ACCOUNT = "default_account";
// Sync interval constants 
public static final long SECONDS_PER_MINUTE = 60L;
public static final long SYNC_INTERVAL_IN_MINUTES = 60L;
public static final long SYNC_INTERVAL =
        SYNC_INTERVAL_IN_MINUTES *
        SECONDS_PER_MINUTE;
// Global variables 
// A content resolver for accessing the provider 
ContentResolver mResolver;
... 
@Override 
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ... 
    // Get the content resolver for your app 
    mResolver = getContentResolver();
    /* 
     * Turn on periodic syncing 
     */ 
    ContentResolver.addPeriodicSync(
            ACCOUNT,
            AUTHORITY,
            Bundle.EMPTY,
            SYNC_INTERVAL);
    ... 
} 
... 

}

请注意,addPeriodicSync()不会在一天中的特定时间运行同步适配器。要在每天大致相同的时间运行同步适配器,请使用重复警报作为触发器。