2013-07-11 23 views
0

我正在嘗試編寫一個簡單的應用程序,用於接收來自GPS的位置信息並繪製地圖上的點。我爲GPS處理編寫了一項服務,但我在使用它時遇到了問題 - 我無法獲取緯度/經度/高度值。用於GPS更新的Android服務

服務似乎開始正確(GPS在手機上啓動並獲得修復),但是當我嘗試檢索座標時(通過按下Activity中的按鈕調用相關方法),應用程序崩潰,我得到一個java。 LogCat中的lang.NullPointerException錯誤。

我已經看過堆棧溢出和其他網站上的很多例子,但我是新來的Android開發,我不知道我做錯了什麼。我會非常感謝任何建議。

服務:

public class TrackingService extends Service { 
private LocationManager SgpstLocationManager; 
private LocationListener spgstLocationListener; 

private static long minimumDistanceBwUpdates = 10; //10 metres 
private static long minimumTimeBwUpdates = 3000; //3 seconds 

static Location location; 

private void startTrackingService() { 
    //location manager declaration 
    SgpstLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

    //location listener declaration 
    spgstLocationListener = new SgpstLocationListener(); 

    //request location updates from location manager 
    SgpstLocationManager.requestLocationUpdates(
      SgpstLocationManager.GPS_PROVIDER, 
      minimumTimeBwUpdates, 
      minimumDistanceBwUpdates, 
      spgstLocationListener); 
} 

private void stopTrackingService() { 
    //remove location updates from location manager 
    SgpstLocationManager.removeUpdates(spgstLocationListener); 
} 

//location listener class 
public class SgpstLocationListener implements LocationListener { 
    public void onLocationChanged(Location location) { 
     if (location != null) { 
      try { 
       if (location.hasAccuracy()) { 
        //retrieve information about a point: 
        location.getLatitude(); 
        location.getLongitude(); 
       }     
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 

    public void onProviderDisabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onProviderEnabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onStatusChanged(String provider, int status, Bundle extras) { 
     //mandatory method - not used 
    } 
} 

//mandatory service methods 
public void onCreate() { 
    super.onCreate(); 
    startTrackingService(); 
} 

public void onDestroy() { 
    super.onDestroy(); 
    stopTrackingService(); 
} 

//methods for interaction with client objects 
private final IBinder sgpstBinder = new LocalBinder(); 

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

public class LocalBinder extends Binder { 
    TrackingService getService() { 
     return TrackingService.this; 
    } 
} 

//get and set methods 
public static void setMinimumDistanceBwUpdates(long distance) { 
    minimumDistanceBwUpdates = distance; 
} 

public static void setMinimumTimeBwUpdates(long time) { 
    minimumTimeBwUpdates = time; 
} 

public static long getMinimumDistanceBwUpdates() { 
    return minimumDistanceBwUpdates; 
} 

public static long getMinimumTimeBwUpdates() { 
    return minimumTimeBwUpdates; 
} 

public static double getMyLatitude() { 
    return location.getAltitude(); 
} 

public static double getMyLongitude() { 
    return location.getLongitude(); 
} 

public static double getMyAltitude() { 
    return location.getAltitude(); 
} 

} 

活動:

public class GPSTestActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_gpstest); 

    startService(new Intent(GPSTestActivity.this, TrackingService.class)); 

    Button updateButton = (Button)findViewById(R.id.update_button); 
    final TextView latitudeText = (TextView)findViewById(R.id.latitude); 
    final TextView longitudeText = (TextView)findViewById(R.id.longitude); 
    final TextView altitudeText = (TextView)findViewById(R.id.altitude); 
    latitudeText.setText("latitude"); 
    longitudeText.setText("longitude"); 
    altitudeText.setText("altitude"); 

    updateButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       latitudeText.setText(String.valueOf(TrackingService.getMyLatitude())); 
       longitudeText.setText(String.valueOf(TrackingService.getMyLongitude())); 
       altitudeText.setText(String.valueOf(TrackingService.getMyAltitude())); 
      } 
    }); 
} 

的幫助非常感謝。我根據您的建議重寫/重構了代碼。我現在收到以下錯誤:

java.lang.RuntimeException: Unable to instantiate activity 
ComponentInfo{com.example.simplegpstracker/com.example.simplegpstracker.GPSTestActivity}: java.lang.NullPointerException 

我會嘗試閱讀服務綁定自己,但任何建議將受到歡迎。

修改代碼:

服務:

