java – How to automatically receive, in Activity, a value calculated in a Service?

Question:

I have an algorithm that generates prime numbers using a Service . Well, it works but I need it to update the data in my main Activity automatically, at the moment it only does this with a click of a button and I need it to be done automatically.

That is, send to my textView always the last prime number generated in the service automatically. Any idea? I'm a beginner and would appreciate it if you can be very specific with examples I can use.

public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {

    private Chronometer cro;
    private TextView tvCampo;
    private Contador.ContadorServiceBinder binder = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        cro = (Chronometer) findViewById(R.id.cro);
        tvCampo = (TextView) findViewById(R.id.campoTexto);
        findViewById(R.id.botao).setOnClickListener(this);

        startService(Contador.i(this));
        bindService(Contador.i(this), this, BIND_AUTO_CREATE);

    }

    @Override
    public void onClick(View v) {
        cro.start();
        tvCampo.setText(String.valueOf(binder.getPrimo()));
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (binder == null) {
            unbindService(this);
            binder = null;
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binder = (Contador.ContadorServiceBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        binder = null;
    }
}

Here is my Activity that inherits from Service :

public class Contador extends Service {

    public int primo = 0;
    private Boolean ativo = false;
    private ContadorServiceBinder binder = new ContadorServiceBinder();

    public static Intent i(Context context) {
        return new Intent(context, Contador.class);
    }

    @Override
    public void onCreate() {

        if (!ativo) {
            ativo = true;

            new Thread() {

                public void run() {

                    int i = 2;
                    int j = 1;
                    int contador = 0;

                    while (i <= 1000000000) {
                        while (j <= i) {
                            if (i % j == 0) {
                                contador++;
                            }
                            j = j + 1;
                        }

                        if (contador == 2) {
                            primo = i;
                        }

                        i = i + 1;
                        j = 1;
                        contador = 0;
                    }
                }
            }.start();

        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        ativo = false;
        primo = 0;
        binder = null;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    public class ContadorServiceBinder extends Binder {

        public int getPrimo() {
            return primo;
        }
    }
}

Answer:

One of the possible ways for the Service to communicate with the Activity is to use LocalBroadcastManager to generate a broadcast to be received by the Activity

Service

Start by declaring the constants to be used to launch the broadcast :

//A *Action* para criar o *Intent*
public static final String ACTION_PRIME_CALCULATED = "oSeuPackageName.PRIME_CALCULATED";

//Chave para aceder ao *Extra* que guarda o valor do *primo*
public static final String PRIME_VALUE = "prime value";

Next, declare the method for launching the broadcast :

private void sendBroadcast(int primo){
    Intent intent = new Intent(ACTION_PRIME_CALCULATED)
                        .addCategory(Intent.CATEGORY_DEFAULT)
                        .putExtra(PRIME_VALUE, primo);
    LocalBroadcastManager.getInstance(this)
                         .sendBroadcast(intent);
}

At the end of the prime number calculation call this method:

@Override
public void onCreate() {

    if (!ativo) {
        ativo = true;

        new Thread() {

            public void run() {

                int i = 2;
                int j = 1;
                int contador = 0;

                while (i <= 1000000000) {

                    ....
                    ....
                }
                sendBroadcast(int primo);
            }
        }.start();

    }
}

Activity

Declare a BroadcastReceiver to receive the calculated prime number value:

private class PrimeValueReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        int primo = intent.getIntExtra(Contador.PRIME_VALUE,0);
        //Actualiza o TextView
        updateTextView(primo);
    }
}

In the onCreate method create an instance of PrimeValueReceiver :

private PrimeValueReceiver primeValueReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    primeValueReceiver = new PrimeValueReceiver();

    ....
    ....
}

In the onResume method register the BroadcastReceiver :

@Override
protected void onResume() {
    super.onResume();

    IntentFilter intentFilter = new IntentFilter(Contador.ACTION_PRIME_CALCULATED);
    intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
    LocalBroadcastManager.getInstance(this)
                         .registerReceiver(primeValueReceiver, intentFilter);
}

In the onPause method unregister the BroadcastReceiver :

@Override
protected void onPause() {
    super.onPause();

    //Unregister BroadcastReceiver.
    LocalBroadcastManager.getInstance(this)
      .unregisterReceiver(primeValueReceiver);
}

Just need to declare the method to update TextView :

private void updateTextView(int primo){

    tvCampo.setText(String.valueOf(primo));
}

Another possible approach is to use Messager and Handler to communicate Activity <-> Service. Here's an example .

Scroll to Top
AllEscort