How to update periodically from service to activity in Android - android

I have somewhat experience with Android.I would like to know how to update periodically from service to activity in Android.I am playing with an app which has Location Service running at the background and update to Activity how much the user is traveling. In the past, I broadcast distance from service and I use broadcast Receiver in Activity. However, this method is way too slow.
I recently discover that I can bind service, or use Handler to update periodically to activity from service. However, I do not understand detail especially Handler. Can anyone explain me how can I update periodically from service to activity using Handler. When I use handler, do I need to bind service? Or are those separate thing.
What I want is I want to update how much user travel by using onlocationChange() method from service to activity which has UI.

I will first explain you how the onLocationChange(Location l) method works.
This method is call-back - it means it will be called by the android system automatically. It will be called A) after amount of time passes or B ) after your position changes by certain meters. Those two parameters are specified by you when you create the LocationManager.
Having this in mind, you should for example declare a global variable with the distance, lets say
int a = 0;
Now in this method you must use the Location l which you are passed. You must add the moved distance to the variable a. Now, if all this code is inside the activity where you display the distance traveled, you simply use the variable a, else you have many choices. Either put it in shared preferences, or use function that sends that to the other activity.
Best of luck.

Have you look at the official solution?
http://developer.android.com/training/location/receive-location-updates.html
also this is a good example for what you want
https://github.com/commonsguy/cwac-locpoll
I think this can help you.

First create one Interface to Update the location
Interface to get continuous updates.
public interface ILocationlistener {
public void updateLocation(Location location);
public void updateLatitude(Double lat);
public void updateLongitude(Double lang);
}
update the ILocationlistener interface in onLocationChanged(Location location) in LocationListener so every location changes you will get the updatats.
After Use ILocationListerner interfase to update location changes in Activity or Service. After getting location use Handler or UI thread to update the UI in main thread.
For example http://www.androidsourcehelp.com/2014/03/get-location-and-its-changes-in-android.html?m=1

Related

Can not stop fusedLocation updates using removeLocationUpdates

I have created a class naming MyLocationProvider with all methods provided in fusedLocationAPI as well as the following to stop the location updates:
private void stopLocationUpdates() {
mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
In main activity I use this class like this:
MyLocationProvider mylocation=new MyLocationProvider(this);
Location updates works fine but I am confused how requestLocationUpdates works. When I close then application, requestLocationUpdates is not stopped (it seem something like background process but is not listed in device services). When I open the application, a new instance of MyLocationProvider also starts working and I receive multiple parallel updates from my device.
How should I use removeLocationUpdates to stop an exact instance of location provider when they seems not to be a part of my application?
Call this method on stop or on destroy method of fragment or activity which is used by u.

Access the results of a started service from two different activities in Android

I have a service that gets the user's location and broadcasts the latitude and longitude in an intent.
I believe that I need the service to be a started service (as opposed to bound service), because I would like for it to be able to send a push notification to the user when a new geoFire entry from firebase enters their radius even when the app is closed.
Currently, the service is set up to broadcast the location.
Given that the location service will be a started service, I don't know how to access the broadcast from two separate activities.
I believe that I could achieve this if it were a bound service, but since I want it to stay alive indefinitely, I'm not sure what to do.
Here is a minimal example that demonstrates my issue.
Specifically, I can get the latitude and longitude to display on the first activity by registering a broadcast receiver, but I can't get the latitude and longitude to display on the second activity by registering a separate broadcast receiver.
I have read Android's documentation on Services but still don't really know what I'm supposed to do to resolve this problem.
I've been testing this all on an emulator from Android Studio: Nexus 5X API 25 x86.
UPDATE Nov. 8, 2017: I've updated the github project to contain the EventBus solution provided below. It is in the eventBus branch. The master branch still contains the ualtered, problematic code pertaining to the question.
To view:
git clone https://github.com/Atticus29/locationServiceMCV.git
git checkout eventBus
Then, open AndroidStudio or IDE of choice and view/run as you normally would.
Broadcasting the results is one way to solve this issue. But if you're willing to add a lib on your project I would strongly recommend Green Robot's EventBus. It's a very lightweight lib, as it's fast. Also, it's simple to post complex objects through it without having to implement the Parcelable interface.
This lib works on a publisher/subscriber fashion, where in your case, both Activities would be the subscribers, and the Service would be the publisher.
First of all, you have to add the dependency on your build.gradle file as below.
implementation 'org.greenrobot:eventbus:3.0.0'
If you're on a Kotlin project, also add this dependency:
kapt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
Then, define an Event class that will be responsible to carry your data through the app. Note that this could be done from a Service to an Activity. From a Fragment to another. Between Activities, and so on.
public class MessageEvent {
public double lat;
public double lng;
// Add additional fields here if needed
public MessageEvent(double lat, double lng) {
this.lat= lat;
this.lng = lng;
}
}
After that, you have to subscribe to those events on your Activity.
public class MyActivity extends AppCompatActivity {
// ...
#Override
public void onResume() {
super.onResume();
// This line will register your Activity to the EventBus
// making sure that all the methods annotated with #Subscribe
// will be called if their specific Events are posted.
EventBus.getDefault().register(this);
}
#Override
public void onPause() {
super.onPause();
// This line will unregister your Activity.
// It's a good practice to put this on the onPause() method
// to make your event handling system tied to the Activity lifecycle.
EventBus.getDefault().unregister(this);
}
// The threadMode MAIN makes sure this method is called on the main Thread.
// But you could also set it up to be called on other threads if needed. Check the docs for more info.
#Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
/* Call this line below if you want to remove the sticky event.
* That will prevent that this event will be seen by other subscribers once they subscribe.
* In your specific use case, you don't have to remove the sticky event here.
*/
// EventBus.getDefault().removeStickyEvent(event);
double lat = event.lat;
double lng = event.lng;
// Do whatever you want with the data.
};
}
With that implemented, you're ready to post your events. Now, inside your Service, call the following code when you get the new Lat/Lng information.
EventBus.getDefault().postSticky(new MessageEvent(lat,lng));
You can read more on how to setup and customize the EventBus on the docs, or on this tutorial.