public class TrackingService extends Service { 
//fields 
private LocationManager SgpstLocationManager; 
private LocationListener spgstLocationListener; 

private static long minimumDistanceBwUpdates = 10; //10 metres 
private static long minimumTimeBwUpdates = 3000; //3 seconds 

static Location myLocation; 

private void startTrackingService() { 
    //location manager declaration 
    SgpstLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

    //location listener declaration 
    spgstLocationListener = new SgpstLocationListener(); 

    //request location updates from location manager 
    SgpstLocationManager.requestLocationUpdates(
      SgpstLocationManager.GPS_PROVIDER, 
      minimumTimeBwUpdates, 
      minimumDistanceBwUpdates, 
      spgstLocationListener); 
} 

private void stopTrackingService() { 
    //remove location updates from location manager 
    SgpstLocationManager.removeUpdates(spgstLocationListener); 
} 

//location listener class 
public class SgpstLocationListener implements LocationListener { 
    public void onLocationChanged(Location location) { 
     if (location != null) { 
      try { 
       if (location.hasAccuracy()) { 
        //retrieve information about a point: 
        myLocation = location; 
       }     
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 

    public void onProviderDisabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onProviderEnabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onStatusChanged(String provider, int status, Bundle extras) { 
     //mandatory method - not used 
    } 
} 

//mandatory service methods 
public void onCreate() { 
    super.onCreate(); 
    startTrackingService(); 
} 

public void onDestroy() { 
    super.onDestroy(); 
    stopTrackingService(); 
} 

//methods for interaction with client objects 
private final IBinder sgpstBinder = new LocalBinder(); 

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

public class LocalBinder extends Binder { 
    TrackingService getService() { 
     return TrackingService.this; 
    } 
} 

//get and set methods 
public static void setMinimumDistanceBwUpdates(long distance) { 
    minimumDistanceBwUpdates = distance; 
} 

public static void setMinimumTimeBwUpdates(long time) { 
    minimumTimeBwUpdates = time; 
} 

public static long getMinimumDistanceBwUpdates() { 
    return minimumDistanceBwUpdates; 
} 

public static long getMinimumTimeBwUpdates() { 
    return minimumTimeBwUpdates; 
} 

public static double getMyLatitude() { 
    return myLocation.getAltitude(); 
} 

public static double getMyLongitude() { 
    return myLocation.getLongitude(); 
} 

public static double getMyAltitude() { 
    return myLocation.getAltitude(); 
} 

} 

活動:

public class GPSTestActivity extends Activity { 

boolean trackingServiceBounded; 
TrackingService trackingService; 
TextView latitudeText = (TextView)findViewById(R.id.latitude); 
TextView longitudeText = (TextView)findViewById(R.id.longitude); 
TextView altitudeText = (TextView)findViewById(R.id.altitude); 
Button updateButton = (Button)findViewById(R.id.update_button); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_gpstest); 

    //startService(new Intent(GPSTestActivity.this, TrackingService.class)); 

    latitudeText.setText("latitude"); 
    longitudeText.setText("longitude"); 
    altitudeText.setText("altitude"); 

    updateButton.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
       latitudeText.setText(String.valueOf(TrackingService.getMyLatitude())); 
       longitudeText.setText(String.valueOf(TrackingService.getMyLongitude())); 
       altitudeText.setText(String.valueOf(TrackingService.getMyAltitude())); 
      } 
    }); 
} 

@Override 
protected void onStart() { 
    super.onStart(); 
    Intent intent = new Intent(this, TrackingService.class); 
    bindService(intent, serviceConnection, BIND_AUTO_CREATE); 
} 

//bind Activity to the Service 
ServiceConnection serviceConnection = new ServiceConnection() { 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     trackingServiceBounded = true; 
     LocalBinder localBinder = (LocalBinder)service; 
     trackingService = localBinder.getService(); 
    } 

    public void onServiceDisconnected(ComponentName name) { 
     trackingServiceBounded = false; 
     trackingService = null; 
    } 
}; 

@Override 
protected void onStop() { 
    super.onStop(); 
    if (trackingServiceBounded) { 
     unbindService(serviceConnection); 
     trackingServiceBounded = false; 
    } 
} 

} 

回答

0

您聲明location但從不實例化它。
在onLocationChange

if (location.hasAccuracy()) { 
        //save location in the private variable: 
        this.location = location; 
       } 
+0

糟糕!斯科特已經回答。 – ramaral

+0

不會'這個。location'是指位置監聽器類(其中onLocationChanged()是一個方法)的一個字段,而不是Service類的一個字段?我試圖重構代碼(請看下面),但它沒有工作,我仍然得到nullPointerException – whtvr

+0

是的,你是對的。 – ramaral

0

這樣做是爲了有一個更清潔的代碼SgpstLocationListener類移動到另一個文件。
如您所願,我會將CurrentLocation重命名爲myLocation。

//location listener class 
public class SgpstLocationListener implements LocationListener { 

    public Location myLocation; //THIS IS WHAT YOU READ IN THE SERVICE 

    public void onLocationChanged(Location location) { 
     if (location != null) { 
      try { 
       if (location.hasAccuracy()) { 
        //retrieve information about a point: 
        myLocation = location; //SET TO THE CURRENT POSITION 
       }     
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 

     } 
    } 

    public void onProviderDisabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onProviderEnabled(String provider) { 
     //mandatory method - not used 
    } 

    public void onStatusChanged(String provider, int status, Bundle extras) { 
     //mandatory method - not used 
    } 
} 

在服務上使用該得到緯度從SgpstLocationListener

public static double getMyLatitude() { 

     return spgstLocationListener.myLocation.getLatitude(); 
    } 

在進行之前,你必須確保GPS工作正常!

正如你可能已經注意到我的英語不是很好,我希望你能理解