【问题标题】:Codename One: Background Location Listener not firing on Android Lollipop代号一:Android Lollipop 上的后台位置侦听器未触发
【发布时间】:2016-05-18 12:39:35
【问题描述】:

我正在构建一个应用程序,该应用程序应定期捕获用户的位置(我每 60 分钟查找一次),跟踪他们访问过的城市。

我首先开始使用前台位置侦听器,它非常完美,它似乎每隔几分钟就会触发一次,但我已经进行了检查,以便它仅在经过足够的时间后才真正跟踪位置。当我切换到其他应用程序时,看起来前台侦听器将继续触发一段时间,然后停止触发,这对我来说是有道理的,因为我认为操作系统正在后台处理应用程序。此时,我希望后台侦听器已注册并在该侦听器被触发时唤醒应用程序。

关于我的问题...我在使用后台位置监听器时遇到了问题。我知道它不会在模拟器上触发,但是当我为我的设备构建调试(使用内置证书)时它也不会触发。为了这个问题,我根据此处列出的示例将我的应用程序正在做的事情提炼成准系统:https://gist.github.com/shannah/86c739edac34216d3c4d

为了确保我尝试将后台侦听器切换到标准前台侦听器 (.setLocationListener(new BackgroundListener())),并在模拟器上运行,我可以验证我的标签是否已使用适当的数据进行更新。

我还对我的实际应用程序进行了一些测试,我会在无参数构造函数中弹出一个对话框来说明侦听器已初始化,并在调用 locationUpdated 时弹出另一个对话框。我能够在 init 上看到弹出窗口,但 locationUpdated 上没有对话框,这让我相信我的设备从未触发过它。

我正在测试的设备是搭载 Android 5.0.1 (Lollipop) 的三星 S4。

这是我编写的测试应用程序,它非常模仿我的实际应用程序正在做的事情。

bglocation.java

package com.bglocation;


import java.util.List;

import com.codename1.io.Storage;
import com.codename1.location.LocationManager;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;

/**
 * This file was generated by <a href="https://www.codenameone.com/">Codename One</a> for the purpose 
 * of building native mobile applications using Java.
 */
public class bglocation {
    private Form current;
    private Resources theme;

    public void init(Object context) {
        theme = UIManager.initFirstTheme("/theme");
    }

    public void start() {
        if(current != null){
            current.show();
            return;
        }
        Form hi = new Form("Hi World");


        LocationManager.getLocationManager().setBackgroundLocationListener(BackgroundLocationListener.class);

        String lastCheckin = (String)Storage.getInstance().readObject("LOCATION");

        String label = "No checkins.";
        if (lastCheckin != null) {
            label = lastCheckin;
        }

        Label hiLabel = new Label("Last checkin: " + label);
        hi.addComponent(hiLabel);
        hi.show();
    }

    public void stop() {
        current = Display.getInstance().getCurrent();
    }

    public void destroy() {
    }
}

BackgroundLocationListener.java

package com.bglocation;

import java.util.Date;

import com.codename1.io.Storage;
import com.codename1.location.Location;
import com.codename1.location.LocationListener;

public class BackgroundLocationListener implements LocationListener {

    @Override
    public void locationUpdated(Location location) {
        Storage.getInstance().writeObject("LOCATION", new Date().toString());
    }

    @Override
    public void providerStateChanged(int newState) { }
}

【问题讨论】:

    标签: codenameone


    【解决方案1】:

    一旦位置发生重大变化,就会调用后台侦听器,它也在完全不同的进程上运行,因此您实际上并没有 UI 或访问应用程序实例的权限。 与您的应用程序通信所需要做的是触发本地通知或启动意图或将位置存储到文件或数据库中,一旦您的应用程序启动,就会从那里获取数据。

    【讨论】:

    • 你能定义显着的位置变化吗?另外,我可以在哪里存储收到的数据有任何限制吗?我打算使用 Storage 类在它为我的应用程序存储文件的任何位置的根目录中写入文件,所以我假设监听器和我的应用程序都可以访问它。
    • 在 Android 上,后台请求被定义为 10 秒间隔和 50 米变化,在 iOS 上,它被映射到重要的位置变化回调,这意味着当设备检测到设备关联的蜂窝塔发生变化时跨度>
    • 我在原始帖子中更新了我的示例,这样监听器现在只会写入存储,并且在 start()(每次应用程序取消挂起时都会调用)我从同一个位置读取,它仍然无法正常工作,请您帮忙吗?我创建了一个新版本并将其推送到我的设备,我确保该应用程序一整天都没有停止(通过按住主页按钮显示正在运行的应用程序进行验证)。我今天打开了 3 次应用程序:上班前、上班时(约 15 公里外),然后在我回家时再次打开,即使我强制退出/重新打开,标签也没有更新。跨度>
    • 嗨@Chen,任何帮助将不胜感激,我完全不知道为什么它不起作用。
    • 原来是由旧的 Android 错误 (code.google.com/p/android/issues/detail?id=81812) 引起的框架中的错误导致了该问题。 Chen 此后将更改添加到 CN1 框架中,并且一切都按预期工作。
    猜你喜欢
    • 2012-08-26
    • 2015-12-27
    • 2020-08-27
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2016-12-29
    • 1970-01-01
    相关资源
    最近更新 更多