Why can't I call this Service from my Activity?

194 views Asked by At

I've tried calling this Service in two different ways, but it didn't seem to work.

The first way was:

startService(new Intent(getBaseContext(), LocationService.class));

for which I get an error saying `

Caused by: `java.lang.IllegalStateException: GoogleApiClient is not connected yet.

Then I tried this:

Intent serviceIntent = new Intent();
                serviceIntent.setAction("com.parseapp.eseen.eseen.service.LocationService");
                startService(serviceIntent);

Also it didn't work, in contrary absolutely nothing happens, nothing shows up in logcat. Can anyone help? Here's the whole code:

LocationService.class

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener, LocationListener {

// LogCat tag
private static final String TAG = LocationService.class.getSimpleName();

private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;

private Location mLastLocation;

// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;

// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;

private LocationRequest mLocationRequest;

// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters


@Override
public void onCreate() {
    super.onCreate();

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();


}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (mGoogleApiClient != null) {
        mGoogleApiClient.connect();
        togglePeriodicLocationUpdates();
    }



    return START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FATEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

private void togglePeriodicLocationUpdates() {
    mGoogleApiClient.connect();

    if (!mRequestingLocationUpdates) {

        mRequestingLocationUpdates = true;

        startLocationUpdates();

        Log.d(TAG, "Periodic location updates started!");

    } else {

        mRequestingLocationUpdates = false;

        // Stopping the location updates
        stopLocationUpdates();

        Log.d(TAG, "Periodic location updates stopped!");
    }
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

protected void startLocationUpdates() {
    mGoogleApiClient.connect();
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);

}

@Override
public void onConnected(Bundle arg0) {
    createLocationRequest();
}

@Override
public void onConnectionSuspended(int arg0) {
    mGoogleApiClient.connect();
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
            + result.getErrorCode());
}

@Override
public void onLocationChanged(Location location) {
    // Assign the new location
    mLastLocation = location;

    Toast.makeText(getApplicationContext(), "Location changed!",
            Toast.LENGTH_SHORT).show();
}

@Override
public boolean stopService(Intent name) {
    return super.stopService(name);
}

SearchActivity.class

button = (Button)findViewById(R.id.buttonPressed);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent serviceIntent = new Intent();
            serviceIntent.setAction("com.parseapp.eseen.eseen.service.LocationService");
            startService(serviceIntent);
        }
    });

AndroidManifest.xml

<service android:name=".LocationService">

        <intent-filter>
            <action android:name=".LocationService"> </action>
        </intent-filter>

    </service>

   
2

There are 2 answers

4
Bob Snyder On BEST ANSWER

Your first attempt to start the service using the class name worked:

startService(new Intent(getBaseContext(), LocationService.class));

The exception occurred after the service started executing. Your code cannot use LocationServices until the GoogleApi connection is successful, namely after onConnected() is called. Your code calls connect() multiple times before getting to startLocationUpdates(), but does not wait for onConnected() to be called. That method is the notification you receive when the connection has been made and LocationServices can be used.

This demo code is for an AsyncTask, not a Service, but gives an idea of how the connection processing can be done using a CountDownLatch.

3
praveen On

you package name com.parseapp.eseen.eseen and You are tryng to call using com.parseapp.eseen.eseen.service.LocationService as action but you mentioned in Manifest as .LocationService that means you should call using com.parseapp.eseen.eseen.LocationService

in startLocationUpdates(); you are calling connect again and requesting api before connecting request for locationupdates from onConnected method LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient, mLocationRequest, this);