Add notification when server app is not installed
And fix showSingle notifications: the shown ref was shared
This commit is contained in:
parent
25d8cf397e
commit
3e83f3d07d
|
@ -17,6 +17,7 @@ import org.unifiedpush.distributor.nextpush.account.AccountType
|
|||
import org.unifiedpush.distributor.nextpush.api.provider.* // ktlint-disable no-wildcard-imports
|
||||
import org.unifiedpush.distributor.nextpush.api.provider.ApiProvider.Companion.mApiEndpoint
|
||||
import org.unifiedpush.distributor.nextpush.api.response.ApiResponse
|
||||
import org.unifiedpush.distributor.nextpush.utils.NoServerAppNotification
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
|
||||
|
@ -35,14 +36,9 @@ class Api(context: Context) {
|
|||
}.getProviderAndExecute(block)
|
||||
}
|
||||
|
||||
fun apiDestroy() {
|
||||
Log.d(TAG, "Destroying API")
|
||||
syncSource.getAndSet(null)?.cancel()
|
||||
}
|
||||
|
||||
fun apiSync() {
|
||||
private fun tryWithDeviceId(block: (String) -> Unit) {
|
||||
context.npDeviceId?.let {
|
||||
syncDevice(it)
|
||||
block(it)
|
||||
}
|
||||
?: run {
|
||||
Log.d(TAG, "No deviceId found.")
|
||||
|
@ -61,6 +57,7 @@ class Api(context: Context) {
|
|||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
NoServerAppNotification(context).showBig()
|
||||
e.printStackTrace()
|
||||
then()
|
||||
}
|
||||
|
@ -68,7 +65,7 @@ class Api(context: Context) {
|
|||
override fun onComplete() {
|
||||
// Sync once it is registered
|
||||
context.npDeviceId?.let {
|
||||
syncDevice(it)
|
||||
block(it)
|
||||
}
|
||||
Log.d(TAG, "mApi register: onComplete")
|
||||
then()
|
||||
|
@ -81,57 +78,65 @@ class Api(context: Context) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun syncDevice(deviceId: String) {
|
||||
val client = OkHttpClient.Builder()
|
||||
.readTimeout(0, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(false)
|
||||
.build()
|
||||
val url = "$baseUrl${mApiEndpoint}device/$deviceId"
|
||||
fun apiDestroy() {
|
||||
Log.d(TAG, "Destroying API")
|
||||
syncSource.getAndSet(null)?.cancel()
|
||||
}
|
||||
|
||||
val request = Request.Builder().url(url)
|
||||
.get()
|
||||
.build()
|
||||
fun apiSync() {
|
||||
tryWithDeviceId { deviceId ->
|
||||
val client = OkHttpClient.Builder()
|
||||
.readTimeout(0, TimeUnit.SECONDS)
|
||||
.retryOnConnectionFailure(false)
|
||||
.build()
|
||||
val url = "$baseUrl${mApiEndpoint}device/$deviceId"
|
||||
|
||||
syncSource.set(
|
||||
EventSources.createFactory(client).newEventSource(
|
||||
request,
|
||||
SSEListener(context)
|
||||
val request = Request.Builder().url(url)
|
||||
.get()
|
||||
.build()
|
||||
|
||||
syncSource.set(
|
||||
EventSources.createFactory(client).newEventSource(
|
||||
request,
|
||||
SSEListener(context)
|
||||
)
|
||||
)
|
||||
)
|
||||
Log.d(TAG, "cSync done.")
|
||||
Log.d(TAG, "cSync done.")
|
||||
}
|
||||
}
|
||||
|
||||
fun apiDeleteDevice(block: () -> Unit = {}) {
|
||||
val deviceId = context.npDeviceId ?: return
|
||||
try {
|
||||
withApiProvider { apiProvider, then ->
|
||||
apiProvider.deleteDevice(deviceId)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : DisposableObserver<ApiResponse>() {
|
||||
override fun onNext(response: ApiResponse) {
|
||||
if (response.success) {
|
||||
Log.d(TAG, "Device successfully deleted.")
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while deleting the device.")
|
||||
tryWithDeviceId { deviceId ->
|
||||
try {
|
||||
withApiProvider { apiProvider, then ->
|
||||
apiProvider.deleteDevice(deviceId)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : DisposableObserver<ApiResponse>() {
|
||||
override fun onNext(response: ApiResponse) {
|
||||
if (response.success) {
|
||||
Log.d(TAG, "Device successfully deleted.")
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while deleting the device.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
block()
|
||||
then()
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
block()
|
||||
then()
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
block()
|
||||
then()
|
||||
}
|
||||
})
|
||||
context.npDeviceId = null
|
||||
override fun onComplete() {
|
||||
block()
|
||||
then()
|
||||
}
|
||||
})
|
||||
context.npDeviceId = null
|
||||
}
|
||||
} catch (e: NoProviderException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} catch (e: NoProviderException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,43 +144,43 @@ class Api(context: Context) {
|
|||
appName: String,
|
||||
block: (String?) -> Unit
|
||||
) {
|
||||
// The unity of connector token must already be checked here
|
||||
val parameters = context.npDeviceId?.let {
|
||||
mutableMapOf(
|
||||
"deviceId" to it,
|
||||
tryWithDeviceId { deviceId ->
|
||||
// The unity of connector token must already be checked here
|
||||
val parameters = mutableMapOf(
|
||||
"deviceId" to deviceId,
|
||||
"appName" to appName
|
||||
)
|
||||
} ?: return
|
||||
try {
|
||||
withApiProvider { apiProvider, then ->
|
||||
apiProvider.createApp(parameters)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : DisposableObserver<ApiResponse>() {
|
||||
override fun onNext(response: ApiResponse) {
|
||||
val nextpushToken = if (response.success) {
|
||||
Log.d(TAG, "App successfully created.")
|
||||
response.token
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while creating the application.")
|
||||
null
|
||||
try {
|
||||
withApiProvider { apiProvider, then ->
|
||||
apiProvider.createApp(parameters)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : DisposableObserver<ApiResponse>() {
|
||||
override fun onNext(response: ApiResponse) {
|
||||
val nextpushToken = if (response.success) {
|
||||
Log.d(TAG, "App successfully created.")
|
||||
response.token
|
||||
} else {
|
||||
Log.d(TAG, "An error occurred while creating the application.")
|
||||
null
|
||||
}
|
||||
block(nextpushToken)
|
||||
}
|
||||
block(nextpushToken)
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
block(null)
|
||||
then()
|
||||
}
|
||||
override fun onError(e: Throwable) {
|
||||
e.printStackTrace()
|
||||
block(null)
|
||||
then()
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
then()
|
||||
}
|
||||
})
|
||||
override fun onComplete() {
|
||||
then()
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (e: NoProviderException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} catch (e: NoProviderException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.app.PendingIntent
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
|
@ -40,11 +41,12 @@ data class NotificationData(
|
|||
|
||||
open class AppNotification(
|
||||
private val context: Context,
|
||||
private val shown: AtomicBoolean,
|
||||
private val notificationId: Int,
|
||||
private val notificationData: NotificationData,
|
||||
private val channelData: ChannelData
|
||||
private val channelData: ChannelData,
|
||||
) {
|
||||
private fun createNotificationChannel() {
|
||||
internal fun createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
@ -60,7 +62,7 @@ open class AppNotification(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createNotification(
|
||||
internal fun createNotification(
|
||||
intent: PendingIntent?,
|
||||
bigText: Boolean = false
|
||||
): Notification {
|
||||
|
@ -124,7 +126,7 @@ open class AppNotification(
|
|||
}
|
||||
}
|
||||
|
||||
fun create(bigText: Boolean = false): Notification {
|
||||
open fun create(bigText: Boolean = false): Notification {
|
||||
createNotificationChannel()
|
||||
|
||||
return createNotification(
|
||||
|
@ -154,10 +156,6 @@ open class AppNotification(
|
|||
deleteNotification(notificationId)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val shown = AtomicBoolean(false)
|
||||
}
|
||||
}
|
||||
|
||||
private val Context.warningChannelData: ChannelData
|
||||
|
@ -170,6 +168,7 @@ private val Context.warningChannelData: ChannelData
|
|||
|
||||
class DisconnectedNotification(context: Context) : AppNotification(
|
||||
context,
|
||||
Notifications.disconnectedShown,
|
||||
NOTIFICATION_ID_WARNING,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
|
@ -183,6 +182,7 @@ class DisconnectedNotification(context: Context) : AppNotification(
|
|||
|
||||
class NoPingNotification(context: Context) : AppNotification(
|
||||
context,
|
||||
Notifications.noPingShown,
|
||||
NOTIFICATION_ID_NO_PING,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
|
@ -196,6 +196,7 @@ class NoPingNotification(context: Context) : AppNotification(
|
|||
|
||||
class NoStartNotification(context: Context) : AppNotification(
|
||||
context,
|
||||
Notifications.noStartShown,
|
||||
NOTIFICATION_ID_NO_START,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
|
@ -207,8 +208,34 @@ class NoStartNotification(context: Context) : AppNotification(
|
|||
context.warningChannelData
|
||||
)
|
||||
|
||||
class NoServerAppNotification(val context: Context) : AppNotification(
|
||||
context,
|
||||
Notifications.noServerShown,
|
||||
NOTIFICATION_ID_NO_START,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
context.getString(R.string.no_server_app_notif_content),
|
||||
context.getString(R.string.warning_notif_ticker),
|
||||
Notification.PRIORITY_HIGH,
|
||||
false
|
||||
),
|
||||
context.warningChannelData
|
||||
) {
|
||||
override fun create(bigText: Boolean): Notification{
|
||||
createNotificationChannel()
|
||||
|
||||
val notificationIntent = Intent(Intent.ACTION_VIEW)
|
||||
notificationIntent.setData(Uri.parse("https://apps.nextcloud.com/apps/uppush"))
|
||||
return createNotification(
|
||||
PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE),
|
||||
bigText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class LowKeepAliveNotification(context: Context, keepalive: Int) : AppNotification(
|
||||
context,
|
||||
Notifications.lowKeepAliveShown,
|
||||
NOTIFICATION_ID_LOW_KEEPALIVE,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
|
@ -222,6 +249,7 @@ class LowKeepAliveNotification(context: Context, keepalive: Int) : AppNotificati
|
|||
|
||||
class ForegroundNotification(context: Context) : AppNotification(
|
||||
context,
|
||||
Notifications.ignoreShown,
|
||||
NOTIFICATION_ID_FOREGROUND,
|
||||
NotificationData(
|
||||
context.getString(R.string.app_name),
|
||||
|
@ -245,6 +273,7 @@ class ForegroundNotification(context: Context) : AppNotification(
|
|||
|
||||
class FromPushNotification(context: Context, title: String, content: String) : AppNotification(
|
||||
context,
|
||||
Notifications.ignoreShown,
|
||||
Notifications.nextNotificationId.getAndIncrement(),
|
||||
NotificationData(
|
||||
title,
|
||||
|
@ -263,4 +292,10 @@ class FromPushNotification(context: Context, title: String, content: String) : A
|
|||
|
||||
private object Notifications {
|
||||
val nextNotificationId = AtomicInteger(50000)
|
||||
val disconnectedShown = AtomicBoolean(false)
|
||||
val noPingShown = AtomicBoolean(false)
|
||||
val noStartShown = AtomicBoolean(false)
|
||||
val noServerShown = AtomicBoolean(false)
|
||||
val lowKeepAliveShown = AtomicBoolean(false)
|
||||
val ignoreShown = AtomicBoolean(true)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<string name="warning_notif_content">NextPush is disconnected</string>
|
||||
<string name="warning_notif_description">Warn when NextPush is disconnected or an issue occurred.</string>
|
||||
<string name="warning_notif_ticker">Warning</string>
|
||||
<string name="no_server_app_notif_content">Couldn\'t create a device.\n\nYou have probably not installed the UnifiedPush Provider application on your nextcloud server.</string>
|
||||
<string name="start_error_notif_content">The service could not be started correctly. Check the configuration of your server. You may be using a reverse proxy with buffering enabled.</string>
|
||||
<string name="low_keepalive_notif_content">The server app is configured with a low keepalive: %ss. It will drain your battery. We recommend using a higher keepalive.</string>
|
||||
<string name="no_ping_notif_content">NextPush was disconnected 5 times before receiving the ping. You probably have a problem with your server configuration. Your reverse proxy timeout is probably too low.</string>
|
||||
|
|
Loading…
Reference in New Issue