Improved READ_PHONE_STATE / READ_PHONE_NUMBERS permissions usage
This commit is contained in:
parent
c1dafcb9b9
commit
4337dd5da8
14 changed files with 125 additions and 27 deletions
|
@ -20,13 +20,13 @@
|
||||||
|
|
||||||
package org.linphone.activities.assistant.fragments
|
package org.linphone.activities.assistant.fragments
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import androidx.databinding.ViewDataBinding
|
import androidx.databinding.ViewDataBinding
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.linphone.R
|
import org.linphone.R
|
||||||
import org.linphone.activities.GenericFragment
|
import org.linphone.activities.GenericFragment
|
||||||
import org.linphone.activities.assistant.viewmodels.AbstractPhoneViewModel
|
import org.linphone.activities.assistant.viewmodels.AbstractPhoneViewModel
|
||||||
|
import org.linphone.compatibility.Compatibility
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.PermissionHelper
|
import org.linphone.utils.PermissionHelper
|
||||||
import org.linphone.utils.PhoneNumberUtils
|
import org.linphone.utils.PhoneNumberUtils
|
||||||
|
@ -41,19 +41,19 @@ abstract class AbstractPhoneFragment<T : ViewDataBinding> : GenericFragment<T>()
|
||||||
) {
|
) {
|
||||||
if (requestCode == 0) {
|
if (requestCode == 0) {
|
||||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
Log.i("[Assistant] READ_PHONE_STATE permission granted")
|
Log.i("[Assistant] READ_PHONE_STATE/READ_PHONE_NUMBERS permission granted")
|
||||||
updateFromDeviceInfo()
|
updateFromDeviceInfo()
|
||||||
} else {
|
} else {
|
||||||
Log.w("[Assistant] READ_PHONE_STATE permission denied")
|
Log.w("[Assistant] READ_PHONE_STATE/READ_PHONE_NUMBERS permission denied")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun checkPermission() {
|
protected fun checkPermission() {
|
||||||
if (!resources.getBoolean(R.bool.isTablet)) {
|
if (!resources.getBoolean(R.bool.isTablet)) {
|
||||||
if (!PermissionHelper.get().hasReadPhoneState()) {
|
if (!PermissionHelper.get().hasReadPhoneStateOrPhoneNumbersPermission()) {
|
||||||
Log.i("[Assistant] Asking for READ_PHONE_STATE permission")
|
Log.i("[Assistant] Asking for READ_PHONE_STATE/READ_PHONE_NUMBERS permission")
|
||||||
requestPermissions(arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
|
Compatibility.requestReadPhoneStateOrNumbersPermission(requireActivity(), 0)
|
||||||
} else {
|
} else {
|
||||||
updateFromDeviceInfo()
|
updateFromDeviceInfo()
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ class ControlsFragment : GenericFragment<CallControlsFragmentBinding>() {
|
||||||
viewLifecycleOwner,
|
viewLifecycleOwner,
|
||||||
{
|
{
|
||||||
it.consume {
|
it.consume {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
Log.i("[Controls Fragment] Asking for WRITE_EXTERNAL_STORAGE permission")
|
Log.i("[Controls Fragment] Asking for WRITE_EXTERNAL_STORAGE permission")
|
||||||
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ class CallsViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun takeScreenshot() {
|
fun takeScreenshot() {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
askWriteExternalStoragePermissionEvent.value = Event(true)
|
askWriteExternalStoragePermissionEvent.value = Event(true)
|
||||||
} else {
|
} else {
|
||||||
currentCallViewModel.value?.takeScreenshot()
|
currentCallViewModel.value?.takeScreenshot()
|
||||||
|
|
|
@ -402,7 +402,7 @@ class DetailChatRoomFragment : MasterFragment<ChatRoomDetailFragmentBinding, Cha
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.setAttachFileClickListener {
|
binding.setAttachFileClickListener {
|
||||||
if (PermissionHelper.get().hasReadExternalStorage() && PermissionHelper.get().hasCameraPermission()) {
|
if (PermissionHelper.get().hasReadExternalStoragePermission() && PermissionHelper.get().hasCameraPermission()) {
|
||||||
pickFile()
|
pickFile()
|
||||||
} else {
|
} else {
|
||||||
Log.i("[Chat Room] Asking for READ_EXTERNAL_STORAGE and CAMERA permissions")
|
Log.i("[Chat Room] Asking for READ_EXTERNAL_STORAGE and CAMERA permissions")
|
||||||
|
|
|
@ -70,7 +70,7 @@ class ChatMessagesListViewModel(private val chatRoom: ChatRoom) : ViewModel() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version.sdkStrictlyBelow(Version.API29_ANDROID_10) && !PermissionHelper.get().hasWriteExternalStorage()) {
|
if (Version.sdkStrictlyBelow(Version.API29_ANDROID_10) && !PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
for (content in chatMessage.contents) {
|
for (content in chatMessage.contents) {
|
||||||
if (content.isFileTransfer) {
|
if (content.isFileTransfer) {
|
||||||
Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet")
|
Log.i("[Chat Messages] Android < 10 detected and WRITE_EXTERNAL_STORAGE permission isn't granted yet")
|
||||||
|
|
|
@ -19,11 +19,14 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.activities.main.dialer.fragments
|
package org.linphone.activities.main.dialer.fragments
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.annotation.TargetApi
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -44,9 +47,11 @@ import org.linphone.activities.navigateToConfigFileViewer
|
||||||
import org.linphone.activities.navigateToContacts
|
import org.linphone.activities.navigateToContacts
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.databinding.DialerFragmentBinding
|
import org.linphone.databinding.DialerFragmentBinding
|
||||||
|
import org.linphone.mediastream.Version
|
||||||
import org.linphone.utils.AppUtils
|
import org.linphone.utils.AppUtils
|
||||||
import org.linphone.utils.DialogUtils
|
import org.linphone.utils.DialogUtils
|
||||||
import org.linphone.utils.Event
|
import org.linphone.utils.Event
|
||||||
|
import org.linphone.utils.PermissionHelper
|
||||||
|
|
||||||
class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
private lateinit var viewModel: DialerViewModel
|
private lateinit var viewModel: DialerViewModel
|
||||||
|
@ -164,6 +169,10 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
viewModel.transferVisibility.value = sharedViewModel.pendingCallTransfer
|
viewModel.transferVisibility.value = sharedViewModel.pendingCallTransfer
|
||||||
|
|
||||||
checkForUpdate()
|
checkForUpdate()
|
||||||
|
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API23_MARSHMALLOW_60)) {
|
||||||
|
checkPermissions()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
@ -185,6 +194,28 @@ class DialerFragment : SecureFragment<DialerFragmentBinding>() {
|
||||||
viewModel.enteredUri.value = sharedViewModel.dialerUri
|
viewModel.enteredUri.value = sharedViewModel.dialerUri
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<out String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
if (requestCode == 0) {
|
||||||
|
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
Log.i("[Dialer] READ_PHONE_STATE permission has been granted")
|
||||||
|
coreContext.initPhoneStateListener()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Version.API23_MARSHMALLOW_60)
|
||||||
|
private fun checkPermissions() {
|
||||||
|
if (!PermissionHelper.get().hasReadPhoneStatePermission()) {
|
||||||
|
Log.i("[Dialer] Asking for READ_PHONE_STATE permission")
|
||||||
|
requestPermissions(arrayOf(Manifest.permission.READ_PHONE_STATE), 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun displayDebugPopup() {
|
private fun displayDebugPopup() {
|
||||||
val alertDialog = MaterialAlertDialogBuilder(requireContext())
|
val alertDialog = MaterialAlertDialogBuilder(requireContext())
|
||||||
alertDialog.setTitle(getString(R.string.debug_popup_title))
|
alertDialog.setTitle(getString(R.string.debug_popup_title))
|
||||||
|
|
|
@ -69,7 +69,7 @@ class Api21Compatibility {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun addImageToMediaStore(context: Context, content: Content): Boolean {
|
suspend fun addImageToMediaStore(context: Context, content: Content): Boolean {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
Log.e("[Media Store] Write external storage permission denied")
|
Log.e("[Media Store] Write external storage permission denied")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class Api21Compatibility {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun addVideoToMediaStore(context: Context, content: Content): Boolean {
|
suspend fun addVideoToMediaStore(context: Context, content: Content): Boolean {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
Log.e("[Media Store] Write external storage permission denied")
|
Log.e("[Media Store] Write external storage permission denied")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ class Api21Compatibility {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun addAudioToMediaStore(context: Context, content: Content): Boolean {
|
suspend fun addAudioToMediaStore(context: Context, content: Content): Boolean {
|
||||||
if (!PermissionHelper.get().hasWriteExternalStorage()) {
|
if (!PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
Log.e("[Media Store] Write external storage permission denied")
|
Log.e("[Media Store] Write external storage permission denied")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.compatibility
|
package org.linphone.compatibility
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Activity
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.ContentValues
|
import android.content.ContentValues
|
||||||
|
@ -45,6 +47,20 @@ import org.linphone.utils.LinphoneUtils
|
||||||
@TargetApi(29)
|
@TargetApi(29)
|
||||||
class Api29Compatibility {
|
class Api29Compatibility {
|
||||||
companion object {
|
companion object {
|
||||||
|
fun hasReadPhoneStatePermission(context: Context): Boolean {
|
||||||
|
val granted = Compatibility.hasPermission(context, Manifest.permission.READ_PHONE_STATE)
|
||||||
|
if (granted) {
|
||||||
|
Log.d("[Permission Helper] Permission READ_PHONE_STATE is granted")
|
||||||
|
} else {
|
||||||
|
Log.w("[Permission Helper] Permission READ_PHONE_STATE is denied")
|
||||||
|
}
|
||||||
|
return granted
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestReadPhoneStatePermission(activity: Activity, code: Int) {
|
||||||
|
activity.requestPermissions(arrayOf(Manifest.permission.READ_PHONE_STATE), code)
|
||||||
|
}
|
||||||
|
|
||||||
fun createMessageChannel(
|
fun createMessageChannel(
|
||||||
context: Context,
|
context: Context,
|
||||||
notificationManager: NotificationManagerCompat
|
notificationManager: NotificationManagerCompat
|
||||||
|
|
|
@ -19,15 +19,32 @@
|
||||||
*/
|
*/
|
||||||
package org.linphone.compatibility
|
package org.linphone.compatibility
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ShortcutManager
|
import android.content.pm.ShortcutManager
|
||||||
import org.linphone.core.ChatRoom
|
import org.linphone.core.ChatRoom
|
||||||
|
import org.linphone.core.tools.Log
|
||||||
import org.linphone.utils.LinphoneUtils
|
import org.linphone.utils.LinphoneUtils
|
||||||
|
|
||||||
@TargetApi(30)
|
@TargetApi(30)
|
||||||
class Api30Compatibility {
|
class Api30Compatibility {
|
||||||
companion object {
|
companion object {
|
||||||
|
fun hasReadPhoneNumbersPermission(context: Context): Boolean {
|
||||||
|
val granted = Compatibility.hasPermission(context, Manifest.permission.READ_PHONE_NUMBERS)
|
||||||
|
if (granted) {
|
||||||
|
Log.d("[Permission Helper] Permission READ_PHONE_NUMBERS is granted")
|
||||||
|
} else {
|
||||||
|
Log.w("[Permission Helper] Permission READ_PHONE_NUMBERS is denied")
|
||||||
|
}
|
||||||
|
return granted
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestReadPhoneNumbersPermission(activity: Activity, code: Int) {
|
||||||
|
activity.requestPermissions(arrayOf(Manifest.permission.READ_PHONE_NUMBERS), code)
|
||||||
|
}
|
||||||
|
|
||||||
fun removeChatRoomShortcut(context: Context, chatRoom: ChatRoom) {
|
fun removeChatRoomShortcut(context: Context, chatRoom: ChatRoom) {
|
||||||
val peerAddress = chatRoom.peerAddress.asStringUriOnly()
|
val peerAddress = chatRoom.peerAddress.asStringUriOnly()
|
||||||
val localAddress = chatRoom.localAddress.asStringUriOnly()
|
val localAddress = chatRoom.localAddress.asStringUriOnly()
|
||||||
|
|
|
@ -44,6 +44,24 @@ class Compatibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See https://developer.android.com/about/versions/11/privacy/permissions#phone-numbers
|
||||||
|
fun hasReadPhoneStateOrNumbersPermission(context: Context): Boolean {
|
||||||
|
return if (Version.sdkAboveOrEqual(Version.API30_ANDROID_11)) {
|
||||||
|
Api30Compatibility.hasReadPhoneNumbersPermission(context)
|
||||||
|
} else {
|
||||||
|
Api29Compatibility.hasReadPhoneStatePermission(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See https://developer.android.com/about/versions/11/privacy/permissions#phone-numbers
|
||||||
|
fun requestReadPhoneStateOrNumbersPermission(activity: Activity, code: Int) {
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API30_ANDROID_11)) {
|
||||||
|
Api30Compatibility.requestReadPhoneNumbersPermission(activity, code)
|
||||||
|
} else {
|
||||||
|
Api29Compatibility.requestReadPhoneStatePermission(activity, code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getDeviceName(context: Context): String {
|
fun getDeviceName(context: Context): String {
|
||||||
return when (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
|
return when (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
|
||||||
true -> Api25Compatibility.getDeviceName(context)
|
true -> Api25Compatibility.getDeviceName(context)
|
||||||
|
|
|
@ -313,13 +313,7 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
|
|
||||||
configureCore()
|
configureCore()
|
||||||
|
|
||||||
try {
|
initPhoneStateListener()
|
||||||
phoneStateListener =
|
|
||||||
Compatibility.createPhoneListener(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
|
|
||||||
} catch (exception: SecurityException) {
|
|
||||||
val hasReadPhoneStatePermission = PermissionHelper.get().hasReadPhoneState()
|
|
||||||
Log.e("[Context] Failed to create phone state listener: $exception, READ_PHONE_STATE permission status is $hasReadPhoneStatePermission")
|
|
||||||
}
|
|
||||||
|
|
||||||
EmojiCompat.init(BundledEmojiCompatConfig(context))
|
EmojiCompat.init(BundledEmojiCompatConfig(context))
|
||||||
collator.strength = Collator.NO_DECOMPOSITION
|
collator.strength = Collator.NO_DECOMPOSITION
|
||||||
|
@ -410,6 +404,21 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
|
|
||||||
/* Call related functions */
|
/* Call related functions */
|
||||||
|
|
||||||
|
fun initPhoneStateListener() {
|
||||||
|
if (PermissionHelper.get().hasReadPhoneStatePermission()) {
|
||||||
|
try {
|
||||||
|
phoneStateListener =
|
||||||
|
Compatibility.createPhoneListener(context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager)
|
||||||
|
} catch (exception: SecurityException) {
|
||||||
|
val hasReadPhoneStatePermission =
|
||||||
|
PermissionHelper.get().hasReadPhoneStateOrPhoneNumbersPermission()
|
||||||
|
Log.e("[Context] Failed to create phone state listener: $exception, READ_PHONE_STATE permission status is $hasReadPhoneStatePermission")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w("[Context] Can't create phone state listener, READ_PHONE_STATE permission isn't granted")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun answerCallVideoUpdateRequest(call: Call, accept: Boolean) {
|
fun answerCallVideoUpdateRequest(call: Call, accept: Boolean) {
|
||||||
val params = core.createCallParams(call)
|
val params = core.createCallParams(call)
|
||||||
|
|
||||||
|
@ -655,7 +664,7 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10) || PermissionHelper.get().hasWriteExternalStorage()) {
|
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10) || PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
for (content in message.contents) {
|
for (content in message.contents) {
|
||||||
if (content.isFile && content.filePath != null && content.userData == null) {
|
if (content.isFile && content.filePath != null && content.userData == null) {
|
||||||
addContentToMediaStore(content)
|
addContentToMediaStore(content)
|
||||||
|
@ -676,7 +685,7 @@ class CoreContext(val context: Context, coreConfig: Config) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10) || PermissionHelper.get().hasWriteExternalStorage()) {
|
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10) || PermissionHelper.get().hasWriteExternalStoragePermission()) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
when (content.type) {
|
when (content.type) {
|
||||||
"image" -> {
|
"image" -> {
|
||||||
|
|
|
@ -81,7 +81,7 @@ class TelecomHelper private constructor(context: Context) {
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
fun findExistingAccount(context: Context): PhoneAccount? {
|
fun findExistingAccount(context: Context): PhoneAccount? {
|
||||||
if (!PermissionHelper.exists()) PermissionHelper.create(context)
|
if (!PermissionHelper.exists()) PermissionHelper.create(context)
|
||||||
if (PermissionHelper.get().hasReadPhoneState()) {
|
if (PermissionHelper.get().hasReadPhoneStateOrPhoneNumbersPermission()) {
|
||||||
var account: PhoneAccount? = null
|
var account: PhoneAccount? = null
|
||||||
val phoneAccountHandleList: List<PhoneAccountHandle> =
|
val phoneAccountHandleList: List<PhoneAccountHandle> =
|
||||||
telecomManager.selfManagedPhoneAccounts
|
telecomManager.selfManagedPhoneAccounts
|
||||||
|
|
|
@ -21,6 +21,8 @@ package org.linphone.utils
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import org.linphone.compatibility.Compatibility
|
import org.linphone.compatibility.Compatibility
|
||||||
import org.linphone.core.tools.Log
|
import org.linphone.core.tools.Log
|
||||||
|
|
||||||
|
@ -50,15 +52,19 @@ class PermissionHelper private constructor(private val context: Context) {
|
||||||
return hasPermission(Manifest.permission.WRITE_CONTACTS)
|
return hasPermission(Manifest.permission.WRITE_CONTACTS)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasReadPhoneState(): Boolean {
|
fun hasReadPhoneStatePermission(): Boolean {
|
||||||
return hasPermission(Manifest.permission.READ_PHONE_STATE)
|
return hasPermission(Manifest.permission.READ_PHONE_STATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasReadExternalStorage(): Boolean {
|
fun hasReadPhoneStateOrPhoneNumbersPermission(): Boolean {
|
||||||
|
return Compatibility.hasReadPhoneStateOrNumbersPermission(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun hasReadExternalStoragePermission(): Boolean {
|
||||||
return hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
|
return hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasWriteExternalStorage(): Boolean {
|
fun hasWriteExternalStoragePermission(): Boolean {
|
||||||
return hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
return hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +76,7 @@ class PermissionHelper private constructor(private val context: Context) {
|
||||||
return hasPermission(Manifest.permission.RECORD_AUDIO)
|
return hasPermission(Manifest.permission.RECORD_AUDIO)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.O)
|
||||||
fun hasTelecomManagerPermissions(): Boolean {
|
fun hasTelecomManagerPermissions(): Boolean {
|
||||||
return hasPermission(Manifest.permission.READ_PHONE_NUMBERS) &&
|
return hasPermission(Manifest.permission.READ_PHONE_NUMBERS) &&
|
||||||
hasPermission(Manifest.permission.MANAGE_OWN_CALLS)
|
hasPermission(Manifest.permission.MANAGE_OWN_CALLS)
|
||||||
|
|
|
@ -41,7 +41,7 @@ class PhoneNumberUtils {
|
||||||
|
|
||||||
@SuppressLint("MissingPermission", "HardwareIds")
|
@SuppressLint("MissingPermission", "HardwareIds")
|
||||||
fun getDevicePhoneNumber(context: Context): String? {
|
fun getDevicePhoneNumber(context: Context): String? {
|
||||||
if (PermissionHelper.get().hasReadPhoneState()) {
|
if (PermissionHelper.get().hasReadPhoneStateOrPhoneNumbersPermission()) {
|
||||||
try {
|
try {
|
||||||
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
||||||
return tm.line1Number
|
return tm.line1Number
|
||||||
|
|
Loading…
Reference in a new issue