Build an Auto Wallpaper Changer in Android & Flutter with Background WorkManager
Step-by-step tutorial on building a battery-efficient automatic background wallpaper changer using WorkManager, periodic intervals, and NexWall REST API.
⚠️ Production Security Warning — Read Before Publishing to App Store
The code samples in this guide use a Bearer token directly in client-side mobile code. This is for local development and prototyping only.
Any API key or Bearer token embedded inside a compiled Android APK or iOS IPA can be extracted in under 60 seconds using free tools like jadx-gui or apktool.
For production apps on Google Play / App Store, always use a backend proxy architecture:
Your backend holds the NexWall Bearer token securely. It proxies requests from your app, adds auth, and returns responses — keeping your API key permanently hidden from reverse engineers. Read API Docs →
1. How Auto Wallpaper Rotation Works
An automatic wallpaper changer wakes up periodically in the background, requests a random 4K image from https://nexwall.kodnextech.com/api/developer/v1/wallpapers?sort=random, downloads the file, and sets the home or lock screen without user intervention.
2. Creating the Android Background Worker (WorkManager)
import android.app.WallpaperManager
import android.content.Context
import androidx.work.*
import coil.ImageLoader
import coil.request.ImageRequest
import coil.request.SuccessResult
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL
import java.util.concurrent.TimeUnit
class AutoWallpaperWorker(
private val context: Context,
workerParams: WorkerParameters
) : CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result {
return try {
// 1. Fetch random wallpaper metadata from NexWall API
val url = URL("https://nexwall.kodnextech.com/api/developer/v1/wallpapers?sort=random&per_page=1")
val conn = url.openConnection() as HttpURLConnection
conn.setRequestProperty("Authorization", "Bearer YOUR_NEXWALL_API_KEY")
conn.setRequestProperty("Accept", "application/json")
val json = JSONObject(conn.inputStream.bufferedReader().readText())
val imageUrl = json.getJSONArray("data").getJSONObject(0).getString("image_url")
// 2. Download and set bitmap
val loader = ImageLoader(context)
val request = ImageRequest.Builder(context).data(imageUrl).allowHardware(false).build()
val bitmap = ((loader.execute(request) as SuccessResult).drawable as android.graphics.drawable.BitmapDrawable).bitmap
WallpaperManager.getInstance(context).setBitmap(bitmap)
Result.success()
} catch (e: Exception) {
Result.retry()
}
}
}
3. Scheduling with Battery Constraints
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiresBatteryNotLow(true)
.build()
val periodicWork = PeriodicWorkRequestBuilder<AutoWallpaperWorker>(6, TimeUnit.HOURS)
.setConstraints(constraints)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"NexWallAutoChanger",
ExistingPeriodicWorkPolicy.KEEP,
periodicWork
)
Want to test this endpoint right now?
Use the interactive Live Sandbox Console to test queries without writing code.