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:
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!