用于GPS更新的Android服务

时间:2013-07-11 20:32:49

标签: android service gps

我正在尝试编写一个简单的应用程序,它可以从GPS接收位置信息并在地图上绘制点。我写了一个GPS处理服务,但我在一个活动中使用它时遇到了麻烦 - 我无法获得纬度/经度/高度的值。

服务似乎正常启动(GPS在手机上启动并获得修复)但是当我尝试检索坐标时(通过按下Activity中的按钮来调用相关方法)应用程序崩溃并且我得到了一个java.lang LogCat中的.NullPointerException错误。

我在Stack Overflow和其他网站上看了很多例子,但我是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;
    }
}

}

3 个答案:

答案 0 :(得分:0)

要获取服务实例,您需要将服务与活动绑定。请查看以下链接:

http://developer.android.com/guide/components/bound-services.html http://dharmendra4android.blogspot.mx/2012/05/bind-service-using-ibinder-class.html

如果你需要帮助,请告诉我。

答案 1 :(得分:0)

您声明location但从未实例化它。 在onLocationChanged

执行此操作
if (location.hasAccuracy()) {
                    //save location in the private variable:
                    this.location = location;
                }  

答案 2 :(得分: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正常工作!!

你可能已经注意到我的英语不是很好,我希望你理解