Send Intent from Service to Activity

send intent from service to activity

For this, you can use a BroadcastReceiver in your Activity.

Here is a great example I use to communicate continuously between Service <> Activity using BroadcastReceivers.

Here is another great example of communication between Service <> Activity. It uses Messenger and IncomingHandler.

BroadcastReceiver

I will make a quick example for your case.

This is your BroadcastReceiver for your Activity. It is going to receive your String:

//Your activity will respond to this action String
public static final String RECEIVE_JSON = "com.your.package.RECEIVE_JSON";

private BroadcastReceiver bReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(RECEIVE_JSON)) {
String serviceJsonString = intent.getStringExtra("json");
//Do something with the string
}
}
};
LocalBroadcastManager bManager;

In your onCreate() of the activity

bManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVE_JSON);
bManager.registerReceiver(bReceiver, intentFilter);

In your onDestroy() of the activity, make sure you unregister the broadcastReceiver.

bManager.unregisterReceiver(bReceiver);

And finally, in your Service onStart(), do this:

System.out.println("intent Received");
String jsonString = rottenTomatoesSearch(intent.getStringExtra("query"));
Intent RTReturn = new Intent(YourActivity.RECEIVE_JSON);
RTReturn.putExtra("json", jsonString);
LocalBroadcastManager.getInstance(this).sendBroadcast(RTReturn);

and your Activity will receive the intent with that json in it as an extra

Send string from service to activity

LocalBroadcastManager is the best solution for solving this type of problem. I have implemented LocalBroadcastManager to your existing. Its very easy. Hope it will work. You code will look something like this

private BroadcastReceiver statusReceiver;
private IntentFilter mIntent;
Sensor accelerometer;
SensorManager sm;
TextView acceleration;
SendValues sv;
int counter3 = 0;
int counter5 = 0;

private static final String TAG = "MainActivity";

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

//mIntent = new IntentFilter("NOW");

// this.registerReceiver(,new IntentFilter("status"));

sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.registerListener(this,accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

acceleration = (TextView) findViewById(R.id.sensorTxt);

}

private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String type = intent.getStringExtra("message"); //get the type of message from MyGcmListenerService 1 - lock or 0 -Unlock
sm = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Log.d(TAG, "Status: " + type);
if (type == "1") // 1 == lock
{
Toast.makeText(getApplication(), "Lock", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplication(), "UNLOCK", Toast.LENGTH_LONG).show();
}
}
};

@Override
protected void onResume()
{
super.onResume();
//registerReceiver(statusReceiver,mIntent);
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(broadcastReceiver, new IntentFilter("NOW"));
}

@Override
protected void onPause() {
if(mIntent != null) {
unregisterReceiver(statusReceiver);
mIntent = null;
}
super.onPause();
}

And pass your value from push notification something like this

Intent in = new Intent();
in.putExtra("TYPE",typemessage);
in.setAction("NOW");
//sendBroadcast(in);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);

How to send a message from an Intent Service to an activity

Try out as below:

  private Handler handler = new Handler() 
{
public void handleMessage(Message message)
{
final Intent intent = new Intent(this, FillingDatabase.class);
final Messenger messenger = new Messenger(handler);
intent.putExtra("messenger", messenger);
startService(intent);
};
};

How to safely send data from a service to running activity

Q: How do I send data from an Android service to my activity?

A: You have several alternatives:

1. Use intents:

How to get data from service to activity

Send msg from service:

private static void sendMessageToActivity(Location l, String msg) {
Intent intent = new Intent("GPSLocationUpdates");
// You can also include some extra data.
intent.putExtra("Status", msg);
Bundle b = new Bundle();
b.putParcelable("Location", l);
intent.putExtra("Location", b);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

Register to receive message in activity:

LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
mMessageReceiver, new IntentFilter("GPSLocationUpdates"));

Custom message receiver in activity:

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("Status");
Bundle b = intent.getBundleExtra("Location");
lastKnownLoc = (Location) b.getParcelable("Location");
...

I would NOT characterize this as "unsafe" - it can be a perfectly reasonable approach.

2. Have the activity bind to the service

https://developer.android.com/guide/components/bound-services

Service:

public class LocalService extends Service {
// Binder given to clients
private final IBinder binder = new LocalBinder();
...
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}

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

Activity:

