ProductPromotion
Logo

Kotlin

made by https://0x3d.site

GitHub - evilthreads669966/BootLaces: A Kotlin work manager library for Android with progress notifications and Hilt support.
A Kotlin work manager library for Android with progress notifications and Hilt support. - evilthreads669966/BootLaces
Visit Site

GitHub - evilthreads669966/BootLaces: A Kotlin work manager library for Android with progress notifications and Hilt support.

GitHub - evilthreads669966/BootLaces: A Kotlin work manager library for Android with progress notifications and Hilt support.

Release  API  Android Arsenal  Awesome Kotlin Badge

Boot Laces

A kotlin work manager library for Android that includes notifications and Hilt support.

User Instructions

  1. Add the JitPack repository to your project's build.gradle
allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
  1. Add the kapt and hilt plugins to the top of your app's build.gradle file
apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
  1. Add the dependencies for boot laces & hilt to your app's build.gradle
dependencies {
        implementation 'com.github.evilthreads669966:bootlaces:10.0.2'
        implementation "com.google.dagger:hilt-android:2.36"
        kapt "com.google.dagger:hilt-android-compiler:2.36"
}
  1. Add the Hilt plugin to your project's build.gradle dependencies
dependencies {
    ...
    classpath "com.google.dagger:hilt-android-gradle-plugin:2.36"
}
  1. Annotate your subclass of Application class
@HiltAndroidApp
class App: Application()
  1. Add name of your Application subclass to manifest
<application
    android:name=".App"
    ...
>
  1. Create your worker(s).
  • you can opt-in for having a progress notification that displays while Worker.doWork is active
    • the description for your worker is good practice and will be used for things like notifications if you choose to use them
  • you perform your work inside of doWork and Boot Laces will keep it running in the background until it has completed and reschedule as necessary
  • WorkerNine below demonstrates how to create a WorkReceiver
    • a WorkReceiver is created by passing in an action for it to subscribe to.
    • you can broadcast to this BroadcastReceiver from within your doWork function or anywhere else in your app
    • for now the WorkReceiver is only registered and subscribing to broadcast while you are performing work. Everytime doWork executes it registers the receiver & unregisters it after doWork completes
  • If you do not need a worker and just a BroadcastReceiver then you can use PersistentReceiver
    • PersistentReceivers only have a WorkReceiver and you don't need to override doWork function
class WorkerEight: Worker(8, "working for 2 hours", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(AlarmManager.INTERVAL_HOUR * 2)
    }
}

class WorkerOne: Worker(1, "performing database transactions for 2 minutes", true, Dispatchers.IO){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(120000)
    }
}

class WorkerTwo: Worker(2, "performing operations on files for 15 minutes", true, Dispatchers.IO){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(AlarmManager.INTERVAL_FIFTEEN_MINUTES)
    }
}

class WorkerThree: Worker(3, "working for 1 minute", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(60000)
    }
}

class WorkerFour: Worker(4, "working for 5 minutes", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(60000 * 5)
    }
}

class WorkerFive: Worker(5, "working for 45 seconds", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(45000)
    }
}

class WorkerSix: Worker(6, "working for 1 minute", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(60000)
    }
}

class WorkerSeven: Worker(7, "working for a minute and a half", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(90000L)
    }
}

class WorkerThirteen: Worker(13, "working for 20 seconds", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(20000)
    }
}

class WorkerTwelve: Worker(12, "working for 30 seconds", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(30000)
    }
}

class WorkerEleven: Worker(11, "working for 5 seconds", true){
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, description)
        delay(5000)
    }
}

class WorkerTen: Worker(10,"Worker Ten", true) {
    override suspend fun doWork(ctx: Context) {
        Log.d(tag, "working for 10 seconds")
        for(i in 1..10)
            delay(1000)
    }
}

class WorkerFourteen: Worker(14, "survives reboot and performs every hour", true){

    override val receiver: WorkReceiver?
        get() = object : WorkReceiver(Intent.ACTION_TIME_TICK) {

            override fun onReceive(ctx: Context?, intent: Intent?) {
                if(intent?.action?.equals(action) ?: false){
                    val date = DateUtils.formatDateTime(ctx, System.currentTimeMillis(),0)
                    Log.d(this.tag, date ?: "null")
                }
            }
        }

