Fix:
- remove ForegroundPollingService - check notifications in MyFirebaseMessagingService.onMessageReceived - dont send empty search request. Dependencies: - coreLibraryDesugaringEnabled true - desugar_jdk_libs:1.2.0 - material:1.7.0 - exifinterface:1.3.5 - annotation:1.5.0 - firebase-messaging:23.1.0 - work-runtime-ktx:2.8.0-beta01 - appcompat_version = 1.5.1 - kotlin_version = 1.7.20 - Android Gradle plugin 7.3.1 - google-services:4.3.14
This commit is contained in:
parent
0a73842052
commit
19d626e5f1
|
@ -19,6 +19,7 @@ android {
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
coreLibraryDesugaringEnabled true
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
|
@ -128,6 +129,10 @@ dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation fileTree(include: ['*.aar'], dir: 'src/main/libs')
|
implementation fileTree(include: ['*.aar'], dir: 'src/main/libs')
|
||||||
|
|
||||||
|
// desugar_jdk_libs 2.0.0 は AGP 7.4.0-alpha10 以降を要求する
|
||||||
|
//noinspection GradleDependency
|
||||||
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.0'
|
||||||
|
|
||||||
// targetSdkVersion 31 で androidTest 時に android:exported 云々で怒られる問題の対策
|
// targetSdkVersion 31 で androidTest 時に android:exported 云々で怒られる問題の対策
|
||||||
// https://github.com/android/android-test/issues/1022
|
// https://github.com/android/android-test/issues/1022
|
||||||
androidTestImplementation "androidx.test:core:1.4.0"
|
androidTestImplementation "androidx.test:core:1.4.0"
|
||||||
|
@ -158,9 +163,9 @@ dependencies {
|
||||||
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
|
implementation "androidx.drawerlayout:drawerlayout:1.1.1"
|
||||||
|
|
||||||
// NavigationView
|
// NavigationView
|
||||||
implementation "com.google.android.material:material:1.6.1"
|
implementation "com.google.android.material:material:1.7.0"
|
||||||
|
|
||||||
implementation "androidx.exifinterface:exifinterface:1.3.3"
|
implementation "androidx.exifinterface:exifinterface:1.3.5"
|
||||||
|
|
||||||
// CustomTabs
|
// CustomTabs
|
||||||
implementation "androidx.browser:browser:1.4.0"
|
implementation "androidx.browser:browser:1.4.0"
|
||||||
|
@ -168,10 +173,10 @@ dependencies {
|
||||||
// Recyclerview
|
// Recyclerview
|
||||||
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
||||||
|
|
||||||
kapt 'androidx.annotation:annotation:1.4.0'
|
kapt 'androidx.annotation:annotation:1.5.0'
|
||||||
|
|
||||||
// https://firebase.google.com/support/release-notes/android
|
// https://firebase.google.com/support/release-notes/android
|
||||||
implementation "com.google.firebase:firebase-messaging:23.0.8"
|
implementation "com.google.firebase:firebase-messaging:23.1.0"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-reflect"
|
implementation "org.jetbrains.kotlin:kotlin-reflect"
|
||||||
testImplementation "org.jetbrains.kotlin:kotlin-test"
|
testImplementation "org.jetbrains.kotlin:kotlin-test"
|
||||||
|
@ -262,7 +267,7 @@ dependencies {
|
||||||
// optional - Test helpers for LiveData
|
// optional - Test helpers for LiveData
|
||||||
testImplementation "androidx.arch.core:core-testing:$arch_version"
|
testImplementation "androidx.arch.core:core-testing:$arch_version"
|
||||||
|
|
||||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
implementation 'androidx.work:work-runtime-ktx:2.8.0-beta01'
|
||||||
|
|
||||||
def roomVersion = "2.4.3"
|
def roomVersion = "2.4.3"
|
||||||
implementation "androidx.room:room-runtime:$roomVersion"
|
implementation "androidx.room:room-runtime:$roomVersion"
|
||||||
|
|
|
@ -354,9 +354,6 @@
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
<service
|
|
||||||
android:name="jp.juggler.subwaytooter.notification.ForegroundPollingService"
|
|
||||||
android:exported="false" />
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.startup.InitializationProvider"
|
android:name="androidx.startup.InitializationProvider"
|
||||||
|
|
|
@ -2,12 +2,13 @@ package jp.juggler.subwaytooter
|
||||||
|
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
import com.google.firebase.messaging.RemoteMessage
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
import jp.juggler.subwaytooter.notification.ForegroundPollingService
|
import jp.juggler.subwaytooter.notification.PollingChecker
|
||||||
import jp.juggler.subwaytooter.notification.restartAllWorker
|
import jp.juggler.subwaytooter.notification.restartAllWorker
|
||||||
import jp.juggler.subwaytooter.pref.PrefDevice
|
import jp.juggler.subwaytooter.pref.PrefDevice
|
||||||
import jp.juggler.subwaytooter.table.NotificationCache
|
import jp.juggler.subwaytooter.table.NotificationCache
|
||||||
import jp.juggler.subwaytooter.table.SavedAccount
|
import jp.juggler.subwaytooter.table.SavedAccount
|
||||||
import jp.juggler.util.LogCategory
|
import jp.juggler.util.LogCategory
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class MyFirebaseMessagingService : FirebaseMessagingService() {
|
class MyFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
|
@ -33,9 +34,22 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onNewToken(token: String) {
|
||||||
|
try {
|
||||||
|
log.w("onTokenRefresh: token=$token")
|
||||||
|
PrefDevice.from(this).edit().putString(PrefDevice.KEY_DEVICE_TOKEN, token).apply()
|
||||||
|
restartAllWorker(this)
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
log.trace(ex, "onNewToken failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
||||||
val context = this
|
val context = this
|
||||||
|
|
||||||
|
val messageId = remoteMessage.messageId ?: return
|
||||||
|
if (isDuplicateMessage(messageId)) return
|
||||||
|
|
||||||
val accounts = ArrayList<SavedAccount>()
|
val accounts = ArrayList<SavedAccount>()
|
||||||
for ((key, value) in remoteMessage.data) {
|
for ((key, value) in remoteMessage.data) {
|
||||||
log.w("onMessageReceived: $key=$value")
|
log.w("onMessageReceived: $key=$value")
|
||||||
|
@ -60,19 +74,26 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
NotificationCache.resetLastLoad()
|
NotificationCache.resetLastLoad()
|
||||||
accounts.addAll(SavedAccount.loadAccountList(context))
|
accounts.addAll(SavedAccount.loadAccountList(context))
|
||||||
}
|
}
|
||||||
log.i("accounts.size=${accounts.size}")
|
|
||||||
accounts.forEach {
|
log.i("accounts.size=${accounts.size} thred=${Thread.currentThread().name}")
|
||||||
ForegroundPollingService.start(this, remoteMessage.messageId, it.db_id)
|
runBlocking {
|
||||||
|
accounts.forEach {
|
||||||
|
check(it.db_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewToken(token: String) {
|
private suspend fun check(accountDbId: Long) {
|
||||||
try {
|
try {
|
||||||
log.w("onTokenRefresh: token=$token")
|
PollingChecker(
|
||||||
PrefDevice.from(this).edit().putString(PrefDevice.KEY_DEVICE_TOKEN, token).apply()
|
context = this,
|
||||||
restartAllWorker(this)
|
accountDbId = accountDbId
|
||||||
|
).check { a, s ->
|
||||||
|
val text = "[${a.acct.pretty}]${s.desc}"
|
||||||
|
log.i(text)
|
||||||
|
}
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
log.trace(ex, "onNewToken failed")
|
log.trace(ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1034,7 +1034,7 @@ class TootApiClient(
|
||||||
if (result.error != null) return result
|
if (result.error != null) return result
|
||||||
|
|
||||||
val instance = result.caption // same to instance
|
val instance = result.caption // same to instance
|
||||||
val clientName = if (clientNameArg.isNotEmpty()) clientNameArg else DEFAULT_CLIENT_NAME
|
val clientName = clientNameArg.ifEmpty { DEFAULT_CLIENT_NAME }
|
||||||
val clientInfo =
|
val clientInfo =
|
||||||
ClientInfo.load(instance, clientName) ?: return result.setError("missing client id")
|
ClientInfo.load(instance, clientName) ?: return result.setError("missing client id")
|
||||||
|
|
||||||
|
@ -1271,12 +1271,24 @@ class TootApiClient(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// query: query_string after ? ( ? itself is excluded )
|
|
||||||
suspend fun TootApiClient.requestMastodonSearch(
|
suspend fun TootApiClient.requestMastodonSearch(
|
||||||
parser: TootParser,
|
parser: TootParser,
|
||||||
query: String,
|
// 検索文字列
|
||||||
|
q: String,
|
||||||
|
// リモートサーバの情報を解決するなら真
|
||||||
|
resolve: Boolean,
|
||||||
|
// ギャップ読み込み時の追加パラメータ
|
||||||
|
extra: String = "",
|
||||||
): Pair<TootApiResult?, TootResults?> {
|
): Pair<TootApiResult?, TootResults?> {
|
||||||
|
|
||||||
|
if (q.all { CharacterGroup.isWhitespace(it.code) }) {
|
||||||
|
return Pair(null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val query = "q=${q.encodePercent()}&resolve=$resolve${
|
||||||
|
if (extra.isEmpty()) "" else "&$extra"
|
||||||
|
}"
|
||||||
|
|
||||||
var searchApiVersion = 2
|
var searchApiVersion = 2
|
||||||
var apiResult = request("/api/v2/search?$query")
|
var apiResult = request("/api/v2/search?$query")
|
||||||
?: return Pair(null, null)
|
?: return Pair(null, null)
|
||||||
|
@ -1338,7 +1350,8 @@ suspend fun TootApiClient.syncAccountByUrl(
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${whoUrl.encodePercent()}&resolve=true"
|
q = whoUrl,
|
||||||
|
resolve = true,
|
||||||
)
|
)
|
||||||
val ar = searchResult?.accounts?.firstOrNull()
|
val ar = searchResult?.accounts?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && ar == null) {
|
if (apiResult != null && apiResult.error == null && ar == null) {
|
||||||
|
@ -1380,7 +1393,8 @@ suspend fun TootApiClient.syncAccountByAcct(
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${acct.ascii.encodePercent()}&resolve=true"
|
q = acct.ascii,
|
||||||
|
resolve = true,
|
||||||
)
|
)
|
||||||
val ar = searchResult?.accounts?.firstOrNull()
|
val ar = searchResult?.accounts?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && ar == null) {
|
if (apiResult != null && apiResult.error == null && ar == null) {
|
||||||
|
@ -1450,7 +1464,8 @@ suspend fun TootApiClient.syncStatus(
|
||||||
} else {
|
} else {
|
||||||
val (apiResult, searchResult) = requestMastodonSearch(
|
val (apiResult, searchResult) = requestMastodonSearch(
|
||||||
parser,
|
parser,
|
||||||
"q=${url.encodePercent()}&resolve=true"
|
q = url,
|
||||||
|
resolve = true,
|
||||||
)
|
)
|
||||||
val targetStatus = searchResult?.statuses?.firstOrNull()
|
val targetStatus = searchResult?.statuses?.firstOrNull()
|
||||||
if (apiResult != null && apiResult.error == null && targetStatus == null) {
|
if (apiResult != null && apiResult.error == null && targetStatus == null) {
|
||||||
|
|
|
@ -921,10 +921,13 @@ class ColumnTask_Gap(
|
||||||
column.listData.forEach { counter(it) }
|
column.listData.forEach { counter(it) }
|
||||||
|
|
||||||
// https://mastodon2.juggler.jp/api/v2/search?q=gargron&type=accounts&offset=5
|
// https://mastodon2.juggler.jp/api/v2/search?q=gargron&type=accounts&offset=5
|
||||||
var query = "q=${column.searchQuery.encodePercent()}&type=$type&offset=$offset"
|
|
||||||
if (column.searchResolve) query += "&resolve=1"
|
|
||||||
|
|
||||||
val (apiResult, searchResult) = client.requestMastodonSearch(parser, query)
|
val (apiResult, searchResult) = client.requestMastodonSearch(
|
||||||
|
parser,
|
||||||
|
q= column.searchQuery,
|
||||||
|
resolve = column.searchResolve,
|
||||||
|
extra = "type=$type&offset=$offset",
|
||||||
|
)
|
||||||
if (searchResult != null) {
|
if (searchResult != null) {
|
||||||
listTmp = ArrayList()
|
listTmp = ArrayList()
|
||||||
addAll(listTmp, searchResult.hashtags)
|
addAll(listTmp, searchResult.hashtags)
|
||||||
|
|
|
@ -1220,10 +1220,11 @@ class ColumnTask_Loading(
|
||||||
val (instance, instanceResult) = TootInstance.get(client)
|
val (instance, instanceResult) = TootInstance.get(client)
|
||||||
instance ?: return instanceResult
|
instance ?: return instanceResult
|
||||||
|
|
||||||
var query = "q=${column.searchQuery.encodePercent()}"
|
val (apiResult, searchResult) = client.requestMastodonSearch(
|
||||||
if (column.searchResolve) query += "&resolve=1"
|
parser,
|
||||||
|
q=column.searchQuery,
|
||||||
val (apiResult, searchResult) = client.requestMastodonSearch(parser, query)
|
resolve = column.searchResolve,
|
||||||
|
)
|
||||||
if (searchResult != null) {
|
if (searchResult != null) {
|
||||||
listTmp = ArrayList()
|
listTmp = ArrayList()
|
||||||
addAll(listTmp, searchResult.hashtags)
|
addAll(listTmp, searchResult.hashtags)
|
||||||
|
|
|
@ -1,130 +1,130 @@
|
||||||
package jp.juggler.subwaytooter.notification
|
//package jp.juggler.subwaytooter.notification
|
||||||
|
//
|
||||||
import android.app.Service
|
//import android.app.Service
|
||||||
import android.content.Context
|
//import android.content.Context
|
||||||
import android.content.Intent
|
//import android.content.Intent
|
||||||
import android.os.IBinder
|
//import android.os.IBinder
|
||||||
import android.os.SystemClock
|
//import android.os.SystemClock
|
||||||
import androidx.core.content.ContextCompat
|
//import androidx.core.content.ContextCompat
|
||||||
import jp.juggler.subwaytooter.global.appDispatchers
|
//import jp.juggler.subwaytooter.global.appDispatchers
|
||||||
import jp.juggler.subwaytooter.notification.CheckerWakeLocks.Companion.checkerWakeLocks
|
//import jp.juggler.subwaytooter.notification.CheckerWakeLocks.Companion.checkerWakeLocks
|
||||||
import jp.juggler.util.EmptyScope
|
//import jp.juggler.util.EmptyScope
|
||||||
import jp.juggler.util.LogCategory
|
//import jp.juggler.util.LogCategory
|
||||||
import jp.juggler.util.launchMain
|
//import jp.juggler.util.launchMain
|
||||||
import kotlinx.coroutines.channels.Channel
|
//import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.channels.ClosedReceiveChannelException
|
//import kotlinx.coroutines.channels.ClosedReceiveChannelException
|
||||||
import kotlinx.coroutines.launch
|
//import kotlinx.coroutines.launch
|
||||||
import kotlin.math.max
|
//import kotlin.math.max
|
||||||
|
//
|
||||||
class ForegroundPollingService : Service() {
|
//class ForegroundPollingService : Service() {
|
||||||
companion object {
|
// companion object {
|
||||||
private val log = LogCategory("ForegroundPollingService")
|
// private val log = LogCategory("ForegroundPollingService")
|
||||||
private const val NOTIFICATION_ID_FOREGROUND_POLLING = 4
|
// private const val NOTIFICATION_ID_FOREGROUND_POLLING = 4
|
||||||
private const val EXTRA_ACCOUNT_DB_ID = "accountDbId"
|
// private const val EXTRA_ACCOUNT_DB_ID = "accountDbId"
|
||||||
private const val EXTRA_MESSAGE_ID = "messageId"
|
// private const val EXTRA_MESSAGE_ID = "messageId"
|
||||||
|
//
|
||||||
fun start(
|
// fun start(
|
||||||
context: Context,
|
// context: Context,
|
||||||
messageId: String?,
|
// messageId: String?,
|
||||||
dbId: Long,
|
// dbId: Long,
|
||||||
) {
|
// ) {
|
||||||
val intent = Intent(context, ForegroundPollingService::class.java).apply {
|
// val intent = Intent(context, ForegroundPollingService::class.java).apply {
|
||||||
putExtra(EXTRA_ACCOUNT_DB_ID, dbId)
|
// putExtra(EXTRA_ACCOUNT_DB_ID, dbId)
|
||||||
putExtra(EXTRA_MESSAGE_ID, messageId)
|
// putExtra(EXTRA_MESSAGE_ID, messageId)
|
||||||
}
|
// }
|
||||||
ContextCompat.startForegroundService(context, intent)
|
// ContextCompat.startForegroundService(context, intent)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private class Item(
|
// private class Item(
|
||||||
val accountDbId: Long,
|
// val accountDbId: Long,
|
||||||
var lastRequired: Long = 0L,
|
// var lastRequired: Long = 0L,
|
||||||
var lastHandled: Long = 0L,
|
// var lastHandled: Long = 0L,
|
||||||
var lastStartId: Int = 0,
|
// var lastStartId: Int = 0,
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
private val map = HashMap<Long, Item>()
|
// private val map = HashMap<Long, Item>()
|
||||||
private val channel = Channel<Long>()
|
// private val channel = Channel<Long>()
|
||||||
|
//
|
||||||
override fun onBind(intent: Intent?): IBinder? = null
|
// override fun onBind(intent: Intent?): IBinder? = null
|
||||||
|
//
|
||||||
override fun onCreate() {
|
// override fun onCreate() {
|
||||||
log.i("onCreate")
|
// log.i("onCreate")
|
||||||
super.onCreate()
|
// super.onCreate()
|
||||||
checkerWakeLocks(this).acquireWakeLocks()
|
// checkerWakeLocks(this).acquireWakeLocks()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onDestroy() {
|
// override fun onDestroy() {
|
||||||
log.i("onDestroy")
|
// log.i("onDestroy")
|
||||||
super.onDestroy()
|
// super.onDestroy()
|
||||||
checkerWakeLocks(this).releasePowerLocks()
|
// checkerWakeLocks(this).releasePowerLocks()
|
||||||
channel.close()
|
// channel.close()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
// override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
val accountDbId = intent?.getLongExtra(EXTRA_ACCOUNT_DB_ID, -1L) ?: -1L
|
// val accountDbId = intent?.getLongExtra(EXTRA_ACCOUNT_DB_ID, -1L) ?: -1L
|
||||||
val now = SystemClock.elapsedRealtime()
|
// val now = SystemClock.elapsedRealtime()
|
||||||
log.i("onStartCommand startId=$startId, accountDbId=$accountDbId")
|
// log.i("onStartCommand startId=$startId, accountDbId=$accountDbId")
|
||||||
synchronized(map) {
|
// synchronized(map) {
|
||||||
map.getOrPut(accountDbId) {
|
// map.getOrPut(accountDbId) {
|
||||||
Item(accountDbId = accountDbId)
|
// Item(accountDbId = accountDbId)
|
||||||
}.apply {
|
// }.apply {
|
||||||
lastRequired = now
|
// lastRequired = now
|
||||||
lastStartId = startId
|
// lastStartId = startId
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
launchMain {
|
// launchMain {
|
||||||
try {
|
// try {
|
||||||
channel.send(now)
|
// channel.send(now)
|
||||||
} catch (ex: Throwable) {
|
// } catch (ex: Throwable) {
|
||||||
log.trace(ex)
|
// log.trace(ex)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return START_NOT_STICKY
|
// return START_NOT_STICKY
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
init {
|
// init {
|
||||||
EmptyScope.launch(appDispatchers.default) {
|
// EmptyScope.launch(appDispatchers.default) {
|
||||||
var lastStartId = 0
|
// var lastStartId = 0
|
||||||
while (true) {
|
// while (true) {
|
||||||
try {
|
// try {
|
||||||
val target = synchronized(map) {
|
// val target = synchronized(map) {
|
||||||
map.values
|
// map.values
|
||||||
.filter { it.lastRequired > it.lastHandled }
|
// .filter { it.lastRequired > it.lastHandled }
|
||||||
.minByOrNull { it.lastRequired }
|
// .minByOrNull { it.lastRequired }
|
||||||
?.also { it.lastHandled = it.lastRequired }
|
// ?.also { it.lastHandled = it.lastRequired }
|
||||||
}
|
// }
|
||||||
if (target != null) {
|
// if (target != null) {
|
||||||
lastStartId = max(lastStartId, target.lastStartId)
|
// lastStartId = max(lastStartId, target.lastStartId)
|
||||||
check(target.accountDbId)
|
// check(target.accountDbId)
|
||||||
continue
|
// continue
|
||||||
}
|
// }
|
||||||
log.i("stopSelf lastStartId=$lastStartId")
|
// log.i("stopSelf lastStartId=$lastStartId")
|
||||||
if (lastStartId != 0) stopSelf(lastStartId)
|
// if (lastStartId != 0) stopSelf(lastStartId)
|
||||||
channel.receive()
|
// channel.receive()
|
||||||
} catch (ignored: ClosedReceiveChannelException) {
|
// } catch (ignored: ClosedReceiveChannelException) {
|
||||||
log.i("channel closed.")
|
// log.i("channel closed.")
|
||||||
break
|
// break
|
||||||
} catch (ex: Throwable) {
|
// } catch (ex: Throwable) {
|
||||||
log.trace(ex)
|
// log.trace(ex)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private suspend fun check(accountDbId: Long) {
|
// private suspend fun check(accountDbId: Long) {
|
||||||
try {
|
// try {
|
||||||
PollingChecker(
|
// PollingChecker(
|
||||||
context = this@ForegroundPollingService,
|
// context = this@ForegroundPollingService,
|
||||||
accountDbId = accountDbId
|
// accountDbId = accountDbId
|
||||||
).check { a, s ->
|
// ).check { a, s ->
|
||||||
val text = "[${a.acct.pretty}]${s.desc}"
|
// val text = "[${a.acct.pretty}]${s.desc}"
|
||||||
CheckerNotification.showMessage(this, text) {
|
// CheckerNotification.showMessage(this, text) {
|
||||||
startForeground(NOTIFICATION_ID_FOREGROUND_POLLING, it)
|
// startForeground(NOTIFICATION_ID_FOREGROUND_POLLING, it)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
} catch (ex: Throwable) {
|
// } catch (ex: Throwable) {
|
||||||
log.trace(ex)
|
// log.trace(ex)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package jp.juggler.subwaytooter.notification
|
package jp.juggler.subwaytooter.notification
|
||||||
|
|
||||||
|
import android.app.ActivityManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.work.*
|
import androidx.work.*
|
||||||
import jp.juggler.subwaytooter.App1
|
import jp.juggler.subwaytooter.App1
|
||||||
|
@ -91,10 +92,18 @@ class PollingWorker2(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isAppForehround(): Boolean {
|
||||||
|
val processInfo = ActivityManager.RunningAppProcessInfo()
|
||||||
|
ActivityManager.getMyMemoryState(processInfo)
|
||||||
|
return processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun showMessage(text: String) =
|
private suspend fun showMessage(text: String) =
|
||||||
CheckerNotification.showMessage(applicationContext, text) {
|
CheckerNotification.showMessage(applicationContext, text) {
|
||||||
try {
|
try {
|
||||||
setForeground(ForegroundInfo(NOTIFICATION_ID_POLLING_WORKER, it))
|
if(!isAppForehround()) error("app is not foreground.")
|
||||||
|
setForegroundAsync(ForegroundInfo(NOTIFICATION_ID_POLLING_WORKER,it))
|
||||||
|
.await()
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
log.e(ex, "showMessage failed.")
|
log.e(ex, "showMessage failed.")
|
||||||
}
|
}
|
||||||
|
|
10
build.gradle
10
build.gradle
|
@ -7,11 +7,11 @@ buildscript {
|
||||||
ext.compile_sdk_version = 33
|
ext.compile_sdk_version = 33
|
||||||
ext.build_tools_version = "33.0.0"
|
ext.build_tools_version = "33.0.0"
|
||||||
|
|
||||||
ext.appcompat_version = "1.5.0"
|
ext.appcompat_version = "1.5.1"
|
||||||
ext.lifecycle_version = "2.5.1"
|
ext.lifecycle_version = "2.5.1"
|
||||||
ext.arch_version = "2.1.0"
|
ext.arch_version = "2.1.0"
|
||||||
|
|
||||||
ext.kotlin_version = '1.7.10'
|
ext.kotlin_version = '1.7.20'
|
||||||
ext.kotlinx_coroutines_version = '1.6.4'
|
ext.kotlinx_coroutines_version = '1.6.4'
|
||||||
|
|
||||||
ext.anko_version = '0.10.8'
|
ext.anko_version = '0.10.8'
|
||||||
|
@ -30,13 +30,11 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.2.2'
|
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||||
|
|
||||||
// room のバージョンの影響で google-services を上げられない場合がある
|
// room のバージョンの影響で google-services を上げられない場合がある
|
||||||
//noinspection GradleDependency
|
classpath 'com.google.gms:google-services:4.3.14'
|
||||||
classpath 'com.google.gms:google-services:4.3.10'
|
|
||||||
|
|
||||||
//noinspection DifferentKotlinGradleVersion
|
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue