永远不会调用绑定服务中的android onServiceConnected

时间:2014-03-07 14:52:37

标签: android service android-service-binding

我正在尝试将服务绑定到我的活动并从中获取位置值。

我有以下服务:

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;
    }
}

这是GPSService扩展的抽象类。这样做的目标是拥有能够推广传感器,gps传感器加速度计传感器,无论传感器的东西。

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();
    }
}

现在我的活动正在尝试绑定到GPSService。 InSituApp.java

公共类InSituApp扩展了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");
    }
};

}

此代码从不调用onServiceConnected中的mConnection方法。这里有什么问题? onStart中的bindService调用返回false。那是为什么?

编辑:

的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>

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。

问题出在清单文件中,其中服务必须是包的总路径。

在我的案例中是sensors.GPSService

希望它有助于某人