融合位置有时会STOPS

时间:2014-04-30 07:53:34

标签: android google-maps gps location google-play-services

我一直在研究跟踪用户位置的应用。为此,我使用了谷歌播放服务定位模块(a.k.a.融合位置)。总而言之,一切正常。

但有时候,完全随机,我根本不会从谷歌位置服务收到位置更新!我的意思是,我的应用程序工作正常,但没有位置更新。不仅如此,如果我启动谷歌地图,它也无法修复我的位置(即使启用了GPS)。重新安装我的应用程序并不能解决问题。  在我手机上的3个出租车应用程序中,有2个可以查明我的位置。 (很可能他们使用旧的LocationManager来获取设备的位置)。

我发现要修复此问题,我只能重新启动设备。但这非常令人不安,我不能指望我的用户在位置更新出现问题时重启设备。 (虽然这在过去2个月里只发生过我6次)

所以:有没有人知道这个问题,有没有解决方法呢?我的应用程序是否以某种方式崩溃谷歌播放服务?

4 个答案:

答案 0 :(得分:1)

我最近遇到了同样的问题,Sebek。我不相信NYX给出的答案是正确的。对于只有Google知道的问题,似乎还有其他一些解决办法。我为什么这么说?

我创建了一个应用程序,该应用程序使用融合定位服务以30秒的间隔获取移动设备的位置,并在应用程序处于焦点时烘烤位置。但由于某种原因,融合服务刚刚停止工作。我一次又一次地尝试......打开所有位置服务 - WIFI,GPS和网络......没有任何效果。融合位置服务仍未结束。

但后来我尝试了一些东西......我启动了我的应用程序,然后使用内置的Android任务管理器,我启动了Google地图......和BOOM!我的应用程序上的融合定位服务工作并开始每次报告30秒标记的位置数据......并且出于某种奇怪的原因,位置的准确性也得到了提高......高达5米的准确度!我一遍又一遍地尝试相同的程序 - 首先启动我的应用程序而没有...然后启动Maps和BOOM! - 它每次都有效。我推出Google地图时取得了100%的成功。

因此,这清楚地证明了Google正在运行一些代码,以确保在推出Google应用并需要定位服务时,融合定位服务不会退出。 Sebek,也许你可以尝试这个,看看你是否得到了相同的结果。也许那时我们可以在寻找真正修复的地方取得进展。

干杯, 邵氏-T ...

答案 1 :(得分:1)

尝试将位置模式更改为“仅限GPS”,然后再返回“高精度”。有时候你在室内就会出现这个问题并修复它。

See here how to switch GPS programatically on/off

答案 2 :(得分:0)

我发现,如果您未通过在应用关闭时调用LocationManager取消订阅removeUpdates,则有时会导致您遇到的问题。

答案 3 :(得分:0)

我一直在努力解决这个问题好几个星期,我相信Android操作系统限制了一个应用程序,它在后台这意味着应用程序在一两个小时后才能在后台访问gps。可能是因为电池使用量较少。

我正在使用的解决方案是:

这是用于每项活动的BaseActivity:

 public abstract class BaseActivity extends AppCompatActivity {
 @Override
 protected void onPause() {
     super.onPause();
       MyApplication.activityPaused();
 }
 @Override
 protected void onResume() {
     MyApplication.activityResumed();
     super.onResume();
 }
}

这是MyApplication类:

public class MyApplication extends Application  {

public static boolean isActivityVisible() {
    return activityVisible;
}

public static void setVisibilityTrue() {
    activityVisible = true;
}

public static void activityResumed() {
    boolean isScreenOn = true;
    // isScreenOn() method is deprecated API level 21. You should use isInteractive instead:
    PowerManager pm = (PowerManager) MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        isScreenOn = pm.isInteractive();
    } else {
        isScreenOn = pm.isScreenOn();
    }
    if (isScreenOn) {
        activityVisible = true;
    }
}

public static void activityPaused() {
    boolean isScreenOn = true;
    PowerManager pm = (PowerManager) MyApplication.getInstance().getSystemService(Context.POWER_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        isScreenOn = pm.isInteractive();
    } else {
        isScreenOn = pm.isScreenOn();
    }
    if (isScreenOn) {
        activityVisible = false;
    }

}
private static boolean activityVisible;

}

当应用程序在后台时,我们将其带到前台,每隔30秒我们会检查应用程序屏幕是否已锁定,如果已锁定我们打开应用程序:

private void bringApplicationToFront(Context context) {
    /**
     * check if motitor screen is Off/On
     * */
    boolean isScreenOn = true;
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
        isScreenOn = pm.isInteractive();
    } else {
        isScreenOn = pm.isScreenOn();
    }
    if (!isScreenOn) {
        /**
         * check if app  is fore/back ground
         * */
        boolean isInForeBackground = false;
        try {
            isInForeBackground = MyApplication.isActivityVisible();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!isInForeBackground) {
            Intent notificationIntent = new Intent(context, ActivitySplash.class);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
            try {
                pendingIntent.send();
            } catch (PendingIntent.CanceledException e) {
                e.printStackTrace();
            }
        }
    }
}

棘手的部分是当app在后台并且屏幕被锁定时,重新打开应用程序(将其带到前台)后调用onPause() activityVisible被设置为false(意味着不可见,这是不正确的),实际上它是正确的但它不是我想要的,解决这个问题我永远不会让屏幕被锁定时设置activityVisible以及当应用程序在启动时重新打开我将activityVisible设置为true。

我认为如果应用程序到达前台,它的优先级很高,那么它可以一直使用gps。

我希望我能正确解释我的解决方案。 一切顺利......