Home | History | Annotate | Download | only in jobscheduler
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *       http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.example.android.jobscheduler
     18 
     19 import android.app.Service
     20 import android.app.job.JobParameters
     21 import android.app.job.JobService
     22 import android.content.Intent
     23 import android.os.Handler
     24 import android.os.Message
     25 import android.os.Messenger
     26 import android.os.RemoteException
     27 import android.util.Log
     28 
     29 /**
     30  * Service to handle callbacks from the JobScheduler. Requests scheduled with the JobScheduler
     31  * ultimately land on this service's "onStartJob" method. It runs jobs for a specific amount of time
     32  * and finishes them. It keeps the activity updated with changes via a Messenger.
     33  */
     34 class MyJobService : JobService() {
     35 
     36     private var activityMessenger: Messenger? = null
     37 
     38     /**
     39      * When the app's MainActivity is created, it starts this service. This is so that the
     40      * activity and this service can communicate back and forth. See "setUiCallback()"
     41      */
     42     override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
     43         activityMessenger = intent.getParcelableExtra(MESSENGER_INTENT_KEY)
     44         return Service.START_NOT_STICKY
     45     }
     46 
     47     override fun onStartJob(params: JobParameters): Boolean {
     48         // The work that this service "does" is simply wait for a certain duration and finish
     49         // the job (on another thread).
     50         sendMessage(MSG_COLOR_START, params.jobId)
     51 
     52         // Uses a Handler to delay the execution of jobFinished().
     53         val duration = params.extras.getLong(WORK_DURATION_KEY)
     54         Handler().postDelayed({
     55             sendMessage(MSG_COLOR_STOP, params.jobId)
     56             jobFinished(params, false)
     57         }, duration)
     58         Log.i(TAG, "on start job: ${params.jobId}")
     59 
     60         // Return true as there's more work to be done with this job.
     61         return true
     62     }
     63 
     64     override fun onStopJob(params: JobParameters): Boolean {
     65         // Stop tracking these job parameters, as we've 'finished' executing.
     66         sendMessage(MSG_COLOR_STOP, params.jobId)
     67         Log.i(TAG, "on stop job: ${params.jobId}")
     68 
     69         // Return false to drop the job.
     70         return false
     71     }
     72 
     73     private fun sendMessage(messageID: Int, params: Any?) {
     74         // If this service is launched by the JobScheduler, there's no callback Messenger. It
     75         // only exists when the MainActivity calls startService() with the callback in the Intent.
     76         if (activityMessenger == null) {
     77             Log.d(TAG, "Service is bound, not started. There's no callback to send a message to.")
     78             return
     79         }
     80         val message = Message.obtain()
     81         message.run {
     82             what = messageID
     83             obj = params
     84         }
     85         try {
     86             activityMessenger?.send(message)
     87         } catch (e: RemoteException) {
     88             Log.e(TAG, "Error passing service object back to activity.")
     89         }
     90     }
     91 
     92     companion object {
     93         private val TAG = "MyJobService"
     94     }
     95 }
     96