为啥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会在一段时间后禁用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥托管在 Windows 服务内的 WCF 服务会在一段时间后死掉

为啥实体框架会在一段时间后忘记我的数据库模型中的内容?

Chromecast 视频播放会在一段时间后永远挂起

我的领域文件会在一段时间后自动清除所有数据

为啥我们应该让帐户激活/密码重置链接在一段时间后过期?

为啥 Jprofiler 9.11 在一段时间后停止进行分析(CPU 视图 - 热点)?