2014-03-07 30 views
0

我正在嘗試將服務綁定到我的活動並從中獲取位置值。android onServiceConnected在綁定服務中永遠不會調用

我有以下服務:

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延伸活動{

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 =(按鈕)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"); 
    } 
}; 

}

此代碼永遠不會調用內部mConnectiononServiceConnected方法。這裏有什麼問題? 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> 
+0

請上傳清單文件。你有沒有看看你的android日誌? Manifest中定義的服務是什麼? – RaphMclee

+0

如果您稍後要調用'bindService',則不需要調用'startService',尤其是因爲您要求'bindService'根據需要自動創建該服務。檢查'bindService'的返回值,它會告訴你綁定是否發生。檢查你的清單,你需要聲明你的服務才能使綁定工作。 –

+0

我打電話startService,如果我希望它運行indefeinely和bindService返回false。 Manifest現在被添加。 – JoaoFilipeClementeMartins

回答

0

我找到了解決辦法。

問題在於清單文件中服務必須是軟件包的總路徑。

在我的情況sensors.GPSService

希望它可以幫助別人

相關問題