SyncAdapter-onPerformSync не имеет доступа к интернету

У меня есть класс SyncAdapter, который подключается к брокеру MQTT и публикует полезную нагрузку для сервера, чтобы получить полезную нагрузку. Однако похоже, что даже при вызове метода onPerformSync() доступа в Интернет нет. Я думал, что использование SyncAdapter гарантирует доступ в Интернет?

Вот класс SyncAdapter

public class SyncAdapter extends AbstractThreadedSyncAdapter {
    private static final String TAG = SyncAdapter.class.getSimpleName();
    private MqttHelper mqttHelper;

    public SyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        mqttHelper = new MqttHelper(getContext());
    }

    public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
        super(context, autoInitialize, allowParallelSyncs);
    }
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
            = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
        Log.wtf(TAG, "onPerformSync: ");
        Log.wtf(TAG, "SYNC_EXTRAS_MANUAL: " + extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL));
        Log.wtf(TAG, "SYNC_EXTRAS_EXPEDITED: " + extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED));

        Log.wtf(TAG, "internte: " + isNetworkAvailable());


        mqttHelper.connect(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                Log.wtf(TAG, "onSuccess: ");
                mqttHelper.pub("hello/android", "Finally working via sync adapter praise the lord!!!!");
                // TODO: Get Checkpoints from Realm
                // TODO: publish at once
                // TODO: Disconnect
                mqttHelper.disconnect(new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        Log.wtf(TAG, "onSuccess: disconnect");
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        Log.wtf(TAG, "onFailure: disocnnect");
                    }
                });
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                Log.wtf(TAG, "onFailure: ", exception);
            }
        });

    }

    @Override
    public void onSyncCanceled() {
        super.onSyncCanceled();
        Log.wtf(TAG, "sync canceled");
    }
}

А также фрагмент моего манифеста Android, относящегося к MqttService и SyncAdapter:

<application
    ...
    <receiver android:name=".LocationPollingReceiver" />
    <service android:name="org.eclipse.paho.android.service.MqttService"
        android:process=":sync"/>
    <service
        android:name=".LocationPollingService"
        android:exported="false"/>
    <service
        android:name=".sync.AuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator"/>
        </intent-filter>
        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>
    <provider
        android:name=".sync.StubProvider"
        android:authorities="proj.com.fyp.provider"
        android:exported="false"
        android:syncable="true"/>
    <service
        android:name=".sync.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>
</application>

Это как-то связано с запуском синхронизации вручную? как то, что я сделал ниже?

Account mAccount = MainActivity.CreateSyncAccount(context);
Bundle settingsBundle = new Bundle();
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
//settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, true);
ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);

Даже синхронизация через Settings->Account->Sync now дала тот же результат.


person Andy Aldo    schedule 20.05.2017    source источник
comment
Нужна дополнительная информация, например, когда выполняется синхронизация, в каком состоянии находится телефон, подключен Интернет или нет, есть разрешение на доступ к Интернету или нет, синхронизация запускается вручную или периодически?   -  person Manish Kumar    schedule 17.07.2017
comment
Интернет есть, разрешение есть. Если приложение загружено, проблем нет. Проблема в том, когда телефон становится бездействующим. Синхронизация запускается вручную   -  person Andy Aldo    schedule 17.07.2017
comment
Можете ли вы проверить «activeNetwork.isConnectedOrConnecting()»? в настоящее время вы используете isConnected(). Сообщите мне результат.   -  person Manish Kumar    schedule 18.07.2017
comment
Я думал, что использование SyncAdapter гарантирует доступ в Интернет? Я имею в виду, ясно, что SyncAdapter не может этого сделать. JobScheduler может сделать что-то очень похожее. Вы хотели использовать это?   -  person G. Blake Meike    schedule 19.07.2017
comment
Также убедитесь, что ваше устройство не находится в одном из этих режимов энергосбережения или сохранения данных, когда вы пытаетесь, потому что это может отключить фоновые данные.   -  person Rushi M Thakker    schedule 19.07.2017


Ответы (1)


Позвольте мне кое-что объяснить.

onPerformSync() - это обратный вызов, который не зависит от вашего контроля над тем, как и когда он вызывается? Эти типы обратных вызовов, как правило, представляют собой асинхронные задачи, которые могут быть запущены внешними (могут быть удаленными) объектами в любое время. Вот почему мы обычно помещаем эти типы обратных вызовов в наш MainThread (поток пользовательского интерфейса), потому что MainThread не может быть уничтожен во всем приложении. [Примечание: если вы запустили службу в другом процессе, вы также можете запустить onPerformSync() из этой службы]. Я хочу сказать, что это нужно для того, чтобы приложение продолжало работать, изменение этих обратных вызовов могло быть выполнено в любое время.

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

person Uddhav Gautam    schedule 21.07.2017