addPeriodicSync не работает
Возникли проблемы с использованием SyncAdapter
, Я создал его, как в этом руководстве, но когда я пытаюсь использовать addPeriodicSync
Я не получаю никакого эффекта.
Я прочитал все ответы, которые нашел в переполнении стека, но до сих пор не знаю, в чем проблема. Пожалуйста, попросите о помощи.
Код:
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.igordotsenko.dotsenkorssreader" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_STATS" />
<application
android:name="com.activeandroid.app.Application"
android:allowBackup="true"
android:icon="@mipmap/ic_rss"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ItemListActivity" >
</activity>
<activity android:name=".ItemContentActivity" >
</activity>
<service android:name=".RefreshService" />
<provider
android:name=".ReaderContentProvider"
android:authorities="com.igordotsenko.dotsenkorssreader"
android:enabled="true"
android:exported="true" >
</provider>
<service
android:name=".syncadapter.SyncService"
android:exported="true"
>
<!-- android:process=":sync" -->
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter" />
</service>
<service
android:name=".syncadapter.AuthenticatorService"
android:exported="true"
>
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/authenticator" />
</service>
</application>
</manifest>
Реализация SyncAdapter
package com.igordotsenko.dotsenkorssreader.syncadapter;
import android.accounts.Account;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncResult;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import com.igordotsenko.dotsenkorssreader.ReaderContentProvider;
public class ReaderSyncAdapter extends AbstractThreadedSyncAdapter {
public static final String SA_LOG = "syncAdapter_log";
private static final String AUTHORITY = "com.igordotsenko.dotsenkorssreader";
private static final Uri CHANNEL_CONTENT_URI = Uri.parse(
"content://" + AUTHORITY + "/" + ReaderContentProvider.ReaderRawData.CHANNEL_TABLE);
private static final Uri ITEM_CONTENT_URI = Uri.parse(
"content://" + AUTHORITY + "/" + ReaderContentProvider.ReaderRawData.ITEM_TABLE);
private ContentResolver contentResolver;
public ReaderSyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
this.contentResolver = context.getContentResolver();
Log.i(SA_LOG, "ReaderSyncAdapter created");
}
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.i(SA_LOG, "onPerformSync started");
// trying to crash my programm to understand, that onPerforSync was started. Brutal,isn't it?
String str = "a";
if ( true ) str = null;
str.equals("a");
}
}
SyncService
package com.igordotsenko.dotsenkorssreader.syncadapter;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.util.Objects;
public class SyncService extends Service {
private static final Object syncAdapterLock = new Object();
private static ReaderSyncAdapter syncAdapter;
public SyncService() {
synchronized (syncAdapterLock) {
Log.i(ReaderSyncAdapter.SA_LOG, "SyncService started");
if ( syncAdapter == null )
syncAdapter = new ReaderSyncAdapter(getApplicationContext(), true);
Log.i(ReaderSyncAdapter.SA_LOG, "SyncService finished");
}
}
@Override
public IBinder onBind(Intent intent) {
Log.i(ReaderSyncAdapter.SA_LOG, "SyncService onBind");
return syncAdapter.getSyncAdapterBinder();
}
}
syncadapter.xml
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.igordotsenko.dotsenkorssreader"
android:accountType="dummy.com"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="false"
android:isAlwaysSyncable="true"
/>
AuthenticatorService
package com.igordotsenko.dotsenkorssreader.syncadapter;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class AuthenticatorService extends Service {
private ReaderAccountAuthenticator readerAccountAuthenticator;
public AuthenticatorService() {
readerAccountAuthenticator = new ReaderAccountAuthenticator(this);
}
@Override
public IBinder onBind(Intent intent) {
return readerAccountAuthenticator.getIBinder();
}
}
ReaderAccountAuthenticator
Просто основные методы без реализации, так как мой аккаунт просто "пустышка"
authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="dummy.com"
/>
Использование в MainActivity в методе onCreate():
account = new Account(ACCOUNT, ACCOUNT_TYPE);
AccountManager accountManager = (AccountManager) MainActivity.this.getSystemService(ACCOUNT_SERVICE);
accountManager.addAccountExplicitly(account, null, null);
ContentResolver.setIsSyncable(account, AUTHORITY, 1);
ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
ContentResolver.addPeriodicSync(account, AUTHORITY, Bundle.EMPTY, 2);
3 ответа
Я обнаружил, что проблема заключалась в том, что минимальный интервал для периодической синхронизации составляет 1 минуту, поэтому синхронизация запускалась каждую минуту, а не 2 секунды, как я установил.
Проблема решена.
addPeriodicSync() работает только с supportUploading как true в вашем syncadapter.xml. Вот и все.
android:supportsUploading="true"
Периодической синхронизации должно быть больше, как указано в документации :
… Как часто следует выполнять синхронизацию в секундах. На уровне API Android 24 и выше минимальный интервал составляет 15 минут. В предыдущих версиях минимальный интервал - 1 час.
Итак, если вы работаете над ним с короткими интервалами, окажется, что он не работает.