谷歌播放服务的位置停在简历的位置更新,而无需调用onDisconnected [英] Google play services location stops location updates on resume without calling onDisconnected

查看:118
本文介绍了谷歌播放服务的位置停在简历的位置更新,而无需调用onDisconnected的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个谷歌地图和自动位置更新通过谷歌Android应用程序播放服务的新定位API。

实现的,就像这样: https://developer.android.com/training/location/receive-location -updates.html

我特别想接收GPS /精确位置。

它可以100%完美,通常,GPS图标上面,位置进来每隔几秒钟,没有后顾之忧。

奇怪的问题似乎是,如果切换到谷歌地图,等待一秒钟,然后再切换回我的申请,我的应用程序,然后准确地获得多一个位置更新,然后停止接收更新。

我的应用程序被适当停止位置更新的onPause /的onStop,并重新连接,并重新启动它们ONSTART / onResume

我的调试敬酒显示已连接从谷歌地图切换回来后,并显示多了一个更新位置,然后更新停止。 onDisconnected()是没有得到调用,mLocationClient.isConnected的检查()的报告真。

因为我已经加了黑客用定时器处理程序运行每隔几秒钟,如果位置尚未在最后10秒中,它调用stopPauseLocation()和checkStartLocation()所示,这不会修复解决方法这个问题和地点重新开始进入。显然,这是一个丑陋的黑客攻击,我不乐意了。

这似乎是像一个bug,谷歌地图和我自己的应用程序之间的相互冲突的东西,但我不能为我的生活中找出一个真正的解决方案。

任何想法?

下面是关键code片段:

  @覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    //创建LocationRequest对象
    mLocationRequest = LocationRequest.create();
    //使用高精度
    mLocationRequest.setPriority(
            LocationRequest.PRIORITY_HIGH_ACCURACY);
    //设置更新间隔为2秒
    mLocationRequest.setInterval(2000);
    //设置最快的更新间隔为1秒
    mLocationRequest.setFastestInterval(1000);
    / *
     *创建一个新的位置客户端,使用封闭类
     *手柄回调。
     * /
    mLocationClient =新LocationClient(这,这,这一点);

    mLocationManager =(LocationManager)getSystemService(Context.LOCATION_SERVICE);
}

@覆盖
保护无效的OnStart(){
    super.onStart();

    //检查我们的连接播放服务
    checkStartLocation();
}

/ *
 *当活动不再是可见的所有调用。
 *停止更新和断开连接。
 * /
@覆盖
保护无效的onStop(){
    stopPauseLocation();
}

/ *
 *通过调用定位服务时,请求连接
 *客户成功完成。在这一点上,你可以
 *请求当前位置或启动周期性更新
 * /
@覆盖
公共无效onConnected(包dataBundle){
    //显示连接状态
    Toast.makeText(这一点,保持通话,Toast.LENGTH_SHORT).show();
    mLocationClient.requestLocationUpdates(mLocationRequest,这一点);

    super.onStop();
}

私人无效stopPauseLocation()
{
    //如果客户端连接
    如果(mLocationClient.isConnected()){
        / *
         *删除位置更新的监听器。
         *目前的行动是听众,所以
         *的说法是本。
         * /
        mLocationClient.removeLocationUpdates(本);
    }
    / *
     断开()被调用*之后,客户端是
     *认为是死的。
     * /
    mLocationClient.disconnect();
}

/ **
 *辅助检查,如果我们连打,并尝试连接,如果没有
 * /
保护无效checkStartLocation(){
    如果(!mLocationClient.isConnected())
    {
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationClient.connect();
    }
}

/ *
 *通过调用定位服务时,请求连接
 *客户成功完成。在这一点上,你可以
 *请求当前位置或启动周期性更新
 * /
@覆盖
公共无效onConnected(包dataBundle){
    //显示连接状态
    Toast.makeText(这一点,保持通话,Toast.LENGTH_SHORT).show();
    mLocationClient.requestLocationUpdates(mLocationRequest,这一点);
}

@覆盖
公共无效onDisconnected(){
    //显示连接状态
    Toast.makeText(这一点,断开连接,Toast.LENGTH_SHORT).show();
}

/ *
 *通过调用定位服务如果尝试连接到
 *定位服务失败。
 * /
@覆盖
公共无效onConnectionFailed(ConnectionResult connectionResult){
    Toast.makeText(这一点,onConnectionFailed,Toast.LENGTH_SHORT).show();
}

 //定义接收位置更新回调方法
