Sending information from IntentService to Activity

98 views Asked by At

My question is that how I can send String "messages" (RISES and DROPS) from my background running IntentService to Main Activity? I want to show this messages in UI.

I tried to use EventBus, because it's needs less code and should be theoretically more simple for user, but unfortunatelly it's crashing app as soon I try register subscriber in onCreate method. Thanks!

MainActivity.java

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {


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

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

public void startService(View view) {
    Intent intent = new Intent(this, MyService.class);
    startService(intent);
}

// Method to stop the service
public void stopService(View view) {
    stopService(new Intent(getBaseContext(), MyService.class));
    System.exit(0);
}
}

MyService.java EDITED

import android.app.IntentService;
import android.app.Service;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;
import android.widget.Toast;



public class MyService extends IntentService {

public MyService() {
    super("MyService");
}

@Override
protected void onHandleIntent(Intent intent) {

    Runnable r = new Runnable() {
        public void run() {

            final int RECORDER_SAMPLERATE = 8000;
            final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
            final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
            int frequency;
            AudioRecord recorder;
            int numCrossing, p, numSamples;
            short audioData[];
            boolean recording;

            int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
                    RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);

            recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                    RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize);

            recorder.startRecording();
            recording = true;
            audioData = new short[bufferSize];
            int[] values;
            int k = 0, t = 0;

            values = new int[2];

            while (recording) {
                numCrossing = 0;
                numSamples = 0;
                recorder.read(audioData, 0, bufferSize);
                int mod = (bufferSize / 4) * 4;

                for (p = 0; p < mod; p += 4) {
                    if (audioData[p] > 0 && audioData[p + 1] <= 0) numCrossing++;
                    if (audioData[p] < 0 && audioData[p + 1] >= 0) numCrossing++;
                    if (audioData[p + 1] > 0 && audioData[p + 2] <= 0) numCrossing++;
                    if (audioData[p + 1] < 0 && audioData[p + 2] >= 0) numCrossing++;
                    if (audioData[p + 2] > 0 && audioData[p + 3] <= 0) numCrossing++;
                    if (audioData[p + 2] < 0 && audioData[p + 3] >= 0) numCrossing++;
                    if (audioData[p + 3] > 0 && audioData[p + 4] <= 0) numCrossing++;
                    if (audioData[p + 3] < 0 && audioData[p + 4] >= 0) numCrossing++;
                    numSamples += 4;
                }
                for (p = 0; p < bufferSize; p++) {
                    if (audioData[p] > 0 && audioData[p + 1] <= 0) numCrossing++;
                    if (audioData[p] < 0 && audioData[p + 1] >= 0) numCrossing++;
                    numSamples++;
                }

                frequency = (8000 / numSamples) * numCrossing;

                Log.d("proov", String.valueOf(frequency));

                if (frequency >= 2550 && frequency <= 2750 && (values[0] != 2)) {
                    values[0] = 1;
                    values[1] = 2;
                    k = 1;
                }//if

                if (frequency <= 3090 && frequency >= 2900 && (values[0] == 0)) {
                    values[0] = 2;
                    values[1] = 1;
                    k = 1;
                }//if

                if (frequency <= 3090 && frequency >= 2900 && (values[0] == 1)) {
                    t = 1;
                    break;
                }//if

                if (frequency >= 2550 && frequency <= 2750 && (values[0] == 2)) {
                    t = 2;
                    break;
                }//if

                if (k != 0) {
                    k = k + 1;
                }//if

                if (k == 20) {
                    values[0] = 0;
                    values[1] = 0;
                }//if

            }//while

            if (t == 1) {
                String message = "RISES";
                values[0] = 0;
                values[1] = 0;

            }//if

            if (t == 2) {
                String message = "DROPS";
                values[0] = 0;
                values[1] = 0;

            }//if
        }
    };

    Thread t = new Thread(r);
    t.start();
    //return Service.START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
2

There are 2 answers

0
Helmi On

You can use:

public class APIResultReceive extends ResultReceiver {

    private final static String TAG = "APIResultReceive";
    public final static int API_START = 1;
    public final static int API_END = 2;
    public final static int API_SUCCESS = 3;
    public final static int API_FAIL = 4;
    private Receive receive = null;

    public interface Receive {

        public void onReceiveResult(int resultCode, Bundle resultData);
    }

    public APIResultReceive(Handler handler) {
        super(handler);
    }

    public void setReceive(Receive receive) {
        this.receive = receive;
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        if (receive != null) {
            receive.onReceiveResult(resultCode, resultData);
        }
    }
}

in your service:

@Override
protected void onHandleIntent(Intent intent) {
    sendData(
        intent.getIntExtra(EXTRA_COUNT, 0),
        (ResultReceiver) intent.getParcelableExtra(EXTRA_RECEIVE)
    );
}

private void sendData(int count, ResultReceiver resultReceive) {
    resultReceive.send(APIResultReceive.API_START, null);

    for (int i = 0; i < count; i++) {
        Log.i(TAG, "i = " + i);
        SystemClock.sleep(1000);
    }

    resultReceive.send(APIResultReceive.API_END, null);
}

public static void sendData(Context context, int count, APIResultReceive resultReceive) {
    Intent intent = new Intent(context, APIService.class);
    intent.putExtra(EXTRA_COUNT, count);
    intent.putExtra(EXTRA_RECEIVE, resultReceive);
    context.startService(intent);
}

and finally on your activity :

public class MyActivity extends Activity implements APIResultReceive.Receive {

    private final static String TAG = "MyActivity";
    private APIResultReceive resultReceive = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");

        resultReceive = new APIResultReceive(new Handler());
        resultReceive.setReceive(this);

        //  start send data
        APIService.sendData(this, 10, resultReceive);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestory");
        resultReceive.setReceive(null);
    }

    @Override
    public void onReceiveResult(int resultCode, Bundle resultData) {
        switch (resultCode) {
            case APIResultReceive.API_START:
                Log.d(TAG, "APIResultReceive.API_START");
                break;
            case APIResultReceive.API_SUCCESS:
                Log.d(TAG, "APIResultReceive.API_SUCCESS");
                break;
            case APIResultReceive.API_FAIL:
                Log.d(TAG, "APIResultReceive.API_FAIL");
                break;
            case APIResultReceive.API_END:
                Log.d(TAG, "APIResultReceive.API_END");
                break;
        }
    }
}
0
suheb On

You can use BroadcastReceiver. Here's the documentaion for it.

Here's sample code:

MyService.java

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Intent sendIntent = new Intent("send_message");
    sendIntent.putExtra("message","RISES");
    sendBroadcast(sendIntent);
}

MainActivity.java

BroadcastReceiver mMessageReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   mMessageRecevier = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              String message = intent.getStringExtra("message");
              //Do whatever you want with message
          }
   };
}

@Override
public void onResume() {
    super.onResume();
    IntentFilter intentFilter = new IntentFilter("send_message");
    registerReceiver(mMessageRecevier, intentFilter);
}

@Override
public void onPause() {
    super.onPause();
    unregisterReceiver(mMessageRecevier);
}

I hope it helps.