Android 定期运行同步适配器
我已经在我的应用程序中实现了同步适配器功能。我允许用户在脱机模式下使用应用程序,在脱机模式下数据库中的任何更改都保存在一个表中,我希望根据定期同步功能将该表的数据同步到服务器。 我在设置中提供了小时、每日和每周同步选项。 我面临的问题是,不管用户选择的同步频率如何,只要有可用的internet连接,表的数据就会同步。请帮我解决这个问题看看这个简单的代码Android 定期运行同步适配器,android,Android,我已经在我的应用程序中实现了同步适配器功能。我允许用户在脱机模式下使用应用程序,在脱机模式下数据库中的任何更改都保存在一个表中,我希望根据定期同步功能将该表的数据同步到服务器。 我在设置中提供了小时、每日和每周同步选项。 我面临的问题是,不管用户选择的同步频率如何,只要有可用的internet连接,表的数据就会同步。请帮我解决这个问题看看这个简单的代码 public class TimerReceiverSyncInterval extends BroadcastReceiver { @Ove
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.ScheduleAllarms(此) 我不知道什么是最好的方法。但您可以创建一个
SharedReference
变量,如LastSyncTime
,该变量将包含同步时间,并在您实际同步数据的onPerformSync()
中每次同步时更新此值
下次调用
onPerformSync()
时,您可以将LastSyncTime
值与当前时间值进行比较。如果已经一周了,则执行同步并更新LastSyncTime的
值,否则不要执行同步,即退出onPerformSync()
方法而不执行任何操作。使用syncadapter.xml中的android:isAlwaysSyncable=“false”
,然后按预期工作(互联网可用时不自动同步)
android:isAlwaysSyncable
向同步适配器框架指示它可以在您指定的任何时间运行同步适配器。如果您希望以编程方式控制同步适配器何时可以运行,请将此标志设置为false,然后调用requestSync()
以运行同步适配器
read要定期运行同步适配器,请调用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()不会在一天中的特定时间运行同步适配器。若要在每天大致相同的时间运行同步适配器,请使用重复警报作为触发器。在创建链接到同步服务的用户帐户时添加此选项:
if (accountManager.addAccountExplicitly(account, null, null)) {
// Inform the system that this account supports sync
ContentResolver.setIsSyncable(account, BuildConfig.CONTENT_AUTHORITY, 1)
// Inform the system whether this account is eligible for auto sync when the network
// is up. In your case should be false
ContentResolver.setSyncAutomatically(account, BuildConfig.CONTENT_AUTHORITY, false)
// Add a schedule for automatic synchronisation. The system may call the sync function
// a few seconds early or late for battery and network optimisation.
ContentResolver.addPeriodicSync(account, BuildConfig.CONTENT_AUTHORITY, Bundle(),
SYNC_FREQUENCY)
}
您是否创建了报警服务之类的服务来定期调用同步过程?我认为只有当条件与用户设置的时间段匹配时才需要同步的标志的问题可能是您在找到连接时直接同步。这可能是问题所在。我没有使用任何报警服务。我将给出一个示例。假设e用户已从设置中选择每周同步,并已在脱机模式下使用该应用程序。然后,一旦用户打开internet连接,同步就会开始。如果假设用户每天做两次相同的事情,则数据将同步两次。因此,不使用每周同步功能。这就是我指向f的原因延迟我是指共享引用,因为您的方式不正确。请记住,操作系统将在认为最好的时候启动同步适配器-因此,如果您错过了一个,并且有一个挂起,它可能会在您重新连接时执行。我已经设置了android:isAlwaysSyncable=“false”当我打开互联网时,会调用同步适配器并同步所有数据。