0

I cant quite seem to get the values from Broadcast Receiver to textviews in Main Activity.

In Android (KOTLIN) I managed to create a broadcast receiver that gets the phoneNumber and text Message in a Toast Event When an SMS message is received.

In main activity, I also have a button that when clicked calls #133# to check my Airtime Balance.

smsReceive Class code;

package com.example.demmo

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import  android.os.Build
import android.telephony.SmsMessage
import android.widget.Toast
import android.app.Activity


class SmsReceiver : BroadcastReceiver(){
    var activity : Activity? = null
    override fun onReceive(context: Context, intent: Intent) {
        val extras = intent.extras

        if(extras != null){
            val sms = extras.get("pdus") as Array<Any>

            for(i in sms.indices) {
                val format = extras.getString("format")

                var smsMessage = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    SmsMessage.createFromPdu(sms[i] as ByteArray, format)
                } else {
                    SmsMessage.createFromPdu(sms[i] as ByteArray)
                }
                val phoneNumber = smsMessage.originatingAddress
                val messageText = smsMessage.messageBody.toString()

                Toast.makeText(context, "From: $phoneNumber Message: $messageText", Toast.LENGTH_LONG).show()


            }
        }
    }
}

MainActivity.kt code

package com.example.demmo

import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ActivityCompat
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import  android.net.Uri
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private val requestReceiveSms = 2
    val balance = "*144%23"
    val REQUEST_PHONE_CALL = 1

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS)
            != PackageManager.PERMISSION_GRANTED
        ) {

            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.RECEIVE_SMS), requestReceiveSms)
        }

        btnBalance.setOnClickListener {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), REQUEST_PHONE_CALL)
            } else{
                balance()
            }
        }
    }
    @SuppressLint("MissingPermission")
    private fun balance() {
        val callIntent = Intent(Intent.ACTION_CALL)
        callIntent.data = (Uri.parse("tel:" + balance))
        startActivity(callIntent)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        if(requestCode == REQUEST_PHONE_CALL)balance
    }
}

I would like some code after ' Toast.makeText(context, "From: $phoneNumber Message: $messageText", Toast.LENGTH_LONG).show()' to put the values phoneNumber and textmessage to TextViews txtPhone and txtSMS respectively and 'Click' or call phoneNumber programtically.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Well, what's your problem of making it work? It is not really difficult, much less difficult than the rest of what you've achieved. So, where is your problem? What have you tried? – Sheradil Jul 18 '19 at 21:26
  • I can do that manually, but I would like the app to programatically/Automatically call the the number after the toast event. – Kevin Bright Jul 18 '19 at 21:27
  • My first idea (not the cleanest). You just have to call "fun balance" from the SmsReceiver class. Or copy paste the code of "fun balance" behind the toast (First one is the less dirty code, but the first one requires some context handling) – Sheradil Jul 18 '19 at 21:32
  • Thanks Sheradil for quick reply. – Kevin Bright Jul 18 '19 at 21:40
  • I've tried to copy paste the code of "fun balance" behind the toast but i get an Uresolved Refernce startActivity Error. could you be having ideas on how to call "fun balance" from the SmsReceiver class? – Kevin Bright Jul 18 '19 at 21:41
  • Take a look at this one. https://stackoverflow.com/questions/28083430/communication-between-broadcastreceiver-and-activity-android That might help. I didn't get your problem at first. The solution I posted is a bit dirty. I guess your problem is the communication between the main activity and activity that starts by an incoming SMS that has no direct connection with main. So the link should help – Sheradil Jul 18 '19 at 21:41

1 Answers1

0

I can not provide working code as I neither have Android nor Kotlin installed right now. Basically you should follow this approach. The observer pattern is a widely used concept. And maybe the cleanest way to achieve what you're looking for: Communication between BroadcastReceiver and Activity - android

With some dirty code, you would be able to call "fun balance" from the SmsReceiver class. But that's something you really don't want to do. You can try getting it done as an exercise, but I don't recommend using it. Not if there are better ways ;) If, for some reason the observer pattern does not work, I can elaborate on other possiblities.

-------------- EDIT -------------

Ok, if you're having trouble with the observer pattern, I will think of something else.

You want to call "fun balance" from the other activity. The Broadcast-Receiver has no reference to the Main class. So add to your MainActivity

static MainActivity reference
public static MainActivity getInstance() {
    return reference;
}

Add this to the constructor of the MainActivity

reference = this

In the SmsReceiver right after the toast, add:

MainActivity ma = MainActivity.getInstance()
ma.balance()

Don't forget to declare balance as public, else it won't work. I said I can't test it ... There might be a problem as I think that the BroadcastReceiver is executed inside of another thread, so you might have to invoke this on the other Thread. Not sure if you really have to do that though. If that does not work as well, check these link: Calling activity class method from Service class The first 2 answers look promising

Sheradil
  • 407
  • 3
  • 14