requesting updates using location listener in service is stopping another location listener in activity

When I requestUpdates in the service using location listener, another listener which I have put in the activity doesn't work. The moment I stop that service (from within the app using toggle button), the activity starts listening for location again. I want both working. Why both are not working simultaneously? Am I missing something?
Try adding this to your activity :
#Override
public void onDestroy() {
super.onDestroy();
getActivity().unregisterReceiver(receiver);
}
I figured out how the requestLocationUpdates( ) function behaves.
CASE 1: [my case]
I was using two separate Inner Class implementations of LocationListener, one in the Activity and one in the Service, each requesting for location updates at the same time via requestLocationUpdates(.., .., ..,locationListener) function.
These locationListener objects were not instances of SAME class, so the one who first got used in requestLocationUpdates() function, only it was working.
CASE 2:
On the second hand, if you call requestLocationUpdates() with instance(s) of SAME LocationListener class, all of these work simultaneously.
CASE 3:
On the third hand :D, if you call requestLocationUpdates() multiple times with one same instance of a LocationListener implementation, the most recent call takes over the previous ones with whatever minTime and minDistance passed in the function.
Note: all of above cases are tested on the requestLocationUpdates(String provider, int minTime, int minDist, LocationListener listener) version of function.

Android service (location listener) to update activity

I have an activity that shows a map with markers on it. Also I have a location listener, whose values will update the activity arraylist and cause a redraw of the markers based on the updated arraylist values.
I want this to always run (even if the activity is put in the background). I understand that Activity may get killed so I expect that I need a service for the location lisntener. Now my question is: How can I update the activity arraylist and redraw contents when the service is actually the one obtaining info?
I read something about boundservice so maybe I need that? However I need the service running even if activity is killed.
OR Do I just create service and then send a broadcast to activity?
Thank you
Like you have written at the end of your post you could use a BroadcastReceiver for this. That's the way I use it.
In onCreate(...) of your Activity, register it locally:
LocalBroadcastManager.getInstance(this).registerReceiver(...);
in the onReceive(...) method of your receiver, update the required data and unregister it in Activity's onDestroy() method, again using the LocalBroadcastManager object.
Needless to say, you send the broadcast signal from your Service's onLocationChanged(...) method, since it is in the same package as your Activity, the LocalBroadcastManager will forward the signal to your Activity.
LocalBroadcastManager.getInstance(this).sendBroadcast(...);

NMEA location Listener Killed

I have been trying to develop Location listener using NMEANListener in android.
I have a main activity which has start button. Clicking on start button initializes the locationManager and NMEAListener.
After this I get notifications in
public void onNmeaReceived(long arg0, String arg1)
However after some time my NMEAListener is removed by android.
My Mainactivity.java class has following instances declared
private LocationManager locManager = null;
private TextView output = null;
private NMEAMessageListener nmeaMessageListener = null;
I initialize the listener in Main activity class on click of button
nmeaMessageListener = new NMEAMessageListener();
locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 60000,100,nmeaMessageListener);
Location location=locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Please let me know as the reason for Listener being removed by android.
Is there a better way of doing it. I want to keep my location listener running for long time.
Shall i use intentservice to start NMEANListener.
Any help will be appreciated.
If you want to listen for location changes while your app is in background, then put your location listener inside Service. The fact that your listener is removed, is becaus Android is more likely to kill your app while it is in background. If you really want your service to survive low memory conditon, then add notification to is and make if foreground (call setForeground).
IntentService is more suited for single but longer tasks, it provides you with function that will perform task you want to perform in background and after it finished service will probably be finished. This makes it not appropriate for the location listener.
If location listener is implemented in Activity, then you probably remove it yourself inside onStop which is called once Activity is hidden.
Here is example SO: Background service with location listener in android

Categories

Resources