Added top bar alert if post notifications permission isn't granted + improved connexion error toast + improved network unreachable alert

This commit is contained in:
Sylvain Berfini 2024-06-24 11:10:19 +02:00
parent 8f34c3ea5c
commit 08052d64fd
4 changed files with 103 additions and 7 deletions

View file

@ -34,6 +34,7 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import androidx.activity.SystemBarStyle import androidx.activity.SystemBarStyle
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.UiThread import androidx.annotation.UiThread
import androidx.car.app.connection.CarConnection import androidx.car.app.connection.CarConnection
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
@ -107,6 +108,17 @@ class MainActivity : GenericActivity() {
} }
} }
private val postNotificationsPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
Log.i("$TAG POST_NOTIFICATIONS permission has been granted")
viewModel.updatePostNotificationsPermission()
} else {
Log.w("$TAG POST_NOTIFICATIONS permission has been denied!")
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
// Must be done before the setContentView // Must be done before the setContentView
installSplashScreen() installSplashScreen()
@ -172,6 +184,12 @@ class MainActivity : GenericActivity() {
} }
} }
viewModel.askPostNotificationsPermissionEvent.observe(this) {
it.consume {
postNotificationsPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
viewModel.defaultAccountRegistrationErrorEvent.observe(this) { viewModel.defaultAccountRegistrationErrorEvent.observe(this) {
it.consume { error -> it.consume { error ->
val tag = "DEFAULT_ACCOUNT_REGISTRATION_ERROR" val tag = "DEFAULT_ACCOUNT_REGISTRATION_ERROR"
@ -325,6 +343,7 @@ class MainActivity : GenericActivity() {
super.onResume() super.onResume()
viewModel.checkForNewAccount() viewModel.checkForNewAccount()
viewModel.updateNetworkReachability()
} }
override fun onNewIntent(intent: Intent) { override fun onNewIntent(intent: Intent) {

View file

@ -19,8 +19,13 @@
*/ */
package org.linphone.ui.main.viewmodel package org.linphone.ui.main.viewmodel
import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.annotation.UiThread import androidx.annotation.UiThread
import androidx.annotation.WorkerThread import androidx.annotation.WorkerThread
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
@ -55,6 +60,7 @@ class MainViewModel @UiThread constructor() : ViewModel() {
const val NONE = 0 const val NONE = 0
const val NON_DEFAULT_ACCOUNT_NOTIFICATIONS = 5 const val NON_DEFAULT_ACCOUNT_NOTIFICATIONS = 5
const val NON_DEFAULT_ACCOUNT_NOT_CONNECTED = 10 const val NON_DEFAULT_ACCOUNT_NOT_CONNECTED = 10
const val SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED = 17
const val NETWORK_NOT_REACHABLE = 19 const val NETWORK_NOT_REACHABLE = 19
const val SINGLE_CALL = 20 const val SINGLE_CALL = 20
const val MULTIPLE_CALLS = 21 const val MULTIPLE_CALLS = 21
@ -84,6 +90,10 @@ class MainViewModel @UiThread constructor() : ViewModel() {
MutableLiveData<Event<Boolean>>() MutableLiveData<Event<Boolean>>()
} }
val askPostNotificationsPermissionEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val showNewAccountToastEvent: MutableLiveData<Event<Boolean>> by lazy { val showNewAccountToastEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>() MutableLiveData<Event<Boolean>>()
} }
@ -165,13 +175,7 @@ class MainViewModel @UiThread constructor() : ViewModel() {
@WorkerThread @WorkerThread
override fun onNetworkReachable(core: Core, reachable: Boolean) { override fun onNetworkReachable(core: Core, reachable: Boolean) {
Log.i("$TAG Network is ${if (reachable) "reachable" else "not reachable"}") checkNetworkReachability()
if (!reachable) {
val label = AppUtils.getString(R.string.network_not_reachable)
addAlert(NETWORK_NOT_REACHABLE, label)
} else {
removeAlert(NETWORK_NOT_REACHABLE)
}
} }
@WorkerThread @WorkerThread
@ -216,6 +220,15 @@ class MainViewModel @UiThread constructor() : ViewModel() {
} }
} }
} }
RegistrationState.Progress, RegistrationState.Refreshing -> {
if (defaultAccountRegistrationFailed) {
Log.i(
"$TAG Default account is registering, removing registration failed toast for now"
)
defaultAccountRegistrationFailed = false
defaultAccountRegistrationErrorEvent.postValue(Event(false))
}
}
else -> {} else -> {}
} }
} }
@ -267,6 +280,10 @@ class MainViewModel @UiThread constructor() : ViewModel() {
addAlert(NETWORK_NOT_REACHABLE, label) addAlert(NETWORK_NOT_REACHABLE, label)
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
checkPostNotificationsPermission()
}
if (core.callsNb > 0) { if (core.callsNb > 0) {
updateCallAlert() updateCallAlert()
} }
@ -300,6 +317,22 @@ class MainViewModel @UiThread constructor() : ViewModel() {
} }
} }
@UiThread
fun updateNetworkReachability() {
coreContext.postOnCoreThread {
checkNetworkReachability()
}
}
@UiThread
fun updatePostNotificationsPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
coreContext.postOnCoreThread {
checkPostNotificationsPermission()
}
}
}
@UiThread @UiThread
fun checkForNewAccount() { fun checkForNewAccount() {
coreContext.postOnCoreThread { core -> coreContext.postOnCoreThread { core ->
@ -327,6 +360,8 @@ class MainViewModel @UiThread constructor() : ViewModel() {
fun onTopBarClicked() { fun onTopBarClicked() {
if (atLeastOneCall.value == true) { if (atLeastOneCall.value == true) {
goBackToCallEvent.value = Event(true) goBackToCallEvent.value = Event(true)
} else if (!isPostNotificationsPermissionGranted()) {
askPostNotificationsPermissionEvent.value = Event(true)
} else { } else {
openDrawerEvent.value = Event(true) openDrawerEvent.value = Event(true)
} }
@ -458,6 +493,9 @@ class MainViewModel @UiThread constructor() : ViewModel() {
NETWORK_NOT_REACHABLE -> { NETWORK_NOT_REACHABLE -> {
alertIcon.postValue(R.drawable.wifi_slash) alertIcon.postValue(R.drawable.wifi_slash)
} }
SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED -> {
alertIcon.postValue(R.drawable.bell_simple_slash)
}
SINGLE_CALL, MULTIPLE_CALLS -> { SINGLE_CALL, MULTIPLE_CALLS -> {
alertIcon.postValue(R.drawable.phone) alertIcon.postValue(R.drawable.phone)
} }
@ -489,4 +527,41 @@ class MainViewModel @UiThread constructor() : ViewModel() {
Log.i("$TAG Trying to fetch & import native contacts") Log.i("$TAG Trying to fetch & import native contacts")
startLoadingContactsEvent.postValue(Event(true)) startLoadingContactsEvent.postValue(Event(true))
} }
@WorkerThread
private fun checkNetworkReachability() {
val reachable = coreContext.core.isNetworkReachable
Log.i("$TAG Network is ${if (reachable) "reachable" else "not reachable"}")
if (!reachable) {
val label = AppUtils.getString(R.string.network_not_reachable)
addAlert(NETWORK_NOT_REACHABLE, label)
} else {
removeAlert(NETWORK_NOT_REACHABLE)
}
}
private fun isPostNotificationsPermissionGranted(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
ContextCompat.checkSelfPermission(
coreContext.context,
Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED
} else {
true
}
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@WorkerThread
private fun checkPostNotificationsPermission() {
if (!isPostNotificationsPermissionGranted()) {
Log.w("$TAG POST_NOTIFICATIONS seems to be not granted!")
val label = AppUtils.getString(R.string.post_notifications_permission_not_granted)
coreContext.postOnCoreThread {
addAlert(SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED, label)
}
} else {
removeAlert(SEND_NOTIFICATIONS_PERMISSION_NOT_GRANTED)
}
}
} }

View file

@ -698,6 +698,7 @@
<string name="generic_address_picker_conversations_list_title">Conversations</string> <string name="generic_address_picker_conversations_list_title">Conversations</string>
<string name="generic_address_picker_contacts_list_title">Contacts</string> <string name="generic_address_picker_contacts_list_title">Contacts</string>
<string name="generic_address_picker_suggestions_list_title">Suggestions</string> <string name="generic_address_picker_suggestions_list_title">Suggestions</string>
<string name="post_notifications_permission_not_granted">La permission de poster des notifications n\'est pas donnée !</string>
<!-- Keep <u></u> in the following strings translations! --> <!-- Keep <u></u> in the following strings translations! -->
<string name="welcome_carousel_skip"><u>Passer</u></string> <string name="welcome_carousel_skip"><u>Passer</u></string>

View file

@ -735,6 +735,7 @@
<string name="generic_address_picker_conversations_list_title">Conversations</string> <string name="generic_address_picker_conversations_list_title">Conversations</string>
<string name="generic_address_picker_contacts_list_title">Contacts</string> <string name="generic_address_picker_contacts_list_title">Contacts</string>
<string name="generic_address_picker_suggestions_list_title">Suggestions</string> <string name="generic_address_picker_suggestions_list_title">Suggestions</string>
<string name="post_notifications_permission_not_granted">Post notifications permission not granted!</string>
<!-- Keep <u></u> in the following strings translations! --> <!-- Keep <u></u> in the following strings translations! -->
<string name="welcome_carousel_skip"><u>Skip</u></string> <string name="welcome_carousel_skip"><u>Skip</u></string>