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
Fused Location Provider Unexpected Behavior
How to Detect "Recent Apps" System Button Clicks (Honeycomb+)
Access_Coarse_Location Permission Gives a Cell Tower Precision on Android
My Android Camera Uri Is Returning a Null Value, But the Samsung Fix Is in Place, Help
Get Android Subscription Status, Failed with 403
Dependency Ignored Because of Conflict Android Studio
Proxy Which Requires Authentication with Android Emulator
Stop Fragment Refresh in Bottom Nav Using Navhost
Activity Killed/Oncreate Called After Taking Picture via Intent
Suggestions to Avoid Bitmap Out of Memory Error
Viewpager Offscreen Page Limit
How to Implement the Deprecated Methods of Notification
Size of Android Notification Bar and Title Bar
How to Detect Wifi Tethering State
Getting Context in Androidtestcase or Instrumentationtestcase in Android Studio's Unit Test Feature
Cordova - White Screen After Splash, No Exceptions in Console