I have a SyncAdapter
class that connects to an MQTT broker and publish payload for the server to receive the payload. However, it seems that even though the onPerformSync()
method is invoked, the internet access is not there. I thought using SyncAdapter
guarantees internet access?
Here is the SyncAdapter Class
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");
}
}
And also a snippet of my Android Manifest pertaining to the MqttService and 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>
Does this have anything to do with invoking the sync manually? like what I did below?
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);
Even syncing via the Settings->Account->Sync now
produced the same result.
Let me explain something.
onPerformSync() is a callback, which is not up to your control on how/when it gets called? These types of callbacks are generally Async Tasks, which can be triggered from external (can be remote) objects anytime. That's why we generally put these types of callbacks in our MainThread (UI thread) because, MainThread can't be killed throughout the app. [Note: If you have executed a service in the different process then you can run onPerformSync() from that Service as well]. My intention of saying this is to make sure that throughout the app keeps running, there is a change of these callbacks can be executed anytime.
I really don't see any use of onNetworkAvailable() method here. You use this onNetworkAvailable() if you want to do some network operations from your side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With