没有android.content.SyncAdapter元数据

时间:2016-06-15 10:30:55

标签: android synchronization adapter kotlin authenticator

我正在尝试为我的应用实现同步适配器,我遇到了这个问题:

  

org.xmlpull.v1.XmlPullParserException:没有android.content.SyncAdapter   元数据

由于这个(我希望),我的同步适配器没有调用onPerformSync()。我知道之前曾问过这个问题,但答案对我的情况没有帮助。我必须提到我在谷歌示例中使用StubContentProvider,这里有一些配置文件:

清单:

 <service android:name=".sync.AuthenticatorService">
        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator" />
        </intent-filter>
    </service>

    <provider
        android:name=".sync.StubContentProvider"
        android:authorities="${applicationId}.sync.StubContentProvider"
        android:exported="false"
        android:label="@string/app_name"
        android:syncable="true" />

    <!-- Sync Adapter -->
    <service
        android:name=".sync.SyncDataService"
        android:label="@string/app_name"
        android:exported="false">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>

syncadapter.xml

    <?xml version="1.0" encoding="utf-8"?>
<sync-adapter
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:contentAuthority="@string/account_authorities"
    android:accountType="one.random.net"
    android:allowParallelSyncs="true"
    android:isAlwaysSyncable="true"
    android:supportsUploading="false"
    android:userVisible="true" />

authenticator.xml:

    <?xml version="1.0" encoding="utf-8"?>
<account-authenticator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="one.random.net"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:smallIcon="@mipmap/ic_launcher"/>

SyncSupport.kt:

fun setupSyncAdapter(context: Context) {
        // Create the account type and default account
        val accountName = context.getString(R.string.account_name)
        val accountType = ACCOUNT_TYPE
        val newAccount = Account(accountName, accountType)
        Log.d("Sync", "Account is $newAccount")
        // Get an instance of the account manager
        val accountManager = context.getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
        Log.d("Sync", "Account manager")
        // Add the account and account type, no password or user data
        // If successful, return the Account object, otherwise report an error.
        Log.d("Sync", "Account manager size ${accountManager.getAccountsByType(accountType).size}")
      /*  ContentResolver.setSyncAutomatically(newAccount, AUTHORITY, true)
        ContentResolver.setIsSyncable(newAccount, AUTHORITY, 1)*/

        try {
            if (accountManager.addAccountExplicitly(newAccount, null, null)) {
                //  If you don't set android:syncable="true" in your <provider> element in the
                // manifest, then call context.setIsSyncable(account, AUTHORITY, 1) here
                Log.d("Sync", "Sync Account added")
            } else {
                // The account exists or some other error occurred. Log this, report it,
                // or handle it internally.
                Log.d("Sync", "Sync Account not added or error")
            }
        } catch(e: Exception) {
            Log.e("SyncSupport", e.message, e)
            return
        }

        periodicSync(context)

    }

    /**
     * Expedite a sync request, this will run even if there is sync queued up.
     *
     * **Remember this does IO, and should be threaded**

     * @param context
     */
    fun requestSyncNow(context: Context) {
        val account = getAccount(context) ?: return

        // Pass the settings flags by inserting them in a bundle
        val settingsBundle = Bundle()
        settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true)
        settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true)
        settingsBundle.putBoolean(KEY_SYNC, true)
        // Request the sync for the default account, authority, and manual sync settings
      /*  ContentResolver.setSyncAutomatically(account, AUTHORITY, true)
        ContentResolver.setIsSyncable(account, AUTHORITY, 1)*/
        ContentResolver.requestSync(account, AUTHORITY, settingsBundle)
    }

    /**
     * Requests a sync, at the next opportunity.
     *
     *
     * **This does IO, remember to call it off the UI thread.**

     * @param context
     */
    fun requestSync(context: Context) {
        val account = getAccount(context) ?: return

        val settingsBundle = Bundle()
        settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true
        settingsBundle.putBoolean(KEY_SYNC, true)
        /*
     * Signal the framework to run your sync adapter. Assume that
     * app initialization has already created the account.
     */
        ContentResolver.setSyncAutomatically(account, AUTHORITY, true)
        ContentResolver.setIsSyncable(account, AUTHORITY, 1)
        ContentResolver.requestSync(account, AUTHORITY, settingsBundle)

    }

    fun periodicSync(context: Context) {
        val account = getAccount(context) ?: return
        Log.d("Sync", "Periodic sync triggered")
        ContentResolver.setSyncAutomatically(account, AUTHORITY, true)
    //    ContentResolver.setIsSyncable(account, AUTHORITY, 1)
        // We run the Sync Adapter every 12 hours normally or every 5 min's on dev to test.
        //noinspection ConstantConditions
        val pollPeriod = if (BuildConfig.DEBUG) TimeUnit.MINUTES.toSeconds(5L) else TimeUnit.HOURS.toSeconds(12L)
        val settingsBundle = Bundle()

        settingsBundle.putBoolean(KEY_SYNC, true)

        val b = SyncRequest.Builder().syncPeriodic(pollPeriod, pollPeriod)
        b.setSyncAdapter(account, AUTHORITY)
        b.setExtras(settingsBundle)
        ContentResolver.requestSync(b.build())

        //Timber.i("Sync: PeriodicSync: %ss", pollPeriod.toString())
    }

    fun getAccount(context: Context): Account? {
        val accountManager = context.applicationContext.getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
        val accountsByType = accountManager.getAccountsByType(ACCOUNT_TYPE)
        for (account in accountsByType) return account
        return null
    }

从我多次检查的字符串是可以的但由于某种原因我仍然得到这个错误。

0 个答案:

没有答案