    override suspend fun doWork(ctx: Context) {
        while(true){
            Log.d(tag, "working for three minutes")
            delay(60000L * 3)
        }
    }
}

class ReceiverAtReboot: PersistentReceiver(18){
   override val receiver: WorkReceiver?
       get() = object : WorkReceiver(Intent.ACTION_AIRPLANE_MODE_CHANGED, Intent.ACTION_BATTERY_CHANGED){
           override fun onReceive(ctx: Context?, intent: Intent?) {
               super.onReceive(ctx, intent)
               goAsync().apply {
                   when(intent?.action){
                       Intent.ACTION_BATTERY_CHANGED -> Log.d([email protected], "battery level changed")
                       Intent.ACTION_AIRPLANE_MODE_CHANGED -> Log.d([email protected], "airplane mode changed")
                       else -> Log.d([email protected], "action not found")
                   }
               }.finish()
           }
       }
}
  1. Inject your WorkScheduler inside of an Android context
@Inject lateinit var scheduler: WorkScheduler
  1. Your WorkScheduler instance provides you with a scoping function called WorkScheduler.use
  • it accepts a trailing lambda
  • within WorkScheduler.use scope you have access to scheduling functions that have a receiver type of Worker
    • This allows you to use your worker(s) instance(s) to call schedule on your worker
  1. Schedule your worker inside of WorkScheduler.use scope
  • you can pass four arguments to your worker's many available KTX schedule functions
    • surviveReboot
      • allows the worker to survive the phone rebooting
    • precision
      • ensures the worker executes at the exact time scheduled.
        • not using precision allows for the operating system to only execute the worker when there are not too many workers in the background.
    • repeating
      • sets whether the worker should be scheduled to repeat everytime the specified time passes
    • it's default value is false so you don't have to opt out of repeating
      • wakeUpIfIdle
    • sets whether you worker should wake up the device to perform work rather than wait for it stop sleeping
      • the default value for this is false
@AndroidEntryPoint
class LauncherActivity: AppCompatActivity(){
    @Inject lateinit var scheduler: WorkScheduler

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
              scheduler.use {
                   runBlocking {
                       WorkerSix().scheduleQuarterHour(surviveReboot = true, repeating =  true, allowWhileIdle = true, precision = true).await()
                       WorkerFive().scheduleHalfHour().await()
                   }
               }
               scheduler.use {
                   runBlocking {
                       WorkerFour().scheduleHour(surviveReboot = true, repeating =  true, allowWhileIdle = true, precision = true).await()
                       WorkerTwelve().scheduleFuture(60000L * 8, repeating = true, allowWhileIdle = true, precision = true).await()
                       WorkerEleven().scheduleFuture(60000L * 3, repeating = true, allowWhileIdle = true, precision = true).await()
                       WorkerThirteen().scheduleNow().await()
                       WorkerTwo().scheduleDay(surviveReboot = true, repeating =  true, allowWhileIdle = true, precision = true).await()
                       val fourtyFiveSeconds = 45000L
                       WorkerOne().scheduleFuture(fourtyFiveSeconds, repeating = true, allowWhileIdle = true).await()
                       WorkerThree().scheduleQuarterDay(repeating =  true, allowWhileIdle = true, precision = true).await()
                   }
               }
               scheduler.use {
                   runBlocking {
                       WorkerSeven().scheduleNow().await()
                       WorkerEight().scheduleHoursTwo(repeating =  true, allowWhileIdle = true, precision = true).await()
                       WorkerTen().scheduleHalfWeek(repeating =  true, allowWhileIdle = true, precision = true).await()
                       WorkerFourteen().scheduleHour(surviveReboot = true, repeating = true, allowWhileIdle = true, precision = true).await()
                       ReceiverAtReboot().scheduleReceiver().await()
                   }
               }
           }
    }
}

Important To Know

License

Copyright 2019 Chris Basinger

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory