I have a messaging app that receives instant messages over a websocket. However there seems to be no reliable way to persist this connection so that the user can receive messages and notifications while the app is closed. I've looked into various options such as the WorkManager and JobScheduler API's, but they don't meet my needs. WorkManager supports coroutines but doesn't have a nice way of restarting it if its killed by the system, and JobScheduler has the onStopJob() method to help with restarts, but has no support for coroutines. I've included my current solution below. I figure this is a common problem for messaging apps so there has to be a supported solution somewhere right?
Manifest:
<receiver
android:name=".messaging.MessagingService"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="com.rld.datingapp.RESTART_MESSAGING_LISTENER"/>
</intent-filter>
</receiver>
Receiver:
class MessageStarter: BroadcastReceiver() {
@RequiresApi(Build.VERSION_CODES.S)
override fun onReceive(context: Context, intent: Intent) {
if(intent.action == Intent.ACTION_BOOT_COMPLETED || intent.action == MESSAGING_RESTART_BROADCAST) {
Log.d(MESSAGING_LOG_TAG, "Starting Service")
val scheduler = context.getSystemService(JobScheduler::class.java) as JobScheduler
scheduler.schedule(
JobInfo.Builder(id++, ComponentName(context.applicationContext, MessagingService::class.java))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setPersisted(true)
.setExpedited(true)
.setOverrideDeadline(0)
.build()
)
} else Log.d(MESSAGING_LOG_TAG, "Received another intent")
}
companion object {
const val MESSAGING_RESTART_BROADCAST = "com.rld.datingapp.RESTART_MESSAGING_LISTENER"
const val MESSAGING_LOG_TAG = "$LOGGER_TAG Worker 1"
var id = 0
}
}
Service:
class MessagingService: JobService() {
init {
Configuration.Builder() //stop the warning
.setJobSchedulerJobIdRange(0, 1000)
.build()
}
override fun onStartJob(params: JobParameters): Boolean {
Dispatchers.IO.apply {
dispatch(this) {
//do our work
}
}
return true
}
override fun onStopJob(params: JobParameters): Boolean {
Log.d(MESSAGING_LOG_TAG, "Restarting Service")
baseContext.sendBroadcast(Intent(MESSAGING_RESTART_BROADCAST))
return false //receiver will restart it
}
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744342778a4569502.html
评论列表(0条)