From abfc402f27595a0b479b539f7f7d3500e03c7515 Mon Sep 17 00:00:00 2001 From: javavirys Date: Mon, 17 Oct 2022 12:28:39 +0300 Subject: [PATCH] ail-7 Add logic for getting SIM Card information --- .idea/deploymentTargetDropDown.xml | 17 +++++ AndroidInfoLib/src/main/AndroidManifest.xml | 1 - .../androidinfo/lib/DeviceInformation.kt | 11 ++- .../lib/DeviceInformationFactory.kt | 15 +++- .../sim/GetSIMCardInformationCommand.kt | 50 +++++++++++++ .../lib/entity/SIMCardInformation.kt | 10 ++- .../exception/PermissionDeniedException.kt | 3 + sample/build.gradle | 1 + sample/src/main/AndroidManifest.xml | 4 ++ .../sample/ui/main/MainFragment.kt | 70 ++++++++++++++++++- .../sample/ui/main/MainViewModel.kt | 15 ++-- 11 files changed, 187 insertions(+), 10 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/command/sim/GetSIMCardInformationCommand.kt create mode 100644 AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/exception/PermissionDeniedException.kt diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..0cce9f1 --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/AndroidInfoLib/src/main/AndroidManifest.xml b/AndroidInfoLib/src/main/AndroidManifest.xml index 44008a4..69fc412 100644 --- a/AndroidInfoLib/src/main/AndroidManifest.xml +++ b/AndroidInfoLib/src/main/AndroidManifest.xml @@ -1,4 +1,3 @@ - \ No newline at end of file diff --git a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformation.kt b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformation.kt index d05530b..ee76b44 100644 --- a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformation.kt +++ b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformation.kt @@ -1,6 +1,8 @@ package com.udfsoft.androidinfo.lib +import android.Manifest import android.content.Context +import androidx.annotation.RequiresPermission import androidx.annotation.WorkerThread import com.udfsoft.androidinfo.lib.entity.* @@ -11,7 +13,14 @@ interface DeviceInformation { fun getDesignInformation(): DesignInformation - fun getSIMCardInformation(): SIMCardInformation + @RequiresPermission( + allOf = [ + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_SMS, + "android.permission.READ_PHONE_NUMBERS" + ] + ) + fun getSIMCardInformation(context: Context): SIMCardInformation fun getNetworkInformation(): NetworkInformation diff --git a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformationFactory.kt b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformationFactory.kt index 94b7d8b..486e8af 100644 --- a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformationFactory.kt +++ b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/DeviceInformationFactory.kt @@ -1,11 +1,14 @@ package com.udfsoft.androidinfo.lib +import android.Manifest import android.content.Context import android.os.Build +import androidx.annotation.RequiresPermission import androidx.annotation.WorkerThread import com.udfsoft.androidinfo.lib.command.GetOSInformationCommand import com.udfsoft.androidinfo.lib.command.GetRAMInformationCommand import com.udfsoft.androidinfo.lib.command.cpu.GetCpuInformationCommand +import com.udfsoft.androidinfo.lib.command.sim.GetSIMCardInformationCommand import com.udfsoft.androidinfo.lib.entity.* @WorkerThread @@ -19,8 +22,16 @@ object DeviceInformationFactory : DeviceInformation { TODO("Not yet implemented") } - override fun getSIMCardInformation(): SIMCardInformation { - TODO("Not yet implemented") + @RequiresPermission( + allOf = [ + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_SMS, + "android.permission.READ_PHONE_NUMBERS" + ] + ) + override fun getSIMCardInformation(context: Context): SIMCardInformation { + val getSIMCardInformationCommand = GetSIMCardInformationCommand(context) + return getSIMCardInformationCommand(Unit) } override fun getNetworkInformation(): NetworkInformation { diff --git a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/command/sim/GetSIMCardInformationCommand.kt b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/command/sim/GetSIMCardInformationCommand.kt new file mode 100644 index 0000000..4a969e6 --- /dev/null +++ b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/command/sim/GetSIMCardInformationCommand.kt @@ -0,0 +1,50 @@ +package com.udfsoft.androidinfo.lib.command.sim + +import android.Manifest +import android.content.Context +import android.os.Build +import android.telephony.TelephonyManager +import androidx.annotation.RequiresPermission +import com.udfsoft.androidinfo.lib.command.CommandInterface +import com.udfsoft.androidinfo.lib.entity.SIMCardInformation + +class GetSIMCardInformationCommand( + private val context: Context +) : CommandInterface { + + @RequiresPermission( + allOf = [Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_SMS, "android.permission.READ_PHONE_NUMBERS"] + ) + override fun invoke(param: Unit): SIMCardInformation { + val telephonyService = + context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager + + val callState = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + telephonyService.callStateForSubscription + } else { + telephonyService.callState + } + + val isMultiSimSupported = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + telephonyService.isMultiSimSupported + } else { + 1 + } + + val deviceSoftwareVersion: String? = telephonyService.deviceSoftwareVersion + val mobileNumber: String? = telephonyService.line1Number + val simOperatorName: String? = telephonyService.simOperatorName + val simState = telephonyService.simState + val simCountryIso = telephonyService.simCountryIso + + return SIMCardInformation( + deviceSoftwareVersion, + mobileNumber, + simOperatorName, + callState, + simState, + simCountryIso, + isMultiSimSupported + ) + } +} \ No newline at end of file diff --git a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/entity/SIMCardInformation.kt b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/entity/SIMCardInformation.kt index f7b5a72..e7b259b 100644 --- a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/entity/SIMCardInformation.kt +++ b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/entity/SIMCardInformation.kt @@ -1,3 +1,11 @@ package com.udfsoft.androidinfo.lib.entity -class SIMCardInformation +data class SIMCardInformation( + val deviceSoftwareVersion: String?, + val mobileNumber: String?, + val simOperatorName: String?, + val callState: Int, + val simState: Int, + val simCountryIso: String, + val isMultiSimSupported: Int +) diff --git a/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/exception/PermissionDeniedException.kt b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/exception/PermissionDeniedException.kt new file mode 100644 index 0000000..7749714 --- /dev/null +++ b/AndroidInfoLib/src/main/java/com/udfsoft/androidinfo/lib/exception/PermissionDeniedException.kt @@ -0,0 +1,3 @@ +package com.udfsoft.androidinfo.lib.exception + +class PermissionDeniedException : RuntimeException() diff --git a/sample/build.gradle b/sample/build.gradle index 575c7b9..25c5d39 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation 'androidx.lifecycle:lifecycle-livedata:2.5.1' implementation "androidx.core:core-ktx:1.9.0" + implementation "androidx.activity:activity-ktx:1.6.0" implementation "androidx.fragment:fragment-ktx:1.5.3" // Widgets diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index c84b730..4f25f42 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -2,6 +2,10 @@ + + + + () + private val requestPermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { + val grantedPermissions = it.values.filter { isGranted -> isGranted }.size + val isGranted = grantedPermissions == 3 + if (isGranted) { + loadInformation() + } else { + Toast.makeText(requireContext(), "Permissions denied!", Toast.LENGTH_SHORT).show() + } + } + + private fun loadInformation() { + if (ActivityCompat.checkSelfPermission( + requireContext(), + Manifest.permission.READ_SMS + ) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission( + requireContext(), + Manifest.permission.READ_PHONE_NUMBERS + ) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission( + requireContext(), + Manifest.permission.READ_PHONE_STATE + ) != PackageManager.PERMISSION_GRANTED + ) { + Toast.makeText(requireContext(), "Permissions denied!", Toast.LENGTH_SHORT).show() + launchRequestPermissions() + return + } + viewModel.loadInformation(requireActivity()) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) initLiveData() - viewModel.loadInformation(requireContext()) + requestPermissions() + } + + private fun requestPermissions() { + if (ActivityCompat.shouldShowRequestPermissionRationale( + requireActivity(), Manifest.permission.READ_PHONE_STATE + ) && ActivityCompat.shouldShowRequestPermissionRationale( + requireActivity(), Manifest.permission.READ_SMS + ) && ActivityCompat.shouldShowRequestPermissionRationale( + requireActivity(), "android.permission.READ_PHONE_NUMBERS" + ) + ) { + launchRequestPermissions() + } else { + launchRequestPermissions() + } } + private fun launchRequestPermissions() { + requestPermissionLauncher.launch( + arrayOf( + Manifest.permission.READ_PHONE_STATE, + Manifest.permission.READ_SMS, + "android.permission.READ_PHONE_NUMBERS" + ) + ) + } + + private fun initLiveData() { viewModel.getGeneralInformationLiveData().observe(viewLifecycleOwner) { Log.d(TAG, it.toString()) } + viewModel.getRAMInformationLiveData().observe(viewLifecycleOwner) { Log.d(TAG, it.toString()) } @@ -28,9 +91,14 @@ class MainFragment : Fragment(R.layout.fragment_main) { viewModel.getOSInformationLiveData().observe(viewLifecycleOwner) { Log.d(TAG, it.toString()) } + viewModel.getCPUInformationLiveData().observe(viewLifecycleOwner) { Log.d(TAG, it.toString()) } + + viewModel.getSIMCardInformationLiveData().observe(viewLifecycleOwner) { + Log.d(TAG, it.toString()) + } } companion object { diff --git a/sample/src/main/java/com/udfsoft/androidinfo/sample/ui/main/MainViewModel.kt b/sample/src/main/java/com/udfsoft/androidinfo/sample/ui/main/MainViewModel.kt index 5ba214a..548d3cd 100644 --- a/sample/src/main/java/com/udfsoft/androidinfo/sample/ui/main/MainViewModel.kt +++ b/sample/src/main/java/com/udfsoft/androidinfo/sample/ui/main/MainViewModel.kt @@ -1,14 +1,13 @@ package com.udfsoft.androidinfo.sample.ui.main +import android.Manifest import android.content.Context +import androidx.annotation.RequiresPermission import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.udfsoft.androidinfo.lib.DeviceInformationFactory -import com.udfsoft.androidinfo.lib.entity.CPUInformation -import com.udfsoft.androidinfo.lib.entity.GeneralInformation -import com.udfsoft.androidinfo.lib.entity.RAMInformation -import com.udfsoft.androidinfo.lib.entity.OSInformation +import com.udfsoft.androidinfo.lib.entity.* import com.udfsoft.androidinfo.sample.util.toLiveData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -23,11 +22,17 @@ class MainViewModel : ViewModel() { private val cpuInformationLiveData = MutableLiveData() + private val simCardInformationLiveData = MutableLiveData() + + @RequiresPermission( + allOf = [Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_SMS, "android.permission.READ_PHONE_NUMBERS"] + ) fun loadInformation(context: Context) = viewModelScope.launch(Dispatchers.IO) { generalInformationLiveData.postValue(DeviceInformationFactory.getGeneralInformation()) ramInformationLiveData.postValue(DeviceInformationFactory.getRAMInformation(context)) osInformationLiveData.postValue(DeviceInformationFactory.getOSInformation()) cpuInformationLiveData.postValue(DeviceInformationFactory.getCPUInformation()) + simCardInformationLiveData.postValue(DeviceInformationFactory.getSIMCardInformation(context)) } fun getGeneralInformationLiveData() = generalInformationLiveData.toLiveData() @@ -37,4 +42,6 @@ class MainViewModel : ViewModel() { fun getOSInformationLiveData() = osInformationLiveData.toLiveData() fun getCPUInformationLiveData() = cpuInformationLiveData.toLiveData() + + fun getSIMCardInformationLiveData() = simCardInformationLiveData.toLiveData() } \ No newline at end of file