Skip to content

Commit

Permalink
implemented scheduled worker for record schedule checker
Browse files Browse the repository at this point in the history
  • Loading branch information
akihito104 committed Feb 10, 2020
1 parent 9f06739 commit c3b1d22
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 35 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
@@ -0,0 +1,4 @@
[*]
insert_final_newline = true
[*.{kt,kts}]
indent_size=4
1 change: 1 addition & 0 deletions app/build.gradle
Expand Up @@ -41,6 +41,7 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-livedata-core-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "androidx.work:work-runtime-ktx:2.3.1"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

implementation 'net.mm2d:mmupnp:3.1.1'
Expand Down
13 changes: 10 additions & 3 deletions app/src/main/AndroidManifest.xml
@@ -1,19 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.freshdigitable.upnpsample">

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".App"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand Down
45 changes: 45 additions & 0 deletions app/src/main/java/com/freshdigitable/upnpsample/App.kt
@@ -0,0 +1,45 @@
package com.freshdigitable.upnpsample

import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationManagerCompat
import androidx.work.Configuration
import androidx.work.ListenableWorker
import androidx.work.WorkManager
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters

class App : Application() {
override fun onCreate() {
super.onCreate()

val conf = Configuration.Builder()
.setWorkerFactory(object : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? {
return RecordScheduleCheckWorker(appContext, workerParameters)
}
})
.build()
WorkManager.initialize(this, conf)

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel =
NotificationChannel(
getString(R.string.notif_schedule_checker_channel_id),
getString(R.string.notif_schedule_checker_name),
NotificationManager.IMPORTANCE_DEFAULT
).apply {
description = getString(R.string.notif_schedule_checker_description)
}
NotificationManagerCompat.from(this)
.createNotificationChannel(notificationChannel)
}
}
}
23 changes: 12 additions & 11 deletions app/src/main/java/com/freshdigitable/upnpsample/MainActivity.kt
Expand Up @@ -3,24 +3,25 @@ package com.freshdigitable.upnpsample
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import java.util.concurrent.TimeUnit

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val nasneDeviceProvider = NasneDeviceProvider(this)
lifecycleScope.launchWhenCreated {
nasneDeviceProvider.init()
val nasneDevice = nasneDeviceProvider.findDevice()
logd("recordScheduleList", nasneDevice.getRecordScheduleList())
logd("getTitleList", nasneDevice.getTitleList())
nasneDeviceProvider.dispose()

}

val workRequest =
PeriodicWorkRequestBuilder<RecordScheduleCheckWorker>(30, TimeUnit.MINUTES)
.build()
WorkManager.getInstance(this).enqueueUniquePeriodicWork(
"scheduleChecker",
ExistingPeriodicWorkPolicy.REPLACE,
workRequest
)
}

companion object {
Expand Down
47 changes: 26 additions & 21 deletions app/src/main/java/com/freshdigitable/upnpsample/NasneDevice.kt
Expand Up @@ -8,19 +8,37 @@ import kotlin.coroutines.suspendCoroutine
class NasneDevice(
private val nasne: Device
) {
suspend fun getRecordScheduleList(): RecordScheduleResultResponse<RecordScheduleItem> {
val args = mapOf(
"SearchCriteria" to "",
"Filter" to "",
"StartingIndex" to "",
"RequestedCount" to "",
"SortCriteria" to ""
)
suspend fun getRecordScheduleList(
startingIndex: Int? = null,
count: Int? = null
): RecordScheduleResultResponse<RecordScheduleItem> {
val args = recordScheduleArgs(startingIndex, count)
return action("X_GetRecordScheduleList", args) { res ->
RecordScheduleResultResponse.create(res) { node -> RecordScheduleItem.createItem(node) }
}
}

suspend fun getTitleList(
startingIndex: Int? = null,
count: Int? = null
): RecordScheduleResultResponse<TitleItem> {
val args = recordScheduleArgs(startingIndex, count)
return action("X_GetTitleList", args) { map ->
RecordScheduleResultResponse.create(map) { node -> TitleItem.createItem(node) }
}
}

private fun recordScheduleArgs(
startingIndex: Int? = null,
count: Int? = null
): Map<String, String> = mapOf(
"SearchCriteria" to "",
"Filter" to "",
"StartingIndex" to (startingIndex?.toString() ?: ""),
"RequestedCount" to (count?.toString() ?: ""),
"SortCriteria" to ""
)

suspend fun getConflictList(): RecordScheduleResultResponse<RecordScheduleItem> { // わからん
val args = mapOf(
"Elements" to ""
Expand All @@ -30,19 +48,6 @@ class NasneDevice(
}
}

suspend fun getTitleList(): RecordScheduleResultResponse<TitleItem> {
val args = mapOf(
"SearchCriteria" to "",
"Filter" to "",
"StartingIndex" to "",
"RequestedCount" to "10",
"SortCriteria" to ""
)
return action("X_GetTitleList", args) { map ->
RecordScheduleResultResponse.create(map) { node -> TitleItem.createItem(node) }
}
}

suspend fun getLiveChList(): PvrRes {
val args = mapOf(
"BroadcastType" to "",
Expand Down
@@ -0,0 +1,44 @@
package com.freshdigitable.upnpsample

import android.content.Context
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters

class RecordScheduleCheckWorker(
private val context: Context,
param: WorkerParameters
) : CoroutineWorker(context, param) {
override suspend fun doWork(): Result {
withDevice {
val recordScheduleList = getRecordScheduleList()
MainActivity.logd("recordSchedule", recordScheduleList)
val mediaAlert = recordScheduleList.result
.filter { it.hasWarnings }
.joinToString { it.title }
if (mediaAlert.isEmpty()) {
return Result.success()
}
val notif = NotificationCompat.Builder(
context,
context.getString(R.string.notif_schedule_checker_channel_id)
)
.setSmallIcon(R.drawable.ic_warning_black_24dp)
.setContentTitle("録画が失敗しそうです")
.setContentText("notice: $mediaAlert")
.build()
NotificationManagerCompat.from(context)
.notify(0, notif)
}
return Result.success()
}

private suspend inline fun withDevice(block: NasneDevice.() -> Unit) {
val nasneDeviceProvider = NasneDeviceProvider(context)
nasneDeviceProvider.init()
val nasneDevice = nasneDeviceProvider.findDevice()
block(nasneDevice)
nasneDeviceProvider.dispose()
}
}
Expand Up @@ -21,6 +21,9 @@ data class RecordScheduleItem(
var recordSize: Int = 0,
var portableRecordFile: String = ""
) {
val hasWarnings: Boolean
get () = mediaRemainAlertID.isNotEmpty() || conflictID.isNotEmpty()

companion object {
private val TAG = RecordScheduleItem::class.java.simpleName

Expand Down
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_warning_black_24dp.xml
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
@@ -1,3 +1,6 @@
<resources>
<string name="app_name">upnp sample</string>
<string name="notif_schedule_checker_channel_id" translatable="false">scheduleChecker</string>
<string name="notif_schedule_checker_name" translatable="false">scheduleChecker</string>
<string name="notif_schedule_checker_description">scheduleChecker description</string>
</resources>

0 comments on commit c3b1d22

Please sign in to comment.