如何为定位服务实现 onConnectionFailed() 和 onDisconnected()

Posted

技术标签:

【中文标题】如何为定位服务实现 onConnectionFailed() 和 onDisconnected()【英文标题】:How to implement onConnectionFailed() and onDisconnected() for a location service 【发布时间】:2014-04-15 06:53:22 【问题描述】:

我正在使用实现com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacksServicecom.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener

该服务应该在运行时每分钟将位置更新上传到服务器。我搜索了教程,但找不到适合我的场景的教程。

我不知道如何实现的方法是:

@Override
public void onConnectionFailed(ConnectionResult connectionResult) 

    ...

有一些教程建议使用connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); 开始一个活动,但由于这是一个Service(不是活动),我不能使用这种方法。我想过将Intent 中的connectionResult 发送到活动,但ConnectionResult 不可序列化。

@Override
public void onDisconnected() 

    ...

我应该在这里再打电话给LocationClient#connect()吗?

【问题讨论】:

【参考方案1】:

1.onConnectionFailed(): 对于“我想将Intent 中的connectionResult 发送到活动,但ConnectionResult 不可序列化。”我认为没有它可以通过以下方式工作:

您可以返回intErrorCodesConstants 的值是 ConnectionResult,根据该值,您可以分配进一步的操作,只需将控制权传递给您的活动/应用程序。 发件人:http://developer.android.com/reference/com/google/android/gms/common/ConnectionResult.html

2.onDisconnected(), 您可以通知用户“您不再接收位置更新”或其他自定义消息,具体取决于您的应用,这将提示用户采取行动。 如果您的服务由于某种我们不知道的原因进入onDisconnected(),再次调用locationClient.connect() 可能无济于事。

在这两种情况下,我们的想法是将控制权传递给您的应用程序,以便在您的活动中的某个位置,它可以作为控制流的决策点。

此外,您还提到“......但我找不到适合我的场景的任何好东西。”因此,稍微准确地描述您的要求可能会对您有所帮助。将相应地编辑我的答案。

如果它向服务器发送位置更新,那么将控制权传递回您的活动/应用程序并提示用户采取行动也会有所帮助。 (例如,检查Settings 是否启用了Location 访问服务)


查找此问题/答案的任何人的当前情况com.google.android.gms.location下不再找到LocationClient,参考:Android play services 6.5: LocationClient is missing

【讨论】:

第 2 点不正确。 onDisconnected() 在调用disconnect() 之后被调用。见here。 @zelanix 感谢您指出这一点,虽然这不是全部错误,但您对引用 onDisconnect() 的行是正确的,我删除了 不,绝对 - 抱歉,措辞有点不公平 - 答案的其余部分看起来不错。我认为 [这个解决方案] (***.com/a/19433291/2433501) 似乎是在onDisconnected() 之后处理重新连接的合理方式。 没关系,好​​吧,现在不认为这很重要,LocationClient 已被弃用,接口实现 onConnectionFailed()onConnectionSuspended() @zelanix 您在使用 location 吗?您是否从应用程序访问位置设置? i am trying to achieve this【参考方案2】:

我不确定过去如何,但现在(棉花糖)ConnectionResult 是 Parcelable:

public final class ConnectionResult implements SafeParcelable

了解这一点后,您可以将其发送到 Intent 的附加功能中:

@Override
public void onConnectionFailed(final ConnectionResult result) 
    Log.w(LOG_TAG, "Connecting to Google Play Services failed. Result=" + result);
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() 
        @Override
        public void run() 
            Intent intent = new Intent(context, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(INTENT_EXTRA_CONNECTION_RESULT, connectionResult);
            context.startActivity(intent);
        
    );

然后 MainActivity(或任何其他 Activity)可以向用户显示正确的分辨率或对话框消息:

