Improved how presence is stored in native contact + fixed issue where write contacts permission was missing + ask for contacts permission in contacts settings

This commit is contained in:
Sylvain Berfini 2020-06-08 15:44:34 +02:00
parent d79c8f09e6
commit c15ecd54ac
5 changed files with 88 additions and 15 deletions

View file

@ -19,6 +19,7 @@
*/
package org.linphone.activities.main.settings.fragments
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -27,11 +28,14 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.activities.main.settings.viewmodels.ContactsSettingsViewModel
import org.linphone.compatibility.Compatibility
import org.linphone.core.tools.Log
import org.linphone.databinding.SettingsContactsFragmentBinding
import org.linphone.utils.PermissionHelper
class ContactsSettingsFragment : Fragment() {
private lateinit var binding: SettingsContactsFragmentBinding
@ -69,5 +73,52 @@ class ContactsSettingsFragment : Fragment() {
}
}
})
viewModel.askWriteContactsPermissionForPresenceStorageEvent.observe(viewLifecycleOwner, Observer {
it.consume {
Log.i("[Contacts Settings] Asking for WRITE_CONTACTS permission to be able to store presence")
requestPermissions(arrayOf(android.Manifest.permission.WRITE_CONTACTS), 1)
}
})
if (!PermissionHelper.required(requireContext()).hasReadContactsPermission()) {
Log.i("[Contacts Settings] Asking for READ_CONTACTS permission")
requestPermissions(arrayOf(android.Manifest.permission.READ_CONTACTS), 0)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
0 -> {
val granted = grantResults[0] == PackageManager.PERMISSION_GRANTED
if (granted) {
Log.i("[Contacts Settings] READ_CONTACTS permission granted")
viewModel.readContactsPermissionGranted.value = true
coreContext.contactsManager.fetchContactsAsync()
} else {
Log.w("[Contacts Settings] READ_CONTACTS permission denied")
}
}
1 -> {
val granted = grantResults[0] == PackageManager.PERMISSION_GRANTED
if (granted) {
Log.i("[Contacts Settings] WRITE_CONTACTS permission granted")
corePreferences.storePresenceInNativeContact = true
if (coreContext.core.isFriendListSubscriptionEnabled) {
Log.i("[Contacts Settings] Updating subscription")
for (list in coreContext.core.friendsLists) {
list.updateSubscriptions()
}
}
} else {
Log.w("[Contacts Settings] WRITE_CONTACTS permission denied")
}
}
}
}
}

View file

