为啥LocationListener会在一段时间后禁用?
Posted
技术标签:
【中文标题】为啥LocationListener会在一段时间后禁用?【英文标题】:Why does LocationListener become disable after a while?为什么LocationListener会在一段时间后禁用? 【发布时间】:2013-12-21 08:03:46 【问题描述】:我编写了一个位置监听器类,它注册了 30000 毫秒和 100 米的更新。它将数据收集到sharedPreferences
10 分钟,然后发送整个数据并清除共享密钥。
但是他们说应用程序不会在 2.3 小时后发送数据?该应用程序在后台运行,不是服务。代码如下:
MainActivity.class
LocManager locMan= null;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
locMan = new LocManager(MainActivity.this);
LocationManager.java
public class LocManager implements LocationListener
Context cnx;
String glbData = "";
LocationManager manager = null;
public boolean sendOnly1Record = false;
public int saveUserApplicationStatusCalled = 0;
Date firstDate = null;
Date currDate = null;
String USR_ID = "", USR_PASSWORD = "", USR_DOMAIN = "";
private boolean isUploadingNow = false;
public LocManager(Context cnx)
this.cnx = cnx;
manager = (LocationManager) this.cnx
.getSystemService(Context.LOCATION_SERVICE);
SharedPreferences sh = cnx.getSharedPreferences(Constants.SH_GLB_DATA,
Context.MODE_PRIVATE);
glbData = sh.getString(Constants.SH_GLB_KEY, "");
USR_ID = sh.getString(Constants.SH_USR_ID_KEY, "nil");
USR_PASSWORD = sh.getString(Constants.SH_USR_PASS_KEY, "nil");
USR_DOMAIN = sh.getString(Constants.SH_USR_DOMAIN_KEY, "nil");
firstDate = new Date();
public void startUpdate()
Criteria myCriteria = new Criteria();
myCriteria.setAccuracy(Criteria.ACCURACY_FINE);
myCriteria.setPowerRequirement(Criteria.POWER_LOW);
String myProvider = manager.getBestProvider(myCriteria, true);
long minTimeMillis = 30000;
manager.requestLocationUpdates(myProvider, minTimeMillis, 100, this);
@Override
public void onLocationChanged(Location location)
if (sendOnly1Record)
sendOnly1Record = false;
funcSendOnly1Record(location);
else if (!isUploadingNow)
String str_date = getCurrentStrDate();
String str_battery_level = "" + getBatteryLevel();
String str_lat = "" + location.getLatitude();
String str_lon = "" + location.getLongitude();
long interval = getDateDiffsinMinutes();
if (interval > 10)
isUploadingNow = true;
postData();
firstDate = new Date();
else
StringBuffer buf = new StringBuffer();
buf.append(str_date);
buf.append("|");
buf.append(str_lat);
buf.append("|");
buf.append(str_lon);
buf.append("|");
buf.append(str_battery_level);
buf.append("|");
buf.append("" + saveUserApplicationStatusCalled);
buf.append("|");
glbData = glbData + buf.toString();
SharedPreferences sh = cnx.getSharedPreferences(
Constants.SH_GLB_DATA, Context.MODE_PRIVATE);
SharedPreferences.Editor ed = sh.edit();
ed.putString(Constants.SH_GLB_KEY, glbData);
ed.commit();
if (saveUserApplicationStatusCalled == 0)
saveUserApplicationStatusCalled = 1;
@Override
public void onProviderDisabled(String provider)
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
private void postData()
//Posts the collected data
;
public void funcSendOnly1Record(Location location)
String str_date = getCurrentStrDate();
String str_battery_level = "" + getBatteryLevel();
String str_lat = "" + location.getLatitude();
String str_lon = "" + location.getLongitude();
StringBuffer buf = new StringBuffer();
buf.append(str_date);
buf.append("|");
buf.append(str_lat);
buf.append("|");
buf.append(str_lon);
buf.append("|");
buf.append(str_battery_level);
buf.append("|");
buf.append("" + saveUserApplicationStatusCalled);
buf.append("|");
//post one data
private int getBatteryLevel()
Intent batteryIntent = cnx.registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
// Error checking that probably isn't needed but I added just in case.
if (level == -1 || scale == -1)
return 50;
float x = ((float) level / (float) scale) * 100.0f;
return (int) x;
private long getDateDiffsinMinutes()
currDate = new Date();
long result = ((currDate.getTime() / 60000) - (firstDate.getTime() / 60000));
return (int) result;
private String getCurrentStrDate()
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = new Date();
String str_date = dateFormat.format(date);
return str_date;
【问题讨论】:
您尝试过新的融合位置提供者 api 吗? developer.android.com/google/play-services/location.html 我看到了,但我没有尝试。我的客户也使用 2.3(我知道它支持 2.2,但我的代码也应该可以工作) 【参考方案1】:您的后台进程正在被终止,以便为其他应用程序释放内存。这是完全正常的预期行为。
【讨论】:
那我应该把它转换成服务吗? @WinstonSmith 是的,但在极端情况下甚至可以杀死服务以节省内存。 @twntee 感谢您的反馈。您如何看待新的位置 API。我在文档中没有看到任何关于终止服务的信息。developer.android.com/google/play-services/location.html以上是关于为啥LocationListener会在一段时间后禁用?的主要内容,如果未能解决你的问题,请参考以下文章