在与谷歌播放服务广播接收器获得位置 [英] get Location in Broadcast receiver with Google Play Services

查看:822
本文介绍了在与谷歌播放服务广播接收器获得位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想启用GPS时,设置标志谷歌地图上。

I want to set up marker on Google Map when GPS is enabled.

我创建了一个广播接收器,以检查是否GPS被启用或禁用。有用。但是,我不知道怎么去定位和设置标记在地图上与谷歌播放服务。

I created a broadcast receiver to check if GPS is enabled or disabled. It works. However, i don't know how to get Location and set up marker on map with Google Play services.

连接方法()在LocationClient上启动方法在onStart()和startUpdates()开始在onResume()。

Method connect() on a LocationClient is started on method onStart() and startUpdates() is started on onResume().

如何在我的广播接收器设置的地图吗?

How can i setup map on my Broadcast receiver ?

如果我使用的getLocation()(见下文),因为我没有连接到GOOGLEPLAY服务返回null。

If i use getLocation() (see below) it returns null because i'm not connected to GooglePlay services.

如果我使用LocationClient.connect()我要等待客户端连接到获得位置。

If i use LocationClient.connect() i have to wait the client be connected to get location.

我怎样才能做到这一点?

How can i do that ?

PS:我用code此示例连接到谷歌播放服务:的 http://developer.android.com/training/location/receive-location-updates.html

PS : I use this sample of code to connect to Google play services : http://developer.android.com/training/location/receive-location-updates.html

我的内部类GpsLocationReceiver:

My inner class GpsLocationReceiver :

public class GpsLocationReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            LocationManager lm = (LocationManager) context.getSystemService(Service.LOCATION_SERVICE);
            boolean isEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
            onGpsStatusChanged(isEnabled);
        }
    }

    private void onGpsStatusChanged(boolean b) {
        if (!servicesConnected() && b) {
            mLocationClient.connect();
        }
        /*currentLocation = getLocation();
        //setUpMapIfNeeded();
        if (currentLocation == null) {
            Toast.makeText(this, "GPS enabled - " + b + " Loc : null", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "GPS enabled - " + b + " Loc : " + currentLocation.toString(), Toast.LENGTH_LONG).show();

        }*/
    }

我的方法的getLocation

My method getLocation

public Location getLocation() {

        // If Google Play Services is available
        if (servicesConnected()) {

            // Get the current location
            return mLocationClient.getLastLocation();
        }
        return null;
    }

我的方法onConnected():

my method onConnected() :

 @Override
    public void onConnected(Bundle bundle) {

        //Set currentLocation
        currentLocation = getLocation();

        if (currentLocation == null) {
            Toast.makeText(HomeActivity.this, "location null", Toast.LENGTH_LONG).show();
        }
        else {
            Toast.makeText(HomeActivity.this, "Lat : "+ currentLocation.getLatitude() + " Long : "+currentLocation.getLongitude(), Toast.LENGTH_LONG).show();
            //Get map if needed
            setUpMapIfNeeded();
        }



        if (mUpdatesRequested) {
            startPeriodicUpdates();
        }
    }

THX

编辑:
我不得不修改我的code。这似乎对我来说更清晰。现在,我的函数的getLocation()后连接调用)成功地完返回null。这意味着,谷歌播放服务不可用。

EDIT : I had modify my code. It seems clearer for me. Now, my function getLocation() called after connect) finished succesfully return null. That means that google play service is not available.

这怎么可能因为连接到服务成功完成?

How is it possible because connection to the service is finished successfully ?

推荐答案

如果我理解你很好,但问题是,即使启用GPS你必须等待,直到GPS获得至少它的首次定位来获取用户的位置。我不明白为什么要检查在广播接收器,但我认为,如果你检查,如果GPS在连接之前启用这是更好的<$ C $ GPS状态C> LocationClient (也许你甚至可以启动前检查它的 Actviity ,如果您的要求允许它),然后您可以请求的位置。

If I understand you well, the problem is that even though the GPS is enabled you have to wait until the GPS gets at least it's first fix to get the user's location. I don't understand why you are checking the GPS status in a BroadcastReceiver, but I think it is better if you check if the GPS is enabled before connecting your LocationClient (maybe you could check it even before launching the Actviity, if your requirements allow it) and then you can request the location.