Parcelable connectionResultExtra = activity.getIntent().getParcelableExtra(INTENT_EXTRA_CONNECTION_RESULT);
    if (connectionResultExtra != null) 
        ConnectionResult connectionResult = (ConnectionResult) connectionResultExtra;
        if (connectionResult.hasResolution()) 
            try 
                connectionResult.startResolutionForResult(activity, 1234567890);
             catch (IntentSender.SendIntentException e) 
                Log.e(LOG_TAG, "Unable to resolve ConnectionResult", e);
            
         else 
            int availabilityCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity);
            if (availabilityCode != 0) 
                Dialog errorDialog = GoogleApiAvailability.getInstance().getErrorDialog(activity, availabilityCode, 123);
                errorDialog.show();
        
    

希望对你有帮助。

【讨论】:

【参考方案3】:

    调用“yourLocationClient.connect()”时会调用“OnConnectionFailed()”方法 并且 LocationClient 无法连接到 Google Play 定位服务。

    在“startResolutionForResult(Activity activity, int requestCode)”方法中,第一个参数是一个Activity类,所以UI相关的东西应该在Activity本身上弹出。您应该尝试输入要显示解析结果的 Activity 类的名称。 (我不确定,但你可以试试)

    如果第 2 点不起作用,您可以随时向 Activity 发送广播,并附加一个 'int'。这里的 int 表示您在“connectionResult”中遇到的错误类型。

    如果您希望您的客户端始终保持连接,您可以在“onDisconnected()”中调用“onConnected()”,但在您明确调用“disconnect()”之前它不会断开连接。

    如果您希望即使用户从应用程序托盘关闭应用程序,您的服务也一直运行,请务必选中this 链接。

最重要的:

如果您在应用程序中使用 Google Play 服务,您应该在应用程序第一次启动时检查服务的可用性。甚至在某些服务启动或您将用户带到主活动之前。您可以在任何空白活动/注册后/启动后的活动上执行此操作。

【讨论】:

感谢您的解决方法,谷歌感到羞耻。在谷歌宣布 Android M 之后,这个问题变得更加实际,人们可以在 安装后 禁用权限。【参考方案4】:

这里有一个更好的答案:

ConnectionResult 不可打包,但它有一个构造函数,该构造函数接受一个 errorCode 和一个 pendingIntent。这两个都是可以打包的。

所以,为您服务:

private void notifyUiFailedConnection(ConnectionResult result) 
    Intent intent = new Intent(FIT_NOTIFY_INTENT);
    intent.putExtra(FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE, result.getErrorCode());
    intent.putExtra(FIT_EXTRA_NOTIFY_FAILED_INTENT, result.getResolution());
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

在你的活动中:

private BroadcastReceiver mFitStatusReceiver = new BroadcastReceiver() 
    @Override
    public void onReceive(Context context, Intent intent) 
        // Get extra data included in the Intent
        if (intent.hasExtra(GoogleFitService.FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE) &&
                intent.hasExtra(GoogleFitService.FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE)) 
            //Recreate the connection result
            int statusCode = intent.getIntExtra(GoogleFitService.FIT_EXTRA_NOTIFY_FAILED_STATUS_CODE, 0);
            PendingIntent pendingIntent = intent.getParcelableExtra(GoogleFitService.FIT_EXTRA_NOTIFY_FAILED_INTENT);
            ConnectionResult result = new ConnectionResult(statusCode, pendingIntent);
            fitHandleFailedConnection(result);
        
    
;

【讨论】:

【参考方案5】:

在您的服务中实现 onconnection failed listsner 并覆盖其方法,如下所示:

public class yourService extends Service implements 
    LocationListener, OnConnectionFailedListener 

@Override
public void onConnectionFailed(ConnectionResult arg0) 


【讨论】:

这不能回答上面的问题。

以上是关于如何为定位服务实现 onConnectionFailed() 和 onDisconnected()的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Openfire 实现您自己的(自定义)服务器代码

如何为事件驱动的微服务实现“去抖动”?

如何为 Google Cloud Messaging 实现服务器以发送推送通知 android studio

如何为 iOS 实现亚马逊的产品广告 API?

如何为每个客户端获取一个 DCOM 服务器

如何为 Electron 应用程序服务 Django