Creating your own broadcast messages

As you probably remember, we did code refactoring for the NoteActivity class. Let's show the last state we had in important parts for our further demonstration:

     class NoteActivity : ItemActivity() { 
       ... 
       private val locationListener = object : LocationListener { 
         override fun onLocationChanged(p0: Location?) { 
           p0?.let { 
                LocationProvider.unsubscribe(this) 
                location = p0 
                val title = getNoteTitle() 
                val content = getNoteContent() 
                note = Note(title, content, p0) 
 
                // Switching to intent service. 
                val dbIntent = Intent(this@NoteActivity,
DatabaseService::class.java) dbIntent.putExtra(DatabaseService.EXTRA_ENTRY, note) dbIntent.putExtra(DatabaseService.EXTRA_OPERATION,
MODE.CREATE.mode) startService(dbIntent) sendMessage(true) } } override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?)
{} override fun onProviderEnabled(p0: String?) {} override fun onProviderDisabled(p0: String?) {} } ... private fun updateNote() { if (note == null) { if (!TextUtils.isEmpty(getNoteTitle()) &&
!TextUtils.isEmpty(getNoteContent())) { LocationProvider.subscribe(locationListener) } } else { note?.title = getNoteTitle() note?.message = getNoteContent() // Switching to intent service. val dbIntent = Intent(this@NoteActivity,
DatabaseService::class.java) dbIntent.putExtra(DatabaseService.EXTRA_ENTRY, note) dbIntent.putExtra(DatabaseService.EXTRA_OPERATION,
MODE.EDIT.mode) startService(dbIntent) sendMessage(true) } } ...
}

If you take a look at this again, you will notice that we sent intent to our service on the execution, but since we don't get a return value, we just execute the sendMessage() method with Boolean true as its parameter. Here, we expected a value that represents the result of a CRUD operation, that is, success or failure. We will connect our service with NoteActivity using broadcast messages. Each time we insert or update the note broadcast, a message will be fired. Our listener defined in NoteActivity will respond to this message and trigger the sendMessage() method. Let's update our code! Open the Crud interface and extend it with a companion object containing constants for an action and a CRUD operation result:

    interface Crud<T> { 
      companion object { 
        val BROADCAST_ACTION = "com.journaler.broadcast.crud" 
        val BROADCAST_EXTRAS_KEY_CRUD_OPERATION_RESULT = "crud_result" 
      } 
       ... 
}

Now, open DatabaseService and extend it with a method responsible for sending broadcast messages on CRUD operation execution:

     class DatabaseService : IntentService("DatabaseService") { 
       ... 
       override fun onHandleIntent(p0: Intent?) { 
          p0?.let { 
            val note = p0.getParcelableExtra<Note>(EXTRA_ENTRY) 
            note?.let { 
                val operation = p0.getIntExtra(EXTRA_OPERATION, -1) 
                when (operation) { 
                    MODE.CREATE.mode -> { 
                        val result = Db.insert(note) 
                        if (result) { 
                            Log.i(tag, "Note inserted.") 
                        } else { 
                            Log.e(tag, "Note not inserted.") 
                        } 
                        broadcastResult(result) 
                    } 
                    MODE.EDIT.mode -> { 
                        val result = Db.update(note) 
                        if (result) { 
                            Log.i(tag, "Note updated.") 
                        } else { 
                            Log.e(tag, "Note not updated.") 
                        } 
                        broadcastResult(result) 
                    } 
                    else -> { 
                        Log.w(tag, "Unknown mode [ $operation ]") 
                    } 
                 } 
             } 
           } 
        } 
        ... 
        private fun broadcastResult(result: Boolean) { 
          val intent = Intent() 
          intent.putExtra( 
                Crud.BROADCAST_EXTRAS_KEY_CRUD_OPERATION_RESULT, 
                if (result) { 
                    1 
                } else { 
                    0 
                } 
          ) 
        } }

We introduced a new method. Everything else is the same. We take the CRUD operation result and broadcast it as a message. NoteActivity will listen for it:

   class NoteActivity : ItemActivity() { 
     ... 
     private val crudOperationListener = object : BroadcastReceiver() { 
        override fun onReceive(ctx: Context?, intent: Intent?) { 
            intent?.let { 
                val crudResultValue =
intent.getIntExtra(MODE.EXTRAS_KEY, 0) sendMessage(crudResultValue == 1) } } } ... override fun onCreate(savedInstanceState: Bundle?) { .... registerReceiver(crudOperationListener, intentFiler) } override fun onDestroy() { unregisterReceiver(crudOperationListener) super.onDestroy() } ... private fun sendMessage(result: Boolean) { Log.v(tag, "Crud operation result [ $result ]") val msg = handler?.obtainMessage() if (result) { msg?.arg1 = 1 } else { msg?.arg1 = 0 } handler?.sendMessage(msg) } }

This was simple and easy! We reconnected the original sendMessage() method with the CRUD operation result. In the next sections, we will consider some significant improvements our application can have by listening to boot, shutdown, and network broadcast messages.