现在,还有另外一个问题:如果你调用 mLocationClient.getLastLocation()还有就是你检索缓存的位置(因为它就是所谓的可能性,这是最后一个位置系统记录),或者如果系统没有任何,你可以得到一个的位置,所以你的标志显然会innaccurate。正如我通常做,检查是否启用GPS就可以使后 LocationRequest PRIORITY_HIGH_ACCURACY 和实施 LocationListener的作为Android的训练的话,那么之后的第一个 locationChange 收到你能 removeLocationUpdates 如果你只是想一个标志,现在你可以确保你得到的位置是user`s当前位置,但你必须不可避免地等待GPS连接,它可以是几分钟或它可能永远不会发生,这取决于天气和几个随机变量的在你的控制。

Now, there's another issue: if you call mLocationClient.getLastLocation()there is the possibility that you retrieve a cached location (as it's called, it's the "last location" registered by the system) or if the system didn't have any, you could get a null location, so your marker will obviously be innaccurate. As I usually do, after checking if the GPS is enabled you can make a LocationRequest with PRIORITY_HIGH_ACCURACY and implement the LocationListener as the Android training does, then after the first locationChange is received you can removeLocationUpdates if you only want one marker and now you can be sure that the location you got is the user`s CURRENT location, but you have to INEVITABLY wait for the GPS to connect, it could be a couple of minutes or it may never happen, it depends on the weather and a couple of random variables out of your control.

编辑:这里是取自一个例子,谷歌Play服务SDK的样品(SDK /演员/谷歌/ google_play_services /样本/图)::

here is an example taken from the Google Play Services SDK's samples (sdk/extras/google/google_play_services/samples/maps)::

/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.mapdemo;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
import com.google.android.gms.common.GooglePlayServicesClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
import com.google.android.gms.maps.SupportMapFragment;

import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * This demo shows how GMS Location can be used to check for changes to the users location.  The
 * "My Location" button uses GMS Location to set the blue dot representing the users location. To
 * track changes to the users location on the map, we request updates from the
 * {@link LocationClient}.
 */
public class MyLocationDemoActivity extends FragmentActivity
        implements
        ConnectionCallbacks,
        OnConnectionFailedListener,
        LocationListener,
        OnMyLocationButtonClickListener {

    private GoogleMap mMap;

    private LocationClient mLocationClient;
    private TextView mMessageView;

    // These settings are the same as the settings for the map. They will in fact give you updates
    // at the maximal rates currently possible.
    private static final LocationRequest REQUEST = LocationRequest.create()
            .setInterval(5000)         // 5 seconds
            .setFastestInterval(16)    // 16ms = 60fps
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_location_demo);
        mMessageView = (TextView) findViewById(R.id.message_text);
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
        setUpLocationClientIfNeeded();
        mLocationClient.connect();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mLocationClient != null) {
            mLocationClient.disconnect();
        }
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                mMap.setMyLocationEnabled(true);
                mMap.setOnMyLocationButtonClickListener(this);
            }
        }
    }

    private void setUpLocationClientIfNeeded() {
        if (mLocationClient == null) {
            mLocationClient = new LocationClient(
                    getApplicationContext(),
                    this,  // ConnectionCallbacks
                    this); // OnConnectionFailedListener
        }
    }

    /**
     * Button to get current Location. This demonstrates how to get the current Location as required
     * without needing to register a LocationListener.
     */
    public void showMyLocation(View view) {
        if (mLocationClient != null && mLocationClient.isConnected()) {
            String msg = "Location = " + mLocationClient.getLastLocation();
            Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Implementation of {@link LocationListener}.
     */
    @Override
    public void onLocationChanged(Location location) {
        mMessageView.setText("Location = " + location);
    }

    /**
     * Callback called when connected to GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        mLocationClient.requestLocationUpdates(
                REQUEST,
                this);  // LocationListener
    }

    /**
     * Callback called when disconnected from GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onDisconnected() {
        // Do nothing
    }

    /**
     * Implementation of {@link OnConnectionFailedListener}.
     */
    @Override
    public void onConnectionFailed(ConnectionResult result) {
        // Do nothing
    }

    @Override
    public boolean onMyLocationButtonClick() {
        Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
        // Return false so that we don't consume the event and the default behavior still occurs
        // (the camera animates to the user's current position).
        return false;
    }
}

这篇关于在与谷歌播放服务广播接收器获得位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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