Alexey Nikitin
Alexey Nikitin

Reputation: 664

SyncAdapter onPerformSync not called for MediaProvider

I've trying to acquire changes from android media storage. I've created GallerySyncAdapter with next resource:

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

Added ContentResolver.setIsSyncable(accoutn, MediaStore.AUTHORITY, 1) and ContentResolver.setSyncAutomatically(account, MediaStore.AUTHORITY, true), so it must be synced authomatically. But when I make some photo my GallerySyncAdapter.onPerformSync does not called.

GallerySyncAdapter source:

class GallerySyncAdapter(
    context: Context,
    autoInitialize: Boolean
) : AbstractThreadedSyncAdapter(context, autoInitialize) {

    override fun onPerformSync(
        account: Account?,
        extras: Bundle?,
        authority: String?,
        provider: ContentProviderClient?,
        syncResult: SyncResult?
    ) {
        Log.d("GallerySyncAdapter", "Need sync images...")
    }

}

GallerySyncService:

class GallerySyncService : Service() {

    override fun onCreate() {
        synchronized(sSyncAdapterLock) {
            sSyncAdapter = sSyncAdapter ?: GallerySyncAdapter(applicationContext, true)
        }
    }

    override fun onBind(intent: Intent): IBinder {
        return sSyncAdapter?.syncAdapterBinder ?: throw IllegalStateException()
    }

    companion object {

        private var sSyncAdapter: GallerySyncAdapter? = null
        private val sSyncAdapterLock = Any()
    }
}

Declaration in the AndroidManifest.xml

<service
    android:name=".services.GallerySyncService"
    android:exported="true">
    <intent-filter>
        <action android:name="android.content.SyncAdapter" />
    </intent-filter>
    <meta-data
        android:name="android.content.SyncAdapter"
        android:resource="@xml/gallerysyncadapter" />
</service>

Account created correctly, so I can start syncing from Settings -> Accounts -> My Account -> Sync account -> Sync now, but when I changing media (make new photos, videos, etc) sync is not starting.

It's working, when I declare ContentObserver instead of SyncAdapter:

resolver.registerContentObserver(
    MediaStore.AUTHORITY_URI, // content://media
    true, // notifyForDescendants
    galleryObserver // my own observer
)

But I need a solution to acquire changes even if my application is not started.

Upvotes: 0

Views: 143

Answers (1)

Alexey Nikitin
Alexey Nikitin

Reputation: 664

Use WorkManager and trigger by uri Constraints.Builder.addContentUriTrigger instead:

workManager.enqueueUniqueWork(
    "gallery_updates",
    ExistingWorkPolicy.REPLACE,
    OneTimeWorkRequestBuilder<GalleryUpdatesWorker>()
        .setConstraints(
            Constraints.Builder()
                .addContentUriTrigger(MediaStore.AUTHORITY_URI, true)
                .build()
        )
        .build()
)

And then re-enqueue the job every time the job finish to catch the next chage.

Upvotes: 1

Related Questions