@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
...
@Override
protected void onStop() {
super.onStop();
unbindService(connection);
mBound = false;
...
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection connection = new ServiceConnection() {

@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
...
// To use the service, your client would call mService.someMethod()...

I'm not sure exactly what you're looking for, but example 1 is probably your best bet.

Here's a tutorial that might help give you more details/more ideas:

Basics Of Services In Android:

  • Part 1: Basics
  • Part 2: Binding services to an activity
  • Part 3: Using Messenger

https://developer.android.com/guide/components/broadcasts

Android provides three ways for apps to send broadcast:

  • The sendOrderedBroadcast(Intent, String) method sends broadcasts to one receiver at a time.
  • sendBroadcast(Intent) method sends broadcasts to all receivers in an undefined order. This is called a Normal Broadcast. This is more
    efficient, but means that receivers cannot read results from other
    receivers, propagate data received from the broadcast, or abort the
    broadcast.
  • LocalBroadcastManager.sendBroadcast method sends broadcasts to receivers that are in the same app as the sender. If you don't need to
    send broadcasts across apps, use local broadcasts. The implementation
    is much more efficient (no interprocess communication needed) and you
    don't need to worry about any security issues related to other apps
    being able to receive or send your broadcasts.

Additionally:

https://developer.android.com/guide/components/broadcasts#restrict-broadcasts-permissions

Restricting broadcasts with permissions

Permissions allow you to restrict broadcasts to the set of apps that hold certain permissions. You can enforce restrictions on either
the sender or receiver of a broadcast.

Sending with permissions

When you call sendBroadcast(Intent, String) or sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int,
String, Bundle), you can specify a permission parameter. Only
receivers who have requested that permission with the tag in their
manifest (and subsequently been granted the permission if it is
dangerous) can receive the broadcast. For example, the following code
sends a broadcast:

Personally, I don't see any "security" issue at all with simply using an intent.

But if you want or need to, you can use the above techniques to further lock down communications.

'Hope that helps!

sending intent extras from service to activity

The does() method seems to be using variables in the same scope as onReceive so I'm guessing that the intent variable in does() is actually the Intent passed in from onReceive.

Try adding some logging before sending the broadcast to check if the action of the intent is correct, or simply create the broadcast intent in the onReceive method and name it intent2.

Pass data from Activity to Service using an Intent

First Context (can be Activity/Service etc)

For Service, you need to override onStartCommand there you have direct access to intent:

Override
public int onStartCommand(Intent intent, int flags, int startId) {

You have a few options:

1) Use the Bundle from the Intent:

Intent mIntent = new Intent(this, Example.class);
Bundle extras = mIntent.getExtras();
extras.putString(key, value);

2) Create a new Bundle

Intent mIntent = new Intent(this, Example.class);
Bundle mBundle = new Bundle();
mBundle.extras.putString(key, value);
mIntent.putExtras(mBundle);

3) Use the putExtra() shortcut method of the Intent

Intent mIntent = new Intent(this, Example.class);
mIntent.putExtra(key, value);

New Context (can be Activity/Service etc)

Intent myIntent = getIntent(); // this getter is just for example purpose, can differ
if (myIntent !=null && myIntent.getExtras()!=null)
String value = myIntent.getExtras().getString(key);
}

NOTE: Bundles have "get" and "put" methods for all the primitive types, Parcelables, and Serializables. I just used Strings for demonstrational purposes.

Send broadcast intent from service to Application Class

If your Service is active, then your Application class is active as well.

Otherwise you wouldn't be able to use getApplicationContext().

Although I'm skeptic about a service that runs forever there is a very clean way to make the Service communicate with a certain Activity, should the last one be currently active.

Such clean way is called LocalBroadcastManager.

The Activity meant to receive the data should register a BroadcastReceiver in onResume() and unregister it in onPause().

You instantiate your BroadcastReceiver in your Activity's onCreate()

this.localBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Do what you have to do here if you receive data from the Service.
}
}

You create a Filter so your Activity only listens to a certain type of signals.

private IntentFilter notifIntentFilter new IntentFilter("com.you.yourapp.MY_SIGNAL");

in onResume()

LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, notifIntentFilter);

in onPause()

LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);

Now whenever you want to send data to your Activity, your Service can call:

final Intent intent = new Intent();
intent.setAction("com.you.yourapp.MY_SIGNAL");
// put your data in intent

LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

If your Activity is awake, it will respond to the signal. Otherwise, if it's in the background, or it is not instantiated it won't.

You can apply this pattern to as many Activities as you wish.


Still, I have never used this inside the Application class. But you can try to register your receiver there. It might work, since if the Application class is destroyed, the BroadcastReceiver is destroyed too and thus probably unregistered as well.

The point is, if your Application gets destroyed, your Service will be killed as well. Unless you launched it in another process. But then it will have it's own instance of Application; and this is a complex thing you probably do not want to get into details now...


Important: since the Application class is not tied to any UI component, you can do whatever you need directly inside your service. If you need to manipulate the UI, then the pattern described above will work for you.

Please read about new Android's background limitations.


Edit:

Oh yeah right, if you need your Service to call a function declared in your Application class, you can just do

((MyApplication) getApplication()).myFunctionToHandleData(Intent intent);

I didn't really understand your question though, but either of the methods described above should work for you.

How to get data from service to activity

In my Service class I wrote this

private static void sendMessageToActivity(Location l, String msg) {
Intent intent = new Intent("GPSLocationUpdates");
// You can also include some extra data.
intent.putExtra("Status", msg);
Bundle b = new Bundle();
b.putParcelable("Location", l);
intent.putExtra("Location", b);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
}

and at the Activity side we have to receive this Broadcast message

LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
mMessageReceiver, new IntentFilter("GPSLocationUpdates"));

By this way you can send message to an Activity.
here mMessageReceiver is the class in that class you will perform what ever you want....

in my code I did this....

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Get extra data included in the Intent
String message = intent.getStringExtra("Status");
Bundle b = intent.getBundleExtra("Location");
lastKnownLoc = (Location) b.getParcelable("Location");
if (lastKnownLoc != null) {
tvLatitude.setText(String.valueOf(lastKnownLoc.getLatitude()));
tvLongitude
.setText(String.valueOf(lastKnownLoc.getLongitude()));
tvAccuracy.setText(String.valueOf(lastKnownLoc.getAccuracy()));
tvTimestamp.setText((new Date(lastKnownLoc.getTime())
.toString()));
tvProvider.setText(lastKnownLoc.getProvider());
}
tvStatus.setText(message);
// Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
}
};


Related Topics



Leave a reply



Submit