【问题标题】:SyncAdapter not getting called on "Network tickle"SyncAdapter 没有在“网络痒痒”上被调用
【发布时间】:2016-04-15 19:08:53
【问题描述】:

概述

我跟随Google's tutorial 使用 SyncAdapter 而不使用 ContentProvider、Authenticator..etc。当我需要通过 de SyncAdapter 向服务器“上传”时调用 onPerformSync(...),它可以完美运行。

现在,您可以想象,我还需要从服务器下载(是的,我知道使用 Google 的云消息传递系统会更好,但这是给我的设置,我可以'不要改变它)。为此,我不想进行定期同步,而是想利用 Android 系统在有可用网络时执行的“网络痒痒”。为此,我声明如下:

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

但我的 SyncAdapter 只是没有被调用。查看其他 stackOverFlow 问题,如果使用 SyncAdapter 以 API 10 或更低版本为目标,并且您必须在调用之前的方法之前显式添加帐户之前,似乎存在问题。所以我最终得到了这个:

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); 
    }

现在,当用户登录或应用程序被终止并重新启动时,就会执行此代码。我想知道,我应该只在第一次添加 dummyAccount 时才调用setIsSyncablesetSyncAutomatically 吗?

此外,SyncAdapter 的“优点”之一是它会在出现异常时继续进行调用。但我不太明白这是怎么回事,所以我有这个:

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();

}

如您所见,根据我上传到服务器的结果,我打开或关闭定期同步。

【问题讨论】:

  • 您是否建议有一种方法可以使用您自己的服务器而不是 Google 的服务器来模拟 Google 的云消息传递,以便可以维持长时间运行的推送连接(如何,因为任何持有连接的应用可能随时被杀死?)或者有一些 API 会在 TCP 连接或消息到达时创建一个 Intent 来启动我的服务?
  • GCM 是迄今为止最好的选择,但我的设置是这样的,并且我尝试“按文档”做到最好,尽管它没有按照文档所述工作。当时的文档指出,您可以使用合并的“Network Tickle”,这意味着当互联网连接良好时,系统将执行应用程序的 SyncAdapter 并让它们执行所需的任何操作。如果一切顺利,他们就不会再被召唤了。这就是我想要的,而不是不断地拉/推到服务器。但我从来没有让那个“Network Tickle”在 Android 2.3.6 及更低版本上正常工作。
  • 有什么解决办法吗?请回复

标签: android android-syncadapter


【解决方案1】:

由于 accountManager.getAccounts[] 返回设备上的每个帐户,我认为无法保证 account[0] 是您应用的帐户(也就是具有您的包名称的 ACCOUNT_TYPE)。 -- 在任何情况下都可以调用 addAccountExplicitly(),如果它存在,那么什么也不会发生。

    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】:

    免责声明:我可能弄错了。

    除了您所做的一切之外,您还必须在每次需要运行同步时从您的应用程序中调用ContentResolver.requestSync()。但同步不会立即运行,因为 Android 正在尝试集群网络活动。

    或者您可以使用 Google 的 Cloud Messaging API 来请求同步,但我对此知之甚少。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-12
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多