我在一开始就大声道歉,因为我知道回答这个问题就像将jello钉在墙上一样。我将尽可能多地提供详细信息,但没有太多可以给予。
我正在开发一款Blackberry应用程序,它使用GPS每隔xx分钟获取一个用户的位置(可能是15,30或60,具体取决于用户设置的偏好);它将位置数据发送到Web服务。
它运行正常并报告用户的位置正常,但只有大约16-18小时,然后应用程序停止报告,用户界面不再有效。不会抛出任何错误,它只会在重新启动应用程序之前不再响应用户选择。
对我来说很奇怪,应用程序崩溃是相当可预测的 - 它在8小时或10小时之后永远不会崩溃,它总是在16-18小时的窗口中,这告诉我崩溃与GPS / WebService报告。
基本上,如果我从GPS / WebService的角度来看,看起来应用程序可以设法向WebService报告36次(每半小时18小时),然后它就会死亡。
我会在这里发布一些代码,希望能引发某人的想法。
private void updateGPSLocation(){
gps_interval_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
try{
getGPSLocation();
if(longitude != 0.0 && latitude != 0.0)
{
updateSubscriberLocation();
}
}catch(Exception ex){
}
}
}, 0, gps_interval);
}
这是上一代码中引用的getGPSLocation()调用的代码:
public void getGPSLocation(){
try{
//GPS thread
BlackBerryLocationProvider provider = (BlackBerryLocationProvider)LocationProvider.getInstance(new BlackBerryCriteria(GPSInfo.GPS_MODE_ASSIST));
//geolocation thread
BlackBerryLocationProvider provider1 = (BlackBerryLocationProvider)LocationProvider.getInstance(new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE_CELL));
if (provider != null){
provider.setLocationListener(new LocationListenerImpl(), _interval, 1, 1);
}
if(provider1 != null){
provider1.setLocationListener(new LocationListenerImpl(), _interval, 1, 1);
}
}
catch(Exception le){
}
}
再次,对不起,我知道这是一个开放式的问题。 Blackberry GPS有任何已知问题吗?因为我正在使用计时器任务来安排基于时间间隔的报告,我是否可能通过将预定的计时器任务放入队列来吸收所有可用内存?我是否需要使用cancel()方法显式处理计时器任务?类似的东西:
gps_interval_timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
try{
getGPSLocation();
if(longitude != 0.0 && latitude != 0.0)
{
updateSubscriberLocation();
}
}catch(Exception ex){
}
finally
{
this.cancel();
}
}
}, 0, gps_interval);
非常感谢任何帮助。谢谢!
使用LocationListener代码更新
private class LocationListenerImpl implements LocationListener {
public void locationUpdated(LocationProvider provider, Location location) {
if(location.isValid()) {
longitude = location.getQualifiedCoordinates().getLongitude();
latitude = location.getQualifiedCoordinates().getLatitude();
}
}
public void providerStateChanged(LocationProvider provider, int newState) {
}
}
getGPSLocation()中使用的_interval变量设置为-1。
答案 0 :(得分:1)
我认为您需要重新考虑代码。您正在使用计时器以gps_interval指定的速率创建BlackBerryLocationProvider,该速率将以_interval指定的速率获取位置,并调用LocationListenerImpl的locationUpdated()方法(您为每个BlackBerryLocationProvider创建新方法。至少存在两个潜在问题这里:
调用setLocationListener()有一个interval参数的原因之一是支持你想要做的事情,即定期提供一个位置。使用此功能可让操作系统更智能地处理GPS如何处理GPS,如果使用不当,这将是一个重要的电池消耗。
因此,当您需要位置时,请创建提供程序,为您指定侦听器所需的时间间隔,然后处理侦听器中的位置。确保在单独的线程上连接到后端Web服务。如果停止等待服务器响应的事件线程,则会给系统带来更多麻烦。
编辑:
这可能是getGPSLocation()的一个实现,可以满足您的需求。它将尝试一组标准,然后是另一组标准。它仍然依赖于间隔的计时器,但不使用位置提供程序的间隔/回调属性。由于它没有注册监听器,一旦提供者超出范围,它将受到垃圾收集。
public void getGPSLocation(){
try{
//GPS thread
BlackBerryLocationProvider provider =
(BlackBerryLocationProvider)LocationProvider.getInstance(
new BlackBerryCriteria(GPSInfo.GPS_MODE_ASSIST));
if (provider != null){
try {
Location location = provider.getLocation(timeout);
// process location
return;
} catch (LocationException le) {
} catch (Exception e) {
}
}
provider =
(BlackBerryLocationProvider)LocationProvider.getInstance(
new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE_CELL));
if (provider != null){
try {
Location location = provider.getLocation(timeout);
// process location
} catch (LocationException le) {
} catch (Exception e) {
}
}
}
catch(Exception le){
}
}
说过更好的方法可能是用(来自API文档)替换updateGPSPosition和getGPSPositioin:
public void updateGPSPosition() {
BlackBerryCriteria bbCriteria;
BlackBerryLocationProvider bbProvider;
try { //setup Criteria
bbCriteria = new BlackBerryCriteria()); // use default mode on the device
bbCriteria.enableGeolocationWithGPS(); // retrieve geolocation fix if GPS fix unavailable
} catch (UnsupportedOperationException uoe) {}
try { //setup LocationProvider
bbProvider = (BlackBerryLocationProvider)LocationProvider.getInstance(bbCriteria);
bbprovider.setLocationListener(new LocationListenerImpl(), interval, timeout, maxage);
} catch (LocationException le) {}
}
您可能希望将bbCriteria和bbProvider保存在以后可以更改间隔的位置,或者只是停止获取位置。
很难找到在providerStateChanged()内部做什么这是我通常使用的:
public void providerStateChanged(LocationProvider provider, int newState) {
if (newState == LocationProvider.TEMPORARILY_UNAVAILABLE)
{
if (unavailableCount < 3) {
System.err.println("TEMPORARILY_UNAVAILABLE Reset " + Integer.toString(unavailableCount));
// de-register listener, reset the provider and re-register
locationProvider.setLocationListener(null, -1, -1, -1);
locationProvider.reset();
locationProvider.setLocationListener(this, 1, -1, -1);
unavailableCount++;
} else {
System.err.println("TEMPORARILY_UNAVAILABLE Suspend");
locationProvider.setLocationListener(null, -1, -1, -1);
}
}
else if (newState == LocationProvider.AVAILABLE)
{
unavailableCount = 0;
}
else {
System.err.println("OUT_OF_SERVICE");
locationProvider.setLocationListener(null, -1, -1, -1);
}
}