James
James

Reputation: 213

Android: calling a method from a Service to an Activity

I have a simple question to solve, but I am not sure how to do it.

I have a class that extends Service that runs a thread looking for a TCP connection. If one comes in, it read an input message.

If the input message is "START", I start an activity, in this fashion:

Intent dialogIntent = new Intent(getBaseContext(), VoIPCall.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.putExtra("inetAddress", clientSocket.getInetAddress());
getApplication().startActivity(dialogIntent);

While this activity is running, the Service keeps running. At some point I may reserve a "STOP". I would like to call a method in the previously created Activity but I am not sure how to interact with it.

I do not want to use a static method. How can I please do that?

Thank you very much,

EDIT: I changed my code to this:

Intent dialogIntent = new Intent("com.voip.rudy.START_CALL");
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
dialogIntent.putExtra("inetAddress", clientSocket.getInetAddress());
getApplication().startActivity(dialogIntent);

And in the manifest:

<activity android:name=".VoIPCall">
    <intent-filter>
        <action android:name="com.voip.rudy.START_CALL" />
        <action android:name="com.voip.rudy.STOP_CALL" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>


<category android:name="android.intent.category.DEFAULT" /> was required to avoid having it crash.

EDIT:

The solution given has fixed my issue but I wanted to actually act on member variables on that class, that are previously initialized. Say I call the constructor, then I would like to go back into this activity and act on the member variables.

The member variables are not initialized when I call one action after another, it seems to create a new activity somehow. Would there be anyway to act on the same activity, and keep the objects intact please?

James

Upvotes: 0

Views: 3536

Answers (3)

Jeff S
Jeff S

Reputation: 3256

I think any of the techniques would work. I'm guessing that the behavior you are seeing is related to the lifecycle of the activities within android and you might need to move some of your processing to the onResume/onPause or onStart/onStop methods. If you you find that your activity onCreate is not being called, but you now your activity is active, it might jsut be that an activity instance from a previous invocation is still alive in the system. If so, it is possible that the OS is using that instead of the new activity that you want. The best way to see if this is a problem is to put some "Log.d" calls at the beginning and end of all of the activity methods that you override. You will be able to tell what is happening by watching logcat. The technique that you use may also be dependent on how synchronous you want the activity's reaction to be with the TCP event. If you want completely async you can go with a standard broadcast, or a service callback with a message send. If you want synchronous then do it with a service callback. In case you haven't seen it this SDK link has a pretty good description of the activity lifecycle http://developer.android.com/reference/android/app/Activity.html

Upvotes: 0

dhaag23
dhaag23

Reputation: 6126

Add the Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT flags to your intent and call startActivity with a new action or a special extra that can identify the intent.

In the activity, write a method called :

private void handleIntent(Intent intent) {
}

call this from onCreate (or onResume) using:

handleIntent(getIntent());

and also write:

@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);
    handleIntent(intent);
}

Upvotes: 2

Jeff S
Jeff S

Reputation: 3256

There are a few ways to do it, really depends on the overall structure of your application. All can work. Off the top of my head these are the methods that come to mind

1) Create a custom intent and have the activity or service react to it when the otehr sends it 2) Instead of the service, setup the logic looking for the tcp connection as an async task within the dialog activity, when you have the tcp connection you could pass it off to the service to do its work 3) Take a look at the local service and remote service SDK examples and use the callback code as the basis for passing data back to the activity. You can also call through the interface back to the service. 4) Maybe even setup a broadcast receiver 'architecture'. This has the advantage of decoupling the user activity from the service entirely. You could put some of your application logic in a service in another process, or even in a process that runs at device boot.

Upvotes: 0

Related Questions