34

In my app I have an activity and a service... The service will broadcast messages gathered from data from GPS... The Activity should receive the broadcast messages and update the UI...

my code

public class LocationPollerDemo extends Activity { private static final int PERIOD = 10000; // 30 minutes private PendingIntent pi = null; private AlarmManager mgr = null; private double lati; private double longi; private ServiceReceiver serviceReceiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mgr = (AlarmManager) getSystemService(ALARM_SERVICE); Intent i = new Intent(this, LocationPoller.class); i.putExtra(LocationPoller.EXTRA_INTENT, new Intent(this, ServiceReceiver.class)); i.putExtra(LocationPoller.EXTRA_PROVIDER, LocationManager.GPS_PROVIDER); pi = PendingIntent.getBroadcast(this, 0, i, 0); mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi); DebugLog.logTrace("On Create Demo"); Toast.makeText(this, "Location polling every 30 minutes begun", Toast.LENGTH_LONG).show(); serviceReceiver = new ServiceReceiver(); IntentFilter filter = new IntentFilter("me"); this.registerReceiver(serviceReceiver, filter); } class ServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { File log = new File(Environment.getExternalStorageDirectory(), "Location2.txt"); DebugLog.logTrace(Environment.getExternalStorageDirectory().getAbsolutePath()); try { BufferedWriter out = new BufferedWriter(new FileWriter(log.getAbsolutePath(), log.exists())); out.write(new Date().toString()); out.write(" : "); Bundle b = intent.getExtras(); Location loc = (Location) b.get(LocationPoller.EXTRA_LOCATION); String msg; if (loc == null) { loc = (Location) b.get(LocationPoller.EXTRA_LASTKNOWN); if (loc == null) { msg = intent.getStringExtra(LocationPoller.EXTRA_ERROR); } else { msg = "TIMEOUT, lastKnown=" + loc.toString(); } } else { msg = loc.toString(); } if (msg == null) { msg = "Invalid broadcast received!"; } out.write(msg); out.write("\n"); out.close(); } catch (IOException e) { Log.e(getClass().getName(), "Exception appending to log file", e); DebugLog.logException(e); } } } } 

When I use this code it is not working properly... I am using ServiceReceiver class in separate file works fine.... please tell me...!!

5 Answers 5

70

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(); } }; 
Sign up to request clarification or add additional context in comments.

12 Comments

and never forget to unregister reciever inside onPause
@FaisalNaseer How to unregister can you give some sample code please
Simply unregisterReceiver(mMessageReceiver );
unregister the receiver on "onDestroy" method :)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent); is this Activity Context or Service Context ?
|
12

A good way to have it is using Handler. Create a innerClass in your activity that extends Handler and Override the handleMessage method.

Then, in your ServiceReceiver class, create a handler variable and a constructor like:

public ServiceReceiver(Handler handler){ this.handler = handler; } 

So, in your activity, create your custom handler and pass it to your service. So, when you wants to put some data to your activity, you can put handler.sendMessage() in your Service (it will call handleMessage of your innerClass).

Comments

11

How to send data to Activity from IntentService ?

You don't need to bind a service if the service is meant for one way communication. For such cases using IntentService + BroadcastReceiver is quite easy.

Example:

You have a BackgroundService which calculates signal strength and sends back the data to Activity every second. And the Activity shows data in a GraphView.

How to do that?

enter image description here

Send data from Service

public class TrackWifiService extends IntentService { public TrackWifiService() { super("wifiService"); } protected void onHandleIntent(@Nullable Intent intent) { sendDataToActivity() } private void sendDataToActivity() { Intent sendLevel = new Intent(); sendLevel.setAction("GET_SIGNAL_STRENGTH"); sendLevel.putExtra( "LEVEL_DATA","Strength_Value"); sendBroadcast(sendLevel); } } 

Receive data from Service
For this, your Activity should register with a BroadcastReceiver

public class TrackWifiActivity extends AppCompatActivity { WifiLevelReceiver receiver; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.track_wifi_activity_layout); receiver = new WifiLevelReceiver(); registerReceiver(receiver, new IntentFilter("GET_SIGNAL_STRENGTH")); //<----Register } @Override public void onStop() { super.onStop(); unregisterReceiver(receiver); //<-- Unregister to avoid memoryleak } class WifiLevelReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("GET_SIGNAL_STRENGTH")) { int level = intent.getIntExtra("LEVEL_DATA",0); // Show it in GraphView } } } } 

Note:

If you want to use LocalBroadcastReceiver instead of a BroadcastReceiver. You can just see check out How to convert BroadCastReceiver to LocalBroadcastReceiver

Relevant Links

See Full project
What is an IntentService?
Difference between Bound and Unbound Services

2 Comments

If the user minimizes the app, it will unregister the receiver. So better to register it in onStart().
depends on the use case if you want data even if your app is in the background then register and unregister in bindService() in onCreate() and unbindService() in onDestroy() Read more stackoverflow.com/questions/8614335/… Read more here in the official docs developer.android.com/guide/components/…
1

There are three obvious ways to communicate with services

  1. Using Intents.
  2. Using AIDL.
  3. Using the service object itself (as singleton).

2 Comments

need to add more info about each approach
the question is clear: how to start communication from service to activity.
0
class MainActivity : AppCompatActivity() { private val sb = object :SerToBroad(){ override fun broadcastResult(connected: String?) { t(connected) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) } fun t(connected: String?) { Toast.makeText(MainActivity@this, connected, Toast.LENGTH_SHORT).show() } override fun onStart() { super.onStart() startService(Intent(MainActivity@ this, MService::class.java)) val inf = IntentFilter() inf.addAction(MService.ACTION) registerReceiver(sb, inf) } override fun onStop() { super.onStop() unregisterReceiver(sb) } } ------------------------------------- //Service class class MService : Service() { companion object {const val ACTION = "MY_ACTION"} override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { val intent = Intent() intent.action = ACTION intent.putExtra("DATA", "10") sendBroadcast(intent) return super.onStartCommand(intent, flags, startId) } -------------------------------------------------- broadcast abstract class SerToBroad : BroadcastReceiver() { override fun onReceive(p0: Context?, p1: Intent?) { val rec = p1?.getStringExtra("DATA") broadcastResult(rec) } abstract fun broadcastResult(connected: String?) } 

2 Comments

This code is illegible.
I could understand this, but there's a lack of explanation for others

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.