@ -22,8 +22,15 @@ package org.linphone.activities.main.settings.viewmodels
import androidx.lifecycle.MutableLiveData
import org.linphone.activities.main.settings.SettingListenerStub
import org.linphone.utils.Event
import org.linphone.utils.PermissionHelper
class ContactsSettingsViewModel : GenericSettingsViewModel() {
val askWriteContactsPermissionForPresenceStorageEvent: MutableLiveData<Event<Boolean>> by lazy {
MutableLiveData<Event<Boolean>>()
}
val readContactsPermissionGranted = MutableLiveData<Boolean>()
val friendListSubscribeListener = object : SettingListenerStub() {
override fun onBoolValueChanged(newValue: Boolean) {
core.enableFriendListSubscription(newValue)
@ -33,7 +40,15 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() {
val nativePresenceListener = object : SettingListenerStub() {
override fun onBoolValueChanged(newValue: Boolean) {
if (newValue) {
if (PermissionHelper.get().hasWriteContactsPermission()) {
prefs.storePresenceInNativeContact = newValue
} else {
askWriteContactsPermissionForPresenceStorageEvent.value = Event(true)
}
} else {
prefs.storePresenceInNativeContact = newValue
}
}
}
val nativePresence = MutableLiveData<Boolean>()
@ -55,6 +70,8 @@ class ContactsSettingsViewModel : GenericSettingsViewModel() {
val launcherShortcutsEvent = MutableLiveData<Event<Boolean>>()
init {
readContactsPermissionGranted.value = PermissionHelper.get().hasReadContactsPermission()
friendListSubscribe.value = core.isFriendListSubscriptionEnabled
nativePresence.value = prefs.storePresenceInNativeContact
showOrganization.value = prefs.displayOrganization

View file

@ -287,7 +287,7 @@ class ContactsManager(private val context: Context) {
listener.onContactUpdated(contact)
}
if (corePreferences.storePresenceInNativeContact) {
if (corePreferences.storePresenceInNativeContact && PermissionHelper.get().hasWriteContactsPermission()) {
if (contact is NativeContact) {
for (phoneNumber in contact.phoneNumbers) {
val sipAddress = contact.getContactForPhoneNumberOrAddress(phoneNumber)

View file

@ -235,10 +235,11 @@ class NativeContactEditor(
sipAddress.currentValue.isEmpty() -> {
// New address to add
addCount++
val address = sipAddress.newValue.value.orEmpty()
if (useLinphoneSyncAccount) {
addAddress(sipAddress.newValue.value.orEmpty())
addAddress(address, address)
} else {
addSipAddress(sipAddress.newValue.value.orEmpty())
addSipAddress(address)
}
}
sipAddress.toRemove.value == true -> {
@ -268,7 +269,7 @@ class NativeContactEditor(
Log.i("[Native Contact Editor] Trying to add presence information to contact as ${if (useLinphoneSyncAccount) "phone number" else "SIP address"}")
if (useLinphoneSyncAccount) {
setPresencePhoneNumber(phoneNumber)
setPresence(sipAddress, phoneNumber)
} else {
setPresenceSipAddress(sipAddress)
}
@ -359,7 +360,7 @@ class NativeContactEditor(
addChanges(delete)
}
private fun addAddress(address: String) {
private fun addAddress(address: String, detail: String) {
val insert = ContentProviderOperation.newInsert(contactUri)
.withValue(ContactsContract.Data.RAW_CONTACT_ID, linphoneRawId)
.withValue(
@ -368,7 +369,7 @@ class NativeContactEditor(
)
.withValue("data1", address) // value
.withValue("data2", AppUtils.getString(R.string.app_name)) // summary
.withValue("data3", address) // detail
.withValue("data3", detail) // detail
.build()
addChanges(insert)
}
@ -422,13 +423,13 @@ class NativeContactEditor(
addChanges(delete)
}
private fun setPresencePhoneNumber(phoneNumber: String) {
private fun setPresence(sipAddress: String, phoneNumber: String) {
val contentResolver = coreContext.context.contentResolver
val cursor = contentResolver.query(
ContactsContract.Data.CONTENT_URI,
arrayOf("data1"),
"${ContactsContract.Data.RAW_CONTACT_ID} = ? AND ${ContactsContract.Data.MIMETYPE} = ? AND data1 = ?",
arrayOf(linphoneRawId, AppUtils.getString(R.string.linphone_address_mime_type), phoneNumber),
"${ContactsContract.Data.RAW_CONTACT_ID} = ? AND ${ContactsContract.Data.MIMETYPE} = ? AND data1 = ? AND data3 = ?",
arrayOf(linphoneRawId, AppUtils.getString(R.string.linphone_address_mime_type), sipAddress, phoneNumber),
null
)
val count = cursor?.count ?: 0
@ -436,7 +437,7 @@ class NativeContactEditor(
if (count == 0) {
Log.i("[Native Contact Editor] No existing presence information found for this phone number, let's add it")
addAddress(phoneNumber)
addAddress(sipAddress, phoneNumber)
} else {
Log.i("[Native Contact Editor] There is already an entry for this, skipping")
}

View file

@ -69,28 +69,32 @@
linphone:title="@{@string/contacts_settings_friendlist_subscribe_title}"
linphone:subtitle="@{@string/contacts_settings_friendlist_subscribe_summary}"
linphone:listener="@{viewModel.friendListSubscribeListener}"
linphone:checked="@={viewModel.friendListSubscribe}"/>
linphone:checked="@={viewModel.friendListSubscribe}"
linphone:enabled="@{viewModel.readContactsPermissionGranted}"/>
<include
layout="@layout/settings_widget_switch"
linphone:title="@{@string/contacts_settings_native_presence_title}"
linphone:subtitle="@{@string/contacts_settings_native_presence_summary}"
linphone:listener="@{viewModel.nativePresenceListener}"
linphone:checked="@={viewModel.nativePresence}"/>
linphone:checked="@={viewModel.nativePresence}"
linphone:enabled="@{viewModel.readContactsPermissionGranted &amp;&amp; viewModel.friendListSubscribe}"/>
<include
layout="@layout/settings_widget_switch"
linphone:title="@{@string/contacts_settings_show_organization_title}"
linphone:subtitle="@{@string/contacts_settings_show_organization_summary}"
linphone:listener="@{viewModel.showOrganizationListener}"
linphone:checked="@={viewModel.showOrganization}"/>
linphone:checked="@={viewModel.showOrganization}"
linphone:enabled="@{viewModel.readContactsPermissionGranted}"/>
<include
layout="@layout/settings_widget_switch"
linphone:title="@{@string/contacts_settings_launcher_shortcuts_title}"
linphone:subtitle="@{@string/contacts_settings_launcher_shortcuts_summary}"
linphone:listener="@{viewModel.launcherShortcutsListener}"
linphone:checked="@={viewModel.launcherShortcuts}"/>
linphone:checked="@={viewModel.launcherShortcuts}"
linphone:enabled="@{viewModel.readContactsPermissionGranted}"/>
</LinearLayout>