I have a service checking for location updates I am confused in requesting location updates! Should I have to call requestLocationUpdates() in onCreate() of the service or i
Here is my code that worked for me!
Don't forget to add mgoogleApiClient.connect()
in onCreate()
and then take a look at the onConnected Method of googleapiClient - here I've created the the LocationRequest with
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, mLocationRequest, this);
and then for testing I used
LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
for the initial Request.
If you are using emulator don't forget to telnet localhost 5543 (to your emulator) and then use the command geo fix to set the initial location. You can test it with geofixing to another location then the onLocationChanged Methode should be called ...
package com.pekam.androidservice;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.pekam.myandroidtheme.*;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.location.*;
import com.google.android.gms.location.LocationListener;
public class MyService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener {
private NotificationManager nm;
private Timer timer = new Timer();
private int counter = 0;
private int incrementby = 1;
private static boolean isRunning = false;
private GoogleApiClient googleApiClient;
private LocationRequest mLocationRequest = new LocationRequest();
private String strLOG="LOG";
ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
int mValue = 0; // Holds last value set by a client.
static final int MSG_REGISTER_CLIENT = 1;
static final int MSG_UNREGISTER_CLIENT = 2;
static final int MSG_SET_INT_VALUE = 3;
static final int MSG_SET_STRING_VALUE = 4;
static final int MSG_SET_STRING_LOG =5;
final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.
// LocationRequest
@Override
public void onLocationChanged(Location location) {
Location mCurrentLocation = location;
sendLogMessageToUI("Last Known Loc" + mCurrentLocation.getLongitude() + mCurrentLocation.getLatitude());
}
//GoogleApiClient
@Override
public void onConnectionFailed(ConnectionResult bundle) {
}
@Override
public void onConnected(Bundle bundle) {
Log.i("onConnected", "GoogleApiClient" );
try {
Toast.makeText(this, "Location service connected", Toast.LENGTH_SHORT).show();
createLocationRequest();
LocationServices.FusedLocationApi.requestLocationUpdates(
googleApiClient, mLocationRequest, this);
LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
} catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
Log.e("Google APi Connected", "Google APi Connected Failed.", t);
}
}
@Override
public void onConnectionSuspended(int i) {
}
//Service
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService", "Service Started.");
showNotification();
timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 1900L);
isRunning = true;
try {
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("MyService", "Received start id " + startId + ": " + intent);
return START_STICKY; // run until explicitly stopped.
}
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
public static boolean isRunning()
{
return isRunning;
}
private void onTimerTick() {
Log.i("TimerTick", "Timer doing work." + counter);
try {
counter += incrementby;
sendMessageToUI(counter);
// LocationServices.FusedLocationApi.setMockMode(googleApiClient, true);
// double latitude = LocationServices.FusedLocationApi.getLastLocation(googleApiClient).getLatitude();
} catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
Log.e("TimerTick", "Timer Tick Failed.", t);
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
//GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
private void showNotification() {
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TabBarActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
// Send the notification.
// We use a layout id because it is a unique number. We use it later to cancel.
nm.notify(R.string.service_started, notification);
}
protected void createLocationRequest() {
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void sendMessageToUI(int intvaluetosend) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
// Send data as an Integer
mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));
//Send data as a String
Bundle b = new Bundle();
b.putString("str1", "ab" + intvaluetosend + "cd");
Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
// The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
private void sendLogMessageToUI(String strLOG) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
// Send data as an Integer
mClients.get(i).send(Message.obtain());
//Send data as a String
Bundle b = new Bundle();
b.putString("strLOG", strLOG);
Message msg = Message.obtain(null, MSG_SET_STRING_LOG);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
// The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
class IncomingHandler extends Handler { // Handler of incoming messages from clients.
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_SET_INT_VALUE:
incrementby = msg.arg1;
break;
default:
super.handleMessage(msg);
}
}
}
}