Android Sync Adapter не работает в Android ничего (API> 23) - PullRequest
0 голосов
/ 05 января 2019

Мне нужно подключаться к системному серверу каждую минуту из моего мобильного приложения для синхронизации данных. Для этого я использую класс SyncAdapter в своем приложении. Это прекрасно работает для мобильных телефонов, имеющих API <23 </em> (до зефира это работает отлично). Когда я тестирую свое приложение на мобильном телефоне с api> 23 , класс адаптера синхронизации не срабатывает. Он срабатывает только при первой установке приложения на устройство.

Я использую следующий код в своем приложении. Кто-нибудь может помочь мне решить проблему?

public class MyServiceSyncAdapter extends AbstractThreadedSyncAdapter {
    //TODO change this constant SYNC_INTERVAL to change the sync frequency
    public static final int SYNC_INTERVAL               = 20; //60 * 180;       // 60 seconds (1 minute) * 180 = 3 hours
    public static final int SYNC_FLEXTIME               = SYNC_INTERVAL/3;
    private static final int MOVIE_NOTIFICATION_ID      = 3004;
    public static DataBaseConnection mCon;

    public MyServiceSyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        mCon = new DataBaseConnection(this.getContext());
    }

     @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {

        Log.i("MyServiceSyncAdapter", "onPerformSync");
        //TODO get some data from the internet, api calls, etc.
        //TODO save the data to database, sqlite, couchbase, etc

        try{

            //my code to perform the task

        }catch (Exception e){

        }

    }

   public static void configurePeriodicSync(Context context, int syncInterval, int flexTime) {
        Account account = getSyncAccount(context);
        String authority = context.getString(R.string.content_authority);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // we can enable inexact timers in our periodic sync
            SyncRequest request = new SyncRequest.Builder()
                    .syncPeriodic(syncInterval, flexTime)
                    .setSyncAdapter(account, authority)
                    .setExtras(new Bundle()).build();
            ContentResolver.requestSync(request);

        } else {
            ContentResolver.addPeriodicSync(account, authority, new Bundle(), syncInterval);
        }
    }

    public static void syncImmediately(Context context) {
        Log.i("MyServiceSyncAdapter", "syncImmediately");
        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);
    }


    public static Account getSyncAccount(Context context) {
        AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE); // Get an instance of the Android account manager
        Account newAccount = new Account(context.getString(R.string.app_name), context.getString(R.string.sync_account_type)); // Create the account type and default account

        // If the password doesn't exist, the account doesn't exist
        if (accountManager.getPassword(newAccount) == null) {
            if (!accountManager.addAccountExplicitly(newAccount, "", null)) {
                Log.e("MyServiceSyncAdapter", "getSyncAccount Failed to create new account.");
                return null;
            }
            onAccountCreated(newAccount, context);
        }
        return newAccount;
    }

    private static void onAccountCreated(Account newAccount, Context context) {
        Log.i("MyServiceSyncAdapter", "onAccountCreated");
        MyServiceSyncAdapter.configurePeriodicSync(context, SYNC_INTERVAL, SYNC_FLEXTIME);
        ContentResolver.setSyncAutomatically(newAccount, context.getString(R.string.content_authority), true);
        syncImmediately(context);
    }

    public static void initializeSyncAdapter(Context context) {
        Log.d("MyServiceSyncAdapter", "initializeSyncAdapter");
        getSyncAccount(context);
    }
}

1 Ответ

0 голосов
/ 09 января 2019

Вы уверены, что адаптер не срабатывает и не просто занимает много времени для работы? Из документации для syncPeriodic :

pollFrequency long: количество времени в секундах, которое вы хотите пройти между периодическими синхронизациями. Минимальный срок составляет 1 час.

Так что, если вы подождете достаточно долго, вы можете увидеть периодическое начало синхронизации. Я рассчитал это (медленный день), и синхронизация начинается ... в конце концов.

Обновление
Основываясь на демонстрационном приложении синхронизации здесь , я записал onPerformSync() время запуска для API 23, 24 и 28. Время в следующей таблице было нормализовано до полуночи. Период синхронизации во всех случаях выполняется в одну минуту.

enter image description here

Как вы можете видеть, onPerformSync() запускается примерно один раз в минуту для API 23. Однако API 24 и API 28, похоже, защелкивают время между вызовами до onPerformSync() при 15 минутах отдачи или взятия. API, более ранние, чем API 23, удовлетворяют запросу в течение одной минуты.

В последнее время я не видел минимум одного часа, но уверен, что видел в прошлом.

Возможно, вы захотите найти другие способы синхронизации в зависимости от ваших требований. Взгляните на WorkManager , JobScheduler и AlarmManager в этом порядке. (Если возможно, используйте WorkManager.)

...