|
|
@@ -1,21 +1,25 @@
|
|
|
package com.example.modifier.ui.settings
|
|
|
|
|
|
+import android.Manifest
|
|
|
import android.annotation.SuppressLint
|
|
|
import android.content.Context
|
|
|
import android.content.DialogInterface
|
|
|
-import android.content.Intent
|
|
|
+import android.content.pm.PackageManager
|
|
|
import android.os.Bundle
|
|
|
import android.os.Handler
|
|
|
import android.os.Looper
|
|
|
+import android.telephony.SubscriptionManager
|
|
|
+import android.telephony.TelephonyManager
|
|
|
import android.text.Editable
|
|
|
import android.util.Log
|
|
|
import android.view.LayoutInflater
|
|
|
import android.view.View
|
|
|
import android.view.ViewGroup
|
|
|
import android.widget.Toast
|
|
|
-import androidx.datastore.core.DataStore
|
|
|
-import androidx.datastore.preferences.core.Preferences
|
|
|
-import androidx.datastore.preferences.preferencesDataStore
|
|
|
+import androidx.activity.result.ActivityResultLauncher
|
|
|
+import androidx.activity.result.contract.ActivityResultContracts
|
|
|
+import androidx.core.app.ActivityCompat
|
|
|
+import androidx.core.content.ContextCompat
|
|
|
import androidx.fragment.app.Fragment
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
import com.example.modifier.Global
|
|
|
@@ -23,8 +27,6 @@ import com.example.modifier.Global.load
|
|
|
import com.example.modifier.Global.save
|
|
|
import com.example.modifier.Global.saveServer
|
|
|
import com.example.modifier.Global.servers
|
|
|
-import com.example.modifier.MainActivity
|
|
|
-import com.example.modifier.service.ModifierService.Companion.instance
|
|
|
import com.example.modifier.R
|
|
|
import com.example.modifier.Utils
|
|
|
import com.example.modifier.databinding.FragmentSettingsBinding
|
|
|
@@ -36,12 +38,11 @@ import com.example.modifier.http.response.GetChannelListResponse
|
|
|
import com.example.modifier.http.response.RcsNumberResponse
|
|
|
import com.example.modifier.model.Channel
|
|
|
import com.example.modifier.model.TelephonyConfig
|
|
|
+import com.example.modifier.service.ModifierService.Companion.instance
|
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
|
import io.ktor.client.call.body
|
|
|
-import io.ktor.client.plugins.resources.get
|
|
|
-import io.ktor.client.plugins.resources.put
|
|
|
import io.ktor.client.plugins.resources.post
|
|
|
-import io.ktor.client.request.post
|
|
|
+import io.ktor.client.plugins.resources.put
|
|
|
import io.ktor.client.request.setBody
|
|
|
import io.ktor.client.statement.HttpResponse
|
|
|
import io.ktor.client.statement.bodyAsText
|
|
|
@@ -49,19 +50,16 @@ import io.ktor.http.ContentType
|
|
|
import io.ktor.http.contentType
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
-import kotlinx.coroutines.delay
|
|
|
import kotlinx.coroutines.launch
|
|
|
import kotlinx.coroutines.withContext
|
|
|
-import kotlinx.coroutines.withTimeout
|
|
|
import org.apache.commons.lang3.RandomStringUtils
|
|
|
import org.apache.commons.lang3.StringUtils
|
|
|
import org.apache.commons.validator.routines.UrlValidator
|
|
|
-import java.time.LocalDateTime
|
|
|
-import java.time.temporal.ChronoUnit
|
|
|
import java.util.Objects
|
|
|
import java.util.Optional
|
|
|
import java.util.concurrent.ScheduledThreadPoolExecutor
|
|
|
|
|
|
+@SuppressLint("SetTextI18n", "MissingPermission", "HardwareIds", "NewApi")
|
|
|
class SettingsFragment : Fragment() {
|
|
|
private val TAG = "SettingsFragment"
|
|
|
|
|
|
@@ -72,11 +70,29 @@ class SettingsFragment : Fragment() {
|
|
|
var channels: List<Channel> = emptyList()
|
|
|
var channelId: Int? = null
|
|
|
|
|
|
+ lateinit var requestPermissionLauncher: ActivityResultLauncher<String>
|
|
|
+
|
|
|
init {
|
|
|
Log.i("SettingsFragment", "SettingsFragment")
|
|
|
}
|
|
|
|
|
|
- @SuppressLint("SetTextI18n")
|
|
|
+ override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
+ super.onCreate(savedInstanceState)
|
|
|
+ requestPermissionLauncher =
|
|
|
+ registerForActivityResult(
|
|
|
+ ActivityResultContracts.RequestPermission()
|
|
|
+ ) { isGranted: Boolean ->
|
|
|
+ if (isGranted) {
|
|
|
+ } else {
|
|
|
+ // Explain to the user that the feature is unavailable because the
|
|
|
+ // feature requires a permission that the user has denied. At the
|
|
|
+ // same time, respect the user's decision. Don't link to system
|
|
|
+ // settings in an effort to convince the user to change their
|
|
|
+ // decision.
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
override fun onCreateView(
|
|
|
inflater: LayoutInflater, container: ViewGroup?,
|
|
|
savedInstanceState: Bundle?
|
|
|
@@ -207,6 +223,72 @@ class SettingsFragment : Fragment() {
|
|
|
prefs.edit().putBoolean("do_not_request", isChecked).apply()
|
|
|
}
|
|
|
|
|
|
+ binding.btnCheck.setOnClickListener {
|
|
|
+
|
|
|
+ when {
|
|
|
+ ContextCompat.checkSelfPermission(
|
|
|
+ requireContext(),
|
|
|
+ Manifest.permission.READ_PHONE_STATE
|
|
|
+ ) == PackageManager.PERMISSION_GRANTED -> {
|
|
|
+ val telephonyManager =
|
|
|
+ requireContext().getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
|
|
|
+
|
|
|
+ var res = """IMEI: ${telephonyManager.imei}
|
|
|
+ |IMSI: ${telephonyManager.subscriberId}
|
|
|
+ |ICCID: ${telephonyManager.simSerialNumber}
|
|
|
+ |Phone Number: ${telephonyManager.line1Number}
|
|
|
+ |Network Operator: ${telephonyManager.networkOperator}, ${telephonyManager.networkCountryIso}, ${telephonyManager.networkOperatorName}
|
|
|
+ |Sim Operator: ${telephonyManager.simOperator}, ${telephonyManager.simCountryIso}, ${telephonyManager.simOperatorName}
|
|
|
+ |Sim state: ${telephonyManager.simState}
|
|
|
+ |
|
|
|
+ """.trimMargin()
|
|
|
+ val subscriptionManager: SubscriptionManager =
|
|
|
+ requireContext().getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
|
|
|
+
|
|
|
+ val simCount = subscriptionManager.activeSubscriptionInfoCountMax
|
|
|
+ for (i in 0 until simCount) {
|
|
|
+ val info =
|
|
|
+ subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(i)
|
|
|
+ ?: continue
|
|
|
+ res += """
|
|
|
+ |--- Slot:$i Subscription ID: ${info.subscriptionId} ---
|
|
|
+ |ICCID: ${info.iccId}
|
|
|
+ |Number: ${subscriptionManager.getPhoneNumber(info.subscriptionId)}
|
|
|
+ |Country: ${info.countryIso}
|
|
|
+ |MCC: ${info.mccString}
|
|
|
+ |MNC: ${info.mncString}
|
|
|
+ """.trimMargin()
|
|
|
+ }
|
|
|
+ MaterialAlertDialogBuilder(requireContext())
|
|
|
+ .setTitle("Info")
|
|
|
+ .setMessage(res)
|
|
|
+ .setPositiveButton("OK") { dialog: DialogInterface, which: Int ->
|
|
|
+ dialog.dismiss()
|
|
|
+ }
|
|
|
+ .show()
|
|
|
+ }
|
|
|
+
|
|
|
+ ActivityCompat.shouldShowRequestPermissionRationale(
|
|
|
+ requireActivity(), Manifest.permission.READ_PHONE_STATE
|
|
|
+ ) -> {
|
|
|
+ // In an educational UI, explain to the user why your app requires this
|
|
|
+ // permission for a specific feature to behave as expected, and what
|
|
|
+ // features are disabled if it's declined. In this UI, include a
|
|
|
+ // "cancel" or "no thanks" button that lets the user continue
|
|
|
+ // using your app without granting the permission.
|
|
|
+ }
|
|
|
+
|
|
|
+ else -> {
|
|
|
+ // You can directly ask for the permission.
|
|
|
+ // The registered ActivityResultCallback gets the result of this request.
|
|
|
+ requestPermissionLauncher.launch(
|
|
|
+ Manifest.permission.READ_PHONE_STATE
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
executor.execute {
|
|
|
load()
|
|
|
handler.post {
|