@覆盖
公共无效onLocationChanged(位置定位){
    //报告,该位置已更新的用户界面
    弦乐味精=更新的位置:+
            Double.toString(location.getLatitude())+,+
            Double.toString(location.getLongitude());
    Toast.makeText(这一点,味精,Toast.LENGTH_SHORT).show();
}
 

解决方案

我解决这个发现的唯一方法是一个黑客,但是这是我想出破解的最好的版本。

在code以下将检查每10秒(然后递增15秒,20秒,最多30秒)进行位置更新。如果没有位置已经收到,它调用removeLocationUpdates()和requestLocationUpdates(),这似乎解决我的问题。

 专用处理器locationCheck = NULL;
//跟踪的最后位置更新的时间
专用长lastLocationUpdate = System.currentTimeMillis的();
私人长lastLocationWaitTime = 0;
//等待多久,直到我们重新连接(10秒)
专用长WAIT_LOCATION_AGE_START = 10000;
怎么长得下次检查之前要等待//增量
//递增,每一次失败给系统更多的时间来恢复
专用长WAIT_LOCATION_AGE_INCREMENT = 5000;
//最大等待时间
专用长MAX_WAIT_LOCATION_AGE = 30000;

加入的onCreate在你的类:
locationCheck =新的处理程序();

添加到onResume / ONSTART:
lastLocationUpdate = System.currentTimeMillis的();
lastLocationWaitTime = WAIT_LOCATION_AGE_START;
locationCheck.removeCallbacks(locationCheckRunnable);
locationCheck.postDelayed(locationCheckRunnable,1000);

加入的onStop /的onPause:
locationCheck.removeCallbacks(locationCheckRunnable);

私人可运行locationCheckRunnable =新的Runnable(){
    @覆盖
    公共无效的run(){
        如果((System.currentTimeMillis的() -  lastLocationUpdate)GT; lastLocationWaitTime)
        {
            //验证我们的连接
            checkStartLocation();
            //复位定时器
            lastLocationUpdate = System.currentTimeMillis的();
            //在接下来的检查等待的时间长一点
            lastLocationWaitTime + = WAIT_LOCATION_AGE_INCREMENT;
            lastLocationWaitTime = Math.min(lastLocationWaitTime,MAX_WAIT_LOCATION_AGE);
            //重新请求位置更新
            mLocationClient.removeLocationUpdates(MyParentClassName.this);
            mLocationClient.requestLocationUpdates(mLocationRequest,LocationSocialBaseScreen.this);
        }

        locationCheck.postDelayed(这一点,1000);
    }
};

@覆盖
公共无效onLocationChanged(位置定位){
    lastLocationUpdate = System.currentTimeMillis的();
}
 

I have an Android app with a Google Map and automatic location updates via Google Play Services' new location API.

Implemented just like this: https://developer.android.com/training/location/receive-location-updates.html

I'm specifically trying to receive GPS / accurate locations.

It works 100% perfectly and normally, GPS icon is on above, locations coming in every few seconds, no worries.

The odd problem seems to be that if you switch to Google Maps, wait a second, then switch back to my application, my app then gets exactly one more location update, and then stops receiving updates.

My app is properly stopping location updates onPause/onStop, and re-connecting and re-starting them onStart/onResume.

My debug Toasts show "Connected" after switching back from Google Maps, and show one more "Updated Location", then the updates stop. onDisconnected() is not getting called, and checks of mLocationClient.isConnected() report 'true'.

I have since added a hack work-around with a timer handler that runs every few seconds and if a location hasn't been found in the last 10 seconds, it calls stopPauseLocation() and checkStartLocation() below, which does fix the issue and locations start coming in again. Obviously this is an ugly hack and I'm not happy about it.

It seems to be like a bug, something conflicting between Google Maps and my own app, however, I can't for the life of me figure out a real solution.

Any ideas?

Here's the key code snippets:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create();
    // Use high accuracy
    mLocationRequest.setPriority(
            LocationRequest.PRIORITY_HIGH_ACCURACY);
    // Set the update interval to 2 seconds
    mLocationRequest.setInterval(2000);
    // Set the fastest update interval to 1 second
    mLocationRequest.setFastestInterval(1000);
    /*
     * Create a new location client, using the enclosing class to
     * handle callbacks.
     */
    mLocationClient = new LocationClient(this, this, this);

    mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
}

