У меня есть экран регистрации с помощью мобильного телефона, когда пользователь регистрируется с использованием номера мобильного телефона, отправляется otp, и я слушаю этот otp, чтобы пользователю не приходилось вручную кормить otp, но при прослушивании этого otp я получаюутечка памяти.
Вот мой код для прослушивания смс
class SmsReceiver : BroadcastReceiver() {
private var bundle: Bundle? = null
private lateinit var currentSMS: SmsMessage
private var otp: String? = null
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action.equals("android.provider.Telephony.SMS_RECEIVED")) {
bundle = intent?.extras
if (bundle != null) {
val pduObjects = bundle?.get("pdus") as Array<*>
for (i in pduObjects) {
currentSMS = i?.let { getIncomingMessage(it, bundle!!) }!!
val sender = currentSMS.displayOriginatingAddress
if (sender.endsWith("VK-DICEAP") || sender.endsWith("VM-DICEAP") || sender.endsWith("ID-DICEAP")) {
val msgBody = currentSMS.messageBody
otp = msgBody.replace(("[a-zA-Z.]").toRegex(), "").trim()
mListener.messageReceived(otp ?: "")
}
}
}
}
}
companion object {
private lateinit var mListener: SmsListener
fun bindListener(listener: SmsListener) {
mListener = listener
}
}
private fun getIncomingMessage(aObject: Any, bundle: Bundle): SmsMessage {
val currentSMS: SmsMessage
currentSMS = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val format = bundle.getString("format")
SmsMessage.createFromPdu(aObject as ByteArray?, format)
} else {
SmsMessage.createFromPdu(aObject as ByteArray?)
}
return currentSMS
}
}
Теперь в своей деятельности я использую следующий код
при создании проверяю ли я пользователяпредоставил разрешение или нет
private fun checkSmsPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(Manifest.permission.RECEIVE_SMS), RECEIVE_SMS)
} else {
receiveSms()
}
} else {
receiveSms()
}
}
Если да, тогда я просто отправляю OTP на мой сервер
private fun receiveSms() {
SmsReceiver.bindListener(object : SmsListener {
override fun messageReceived(messageText: String) {
//send otp to server
}
})
}
Я создал отдельный интерфейс только для обратного вызова
interface SmsListener {
fun messageReceived(messageText: String)
}
Теперь я искал это в stackoverflow и увидел, что вместо регистрации получателя в файле манифеста вы должны зарегистрироваться и отменить регистрацию по коду. Поэтому я попытался использовать код следующим образом
override fun onStart() {
super.onStart()
smsReceiver = SmsReceiver()
val filter = IntentFilter()
filter.addAction("android.provider.Telephony.SMS_RECEIVED")
registerReceiver(smsReceiver, filter)
checkSmsPermission()
}
override fun onStop() {
super.onStop()
unregisterReceiver(smsReceiver)
}
, но все равно получаюутечка памяти в моем приложении.Я использую LeakCanary для обнаружения утечек в моем приложении.
Вот скриншот утечки