SyncAdapter not getting called on “Network tickle”

女生的网名这么多〃 提交于 2019-12-08 16:01:29

问题


Overview

I follwed Google's tutorial on using SyncAdapter without using ContentProvider, Authenticator..etc. It works perfectly when I call onPerformSync(...) when I need to do an "upload" to the server via de SyncAdapter.

Now, as you can imagine, I need to do downloads from the server as well (yes I understand that it would be better to use Google's Cloud Messaing system, but this is the set up I was given, and I can't change that). For that, instead of doing periodical syncs, I want to make use of the "Network tickle" Android system carries out when there is a network available. For that I state the following:

ContentResolver.setIsSyncable(accounts[0], AUTHORITY, 1);
ContentResolver.setSyncAutomatically(accounts[0], AUTHORITY, true); 

But my SyncAdapter is just not getting called. Looking into other stackOverFlow questions, there seem to be a problem if targetting API 10 or below with SyncAdapter and that you must add an account explicitly before calling the before methods. So I ended up with this:

AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);

    Account[] accounts = accountManager.getAccounts();
    if(accounts.length == 0){ //ADD DUMMY ACCOUNT
        Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE);
        ContentResolver.setIsSyncable(accounts[0], AUTHORITY, 1);
        ContentResolver.setSyncAutomatically(accounts[0], AUTHORITY, true); 
        accountManager.addAccountExplicitly(newAccount, null, null);
    }else{
         accounts = accountManager.getAccounts();
        ContentResolver.setIsSyncable(accounts[0], AUTHORITY, 1);   
        ContentResolver.setSyncAutomatically(accounts[0], AUTHORITY, true); 
    }

Now this code gets executed when the user signs in, or if the application was killed and is started up again. I am wondering, should I call setIsSyncable and setSyncAutomatically only when I add the dummyAccount the very first time?

Also, part of the "goodiness" of the SyncAdapter is that it will keep on making the calls in case of an exception. But I don't quite understand how this goes about, so instead I have this:

private void profileUpdate(){       
TableAccounts db = TableAccounts.getInstance(getContext());
boolean isRecordDirty = db.isRecordDirty(signedInUser);   

if(isRecordDirty){
   if(server.upDateUserProfile(signedInUser)){
       db.cleanDirtyRecord(signedInUser);
       turnOffPeriodicSync();
   }else{
       this.turnOnPeriodicSync(this.sync_bundle);   
   }
}else
     turnOffPeriodicSync();

}

As you can see, depending on the result of my upload to the server, I turn on or off a periodic sync.


回答1:


Since the accountManager.getAccounts[] return every account on the device, I think nothing guarantee that the account[0] is your app's account (aka, has the ACCOUNT_TYPE of your package name). -- You could call addAccountExplicitly() in any case, if it is existed, then nothing happens.

    Account account = new Account(ACCOUNT, ACCOUNT_TYPE);

    AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
    accountManager.addAccountExplicitly(account, null, null)
    context.getContentResolver().setSyncAutomatically(account, AUTHORITY, true);



回答2:


Disclaimer: I might be mistaken.

On top everything you did, you also have to call ContentResolver.requestSync() from within your app every time you need a sync to run. The sync will not run immediately though, because Android is trying to cluster network activity.

Or you can use Googles Cloud Messaging API to request a sync, but I don't know a whole lot about that.



来源:https://stackoverflow.com/questions/22622364/syncadapter-not-getting-called-on-network-tickle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!