Add support for Android 5.0

This commit is contained in:
Moez Bhatti
2018-06-11 20:16:16 -04:00
parent 9ced706ff0
commit 73887558fa
21 changed files with 205 additions and 125 deletions
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package compat
import android.annotation.TargetApi
import android.os.Build
import android.telephony.SubscriptionInfo
@TargetApi(Build.VERSION_CODES.LOLLIPOP_MR1)
data class SubscriptionInfoCompat(private val subscriptionInfo: SubscriptionInfo) {
val subscriptionId get() = subscriptionInfo.subscriptionId
val simSlotIndex get() = subscriptionInfo.simSlotIndex
}
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
*
* This file is part of QKSMS.
*
* QKSMS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* QKSMS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
*/
package compat
import android.content.Context
import android.os.Build
import android.telephony.SubscriptionManager
import manager.PermissionManager
import javax.inject.Inject
class SubscriptionManagerCompat @Inject constructor(context: Context, private val permissions: PermissionManager) {
private val subscriptionManager: SubscriptionManager?
get() = field?.takeIf { permissions.hasPhone() }
val activeSubscriptionInfoList: List<SubscriptionInfoCompat>
get() {
return if (Build.VERSION.SDK_INT >= 22) {
subscriptionManager?.activeSubscriptionInfoList?.map { SubscriptionInfoCompat(it) } ?: listOf()
} else listOf()
}
init {
subscriptionManager = if (Build.VERSION.SDK_INT >= 22) SubscriptionManager.from(context) else null
}
fun addOnSubscriptionsChangedListener(listener: OnSubscriptionsChangedListener) {
if (Build.VERSION.SDK_INT >= 22) {
subscriptionManager?.addOnSubscriptionsChangedListener(listener.listener)
}
}
fun removeOnSubscriptionsChangedListener(listener: OnSubscriptionsChangedListener) {
if (Build.VERSION.SDK_INT >= 22) {
subscriptionManager?.removeOnSubscriptionsChangedListener(listener.listener)
}
}
abstract class OnSubscriptionsChangedListener {
val listener: SubscriptionManager.OnSubscriptionsChangedListener? = if (Build.VERSION.SDK_INT >= 22) {
object : SubscriptionManager.OnSubscriptionsChangedListener() {
override fun onSubscriptionsChanged() {
this@OnSubscriptionsChangedListener.onSubscriptionsChanged()
}
}
} else null
abstract fun onSubscriptionsChanged()
}
}
@@ -22,11 +22,11 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.support.v4.app.RemoteInput
import compat.SubscriptionManagerCompat
import dagger.android.AndroidInjection
import interactor.MarkRead
import interactor.SendMessage
import repository.MessageRepository
import util.SubscriptionUtils
import javax.inject.Inject
class RemoteMessagingReceiver : BroadcastReceiver() {
@@ -34,7 +34,7 @@ class RemoteMessagingReceiver : BroadcastReceiver() {
@Inject lateinit var markRead: MarkRead
@Inject lateinit var messageRepo: MessageRepository
@Inject lateinit var sendMessage: SendMessage
@Inject lateinit var subUtils: SubscriptionUtils
@Inject lateinit var subscriptionManager: SubscriptionManagerCompat
override fun onReceive(context: Context, intent: Intent) {
AndroidInjection.inject(this, context)
@@ -47,7 +47,7 @@ class RemoteMessagingReceiver : BroadcastReceiver() {
markRead.execute(threadId)
val lastMessage = messageRepo.getMessages(threadId).lastOrNull()
val subId = subUtils.subscriptions.firstOrNull { it.subscriptionId == lastMessage?.subId }?.subscriptionId ?: -1
val subId = subscriptionManager.activeSubscriptionInfoList.firstOrNull { it.subscriptionId == lastMessage?.subId }?.subscriptionId ?: -1
val addresses = messageRepo.getConversation(threadId)?.recipients?.map { it.address } ?: return
val pendingRepository = goAsync()
@@ -0,0 +1,43 @@
package util
import compat.SubscriptionInfoCompat
import compat.SubscriptionManagerCompat
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
class ActiveSubscriptionObservable(
private val subscriptionManager: SubscriptionManagerCompat
) : Observable<List<SubscriptionInfoCompat>>() {
override fun subscribeActual(observer: Observer<in List<SubscriptionInfoCompat>>) {
observer.onNext(subscriptionManager.activeSubscriptionInfoList)
val listener = Listener(subscriptionManager, observer)
observer.onSubscribe(listener)
subscriptionManager.addOnSubscriptionsChangedListener(listener)
}
internal class Listener(
private val subscriptionManager: SubscriptionManagerCompat,
private val observer: Observer<in List<SubscriptionInfoCompat>>
) : Disposable, SubscriptionManagerCompat.OnSubscriptionsChangedListener() {
private var disposed: Boolean = false
override fun onSubscriptionsChanged() {
if (!isDisposed) {
observer.onNext(subscriptionManager.activeSubscriptionInfoList)
}
}
override fun isDisposed(): Boolean = disposed
override fun dispose() {
disposed = true
subscriptionManager.removeOnSubscriptionsChangedListener(this)
}
}
}
@@ -1,69 +0,0 @@
package util
import android.content.Context
import android.telephony.PhoneNumberUtils
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import manager.PermissionManager
import javax.inject.Inject
class SubscriptionUtilsImpl @Inject constructor(
context: Context,
private val permissions: PermissionManager
) : SubscriptionUtils {
/**
* If we don't have the phone permission, then return a null [SubscriptionManager]
*/
private val subscriptionManager: SubscriptionManager? = SubscriptionManager.from(context)
get() = field?.takeIf { permissions.hasPhone() }
override val subscriptions: List<SubscriptionInfo>
get() = subscriptionManager?.activeSubscriptionInfoList ?: listOf()
override val subscriptionsObservable: Observable<List<SubscriptionInfo>> = ActiveSubscriptionObservable(subscriptionManager)
override fun getSubIdForAddress(address: String): Int {
return subscriptions.firstOrNull { PhoneNumberUtils.compare(it.number, address) }?.subscriptionId ?: -1
}
}
class ActiveSubscriptionObservable(
private val subscriptionManager: SubscriptionManager?
) : Observable<List<SubscriptionInfo>>() {
override fun subscribeActual(observer: Observer<in List<SubscriptionInfo>>) {
observer.onNext(subscriptionManager?.activeSubscriptionInfoList ?: listOf())
val listener = Listener(subscriptionManager, observer)
observer.onSubscribe(listener)
subscriptionManager?.addOnSubscriptionsChangedListener(listener)
}
internal class Listener(
private val subscriptionManager: SubscriptionManager?,
private val observer: Observer<in List<SubscriptionInfo>>
) : Disposable, SubscriptionManager.OnSubscriptionsChangedListener() {
private var disposed: Boolean = false
override fun onSubscriptionsChanged() {
if (!isDisposed) {
observer.onNext(subscriptionManager?.activeSubscriptionInfoList ?: listOf())
}
}
override fun isDisposed(): Boolean = disposed
override fun dispose() {
disposed = true
subscriptionManager?.removeOnSubscriptionsChangedListener(this)
}
}
}