@Override
protected void onStart() {
    super.onStart();

    // Check our connection to play services
    checkStartLocation();
}

/*
 * Called when the Activity is no longer visible at all.
 * Stop updates and disconnect.
 */
@Override
protected void onStop() {
    stopPauseLocation();
}

/*
 * Called by Location Services when the request to connect the
 * client finishes successfully. At this point, you can
 * request the current location or start periodic updates
 */
@Override
public void onConnected(Bundle dataBundle) {
    // Display the connection status
    Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
    mLocationClient.requestLocationUpdates(mLocationRequest, this);

    super.onStop();
}

private void stopPauseLocation()
{
    // If the client is connected
    if (mLocationClient.isConnected()) {
        /*
         * Remove location updates for a listener.
         * The current Activity is the listener, so
         * the argument is "this".
         */
        mLocationClient.removeLocationUpdates(this);
    }
    /*
     * After disconnect() is called, the client is
     * considered "dead".
     */
    mLocationClient.disconnect();
}

/**
 * Helper to check if we're connected to play, and try to connect if not
 */
protected void checkStartLocation() {
    if (!mLocationClient.isConnected())
    {
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationClient.connect();
    }
}

/*
 * Called by Location Services when the request to connect the
 * client finishes successfully. At this point, you can
 * request the current location or start periodic updates
 */
@Override
public void onConnected(Bundle dataBundle) {
    // Display the connection status
    Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
    mLocationClient.requestLocationUpdates(mLocationRequest, this);
}

@Override
public void onDisconnected() {
    // Display the connection status
    Toast.makeText(this, "Disconnected.",Toast.LENGTH_SHORT).show();
}

/*
 * Called by Location Services if the attempt to connect to
 * Location Services fails.
 */
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Toast.makeText(this, "onConnectionFailed", Toast.LENGTH_SHORT).show();
}

 // Define the callback method that receives location updates
@Override
public void onLocationChanged(Location location) {
    // Report to the UI that the location was updated
    String msg = "Updated Location: " +
            Double.toString(location.getLatitude()) + "," +
            Double.toString(location.getLongitude());
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}

解决方案

The only method I've found around this is a hack, but this is the best version of the hack I've come up with.

The code below will check every 10s (and then incrementally 15s, 20s, up to 30s) for a location update. If no location has been received, it calls removeLocationUpdates() and requestLocationUpdates(), which seems to fix my issue.

private Handler locationCheck = null;
// Track the time of the last location update
private long lastLocationUpdate = System.currentTimeMillis();
private long lastLocationWaitTime = 0;
// How long to wait until we reconnect (10 sec)
private long WAIT_LOCATION_AGE_START = 10000;
// Increments of how much longer to wait before next check
// Increments on every failure to give the system more time to recover
private long WAIT_LOCATION_AGE_INCREMENT = 5000;
// Max time to wait
private long MAX_WAIT_LOCATION_AGE = 30000;

Add to onCreate in your class:
locationCheck = new Handler();

Add to onResume/onStart:
lastLocationUpdate = System.currentTimeMillis();
lastLocationWaitTime = WAIT_LOCATION_AGE_START;
locationCheck.removeCallbacks(locationCheckRunnable);
locationCheck.postDelayed(locationCheckRunnable, 1000);

Add to onStop/onPause:
locationCheck.removeCallbacks(locationCheckRunnable);

private Runnable locationCheckRunnable = new Runnable() {
    @Override
    public void run() {
        if ((System.currentTimeMillis() - lastLocationUpdate) > lastLocationWaitTime)
        {
            // Verify our connection
            checkStartLocation();
            // Reset the timer
            lastLocationUpdate = System.currentTimeMillis();
            // On next check wait a bit longer
            lastLocationWaitTime += WAIT_LOCATION_AGE_INCREMENT;
            lastLocationWaitTime = Math.min(lastLocationWaitTime, MAX_WAIT_LOCATION_AGE);
            // Re-request location updates
            mLocationClient.removeLocationUpdates(MyParentClassName.this);
            mLocationClient.requestLocationUpdates(mLocationRequest, LocationSocialBaseScreen.this);
        }

        locationCheck.postDelayed(this, 1000);
    }
};

@Override
public void onLocationChanged(Location location) {
    lastLocationUpdate = System.currentTimeMillis();
}

这篇关于谷歌播放服务的位置停在简历的位置更新,而无需调用onDisconnected的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