Question

I am trying to bound a service to my activity and get location values from it.

I have the following service:

GPSService.java

public class GPSService extends SensorElement {

    // Binder given to clients
    private final IBinder mBinder = new LocalBinder();

    /**
     * Class used for the client Binder. Because we know this service always
     * runs in the same process as its clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        public GPSService getService() {
            // Return this instance of GPSService so clients can call public
            // methods
            return GPSService.this;
        }
    }

    private static final String TAG = "GPSServive";
    private LocationManager mLocationManager = null;
    private static final int LOCATION_INTERVAL = 1000;
    private static final float LOCATION_DISTANCE = 10f;

    private Location location;
    private boolean canGetLocation;
    private double latitude;
    private double longitude;
    private double accuracy;
    private long timestamp;

    public SensorType type = SensorType.SOFTWARE_SENSOR;
    public SensorName name = SensorName.GPS_SENSOR;

    private class LocationListener implements android.location.LocationListener {
        Location mLastLocation;

        public LocationListener(String provider) {
            Log.e(TAG, "LocationListener " + provider);
            mLastLocation = new Location(provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.e(TAG, "onLocationChanged: " + location);
            mLastLocation.set(location);
        }

        @Override
        public void onProviderDisabled(String provider) {
            Log.e(TAG, "onProviderDisabled: " + provider);
        }

        @Override
        public void onProviderEnabled(String provider) {
            Log.e(TAG, "onProviderEnabled: " + provider);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.e(TAG, "onStatusChanged: " + provider);
        }
    }

    LocationListener[] mLocationListeners = new LocationListener[] {
            new LocationListener(LocationManager.GPS_PROVIDER),
            new LocationListener(LocationManager.NETWORK_PROVIDER) };

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        super.onStartCommand(intent, flags, startId);
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Log.e(TAG, "onCreate");
        initializeLocationManager();
        if (!isNetworkAvailable() && !isGPSAvailable()) {
            // no network provider is enabled
            setCanGetLocation(false);
        } else if (isNetworkAvailable()){
            setCanGetLocation(true);
            try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL,
                        LOCATION_DISTANCE, mLocationListeners[1]);

                location = mLocationManager
                        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    accuracy = location.getAccuracy();
                    timestamp = System.currentTimeMillis();
                }
            } catch (java.lang.SecurityException ex) {
                Log.i(TAG, "fail to request location update, ignore", ex);
            } catch (IllegalArgumentException ex) {
                Log.d(TAG, "gps provider does not exist " + ex.getMessage());
            }
        } else if (isGPSAvailable()) {
            setCanGetLocation(true);
            try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, LOCATION_INTERVAL,
                        LOCATION_DISTANCE, mLocationListeners[0]);
                location = mLocationManager
                        .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                if (location != null) {
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    accuracy = location.getAccuracy();
                    timestamp = System.currentTimeMillis();
                }
            } catch (java.lang.SecurityException ex) {
                Log.i(TAG, "fail to request location update, ignore", ex);
            } catch (IllegalArgumentException ex) {
                Log.d(TAG,
                        "network provider does not exist, " + ex.getMessage());
            }
        }
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
        if (mLocationManager != null) {
            for (int i = 0; i < mLocationListeners.length; i++) {
                try {
                    mLocationManager.removeUpdates(mLocationListeners[i]);
                } catch (Exception ex) {
                    Log.i(TAG, "fail to remove location listners, ignore", ex);
                }
            }
        }
    }

    private void initializeLocationManager() {
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext()
                    .getSystemService(Context.LOCATION_SERVICE);
        }
    }

    private boolean isNetworkAvailable() {
        return mLocationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    }

    private boolean isGPSAvailable() {
        return mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    public double getLatitude() {
        return latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public double getAccuracy() {
        return accuracy;
    }

    public long getTimestamp() {
        return timestamp;
    }

    public SensorType getType() {
        return type;
    }

    public void setType(SensorType type) {
        this.type = type;
    }

    public SensorName getName() {
        return name;
    }

    public void setName(SensorName name) {
        this.name = name;
    }

    public boolean isCanGetLocation() {
        return canGetLocation;
    }

    public void setCanGetLocation(boolean canGetLocation) {
        this.canGetLocation = canGetLocation;
    }
}

This is the abstract class that the GPSService extends. The goal for this is to have something that generalizes a sensor, gps sensor accelerometer sensor, whatever sensor.

SensorElement.java

public abstract class SensorElement extends Service{

    protected SensorType type;
    protected SensorName name;

    @Override
    public abstract IBinder onBind(Intent arg0);

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public abstract void onCreate();

    @Override
    public void onDestroy(){
        super.onDestroy();
    }
}

Now i have my activity that is trying to bind to the GPSService. InSituApp.java

public class InSituApp extends Activity{

GPSService gpsService;
boolean mBound = false;
public Button buttonGPS;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    startService(new Intent(this, GPSService.class));
    //startService(new Intent(this, MyService.class));

// buttonGPS = (Button) findViewById(R.id.button1); }

@Override
protected void onStart() {
    super.onStart();
    System.out.println("ENTERED IN ONSTART");
    // Bind to GPSService
    Intent intent = new Intent(this, GPSService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}

@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}

/** Called when a button is clicked (the button in the layout file attaches to
  * this method with the android:onClick attribute) */
public void onButtonClick(View v) {
    System.out.println("DIDNT ENTERED IN BOUND");
    if (mBound) {
        // Call a method from the LocalService.
        // However, if this call were something that might hang, then this request should
        // occur in a separate thread to avoid slowing down the activity performance.
        System.out.println("ENTERED IN BOUND");
        double latitude = gpsService.getLatitude();
        double longitude = gpsService.getLongitude();
        double accuracy = gpsService.getAccuracy();
        long timestamp = gpsService.getTimestamp();
        Toast.makeText(this, "latitude: " + latitude, Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "longitude: " + longitude, Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "accuracy: " + accuracy, Toast.LENGTH_SHORT).show();
        Toast.makeText(this, "timestamp: " + timestamp, Toast.LENGTH_SHORT).show();
    }
}

/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to LocalService, cast the IBinder and get LocalService instance
        System.out.println("ENTERED IN ONSERVICE CONNECTED");
        LocalBinder binder = (LocalBinder) service;
        gpsService = binder.getService();
        System.out.println("GPSService: "+gpsService!=null);
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
        System.out.println("ENTERED IN ONSERVICE DISCONNECTED");
    }
};

}

This code never calls the onServiceConnected method inside mConnection. What is wrong in here? The bindService call in onStart returns false. Why is that?

EDIT:

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="main.inSituApp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="main.inSituApp.InSituApp" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".GPSService" />
        <service android:name=".FileObservingService" />
    </application>

</manifest>
Was it helpful?

Solution

I found the solution.

The problem is in the manifest file where the service must be the total path of the package.

in my case sensors.GPSService

Hope it helps someone

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top