Android Google Maps API问题 - 从当前位置请求超时

时间:2016-07-24 22:29:28

标签: android google-maps-android-api-2

我有一个使用Google Maps API的基于位置的应用程序。我已在Google上注册了Google Maps V2 API密钥,虽然我的地图已呈现,但我的应用似乎并未与Google通信,以便找到设备的当前位置。

这是我的位置检测代码:

package ...

import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;

import com.cleveroad.wikiguide.components.Settings;
import com.cleveroad.wikiguide.components.WikiGuideApplication;
import com.cleveroad.wikiguide.components.events.LocationRetrievedEvent;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationAvailability;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class LocationDetector implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{

    public static final int STATUS_UNKNOWN                = -1;
    public static final int STATUS_SUCCESS                = 0;
    public static final int STATUS_RETRIEVING_LOCATION    = 1;
    public static final int STATUS_CUSTOM_LOCATION        = 2;
    public static final int STATUS_LOCATION_NOT_AVAILABLE = 10;
    public static final int STATUS_TIMEOUT_RESPONSE       = 11;
    public static final int STATUS_INTERNET_FAILED        = 12;

    private static LocationDetector object;
    private GoogleApiClient googleApiClient;
    private Location detectedLocation;
    private static int status;
    private Thread retrieveThread;

    public static LocationDetector getInstance(){
        if(object == null)
            throw new RuntimeException("You must init location detector first");

        return object;
    }

    public static void init(Context context){
        object = new LocationDetector(context);
        status = STATUS_UNKNOWN;
    }

    private LocationDetector(Context context) {
        this.googleApiClient = new GoogleApiClient.Builder(context)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        googleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {
        if (Settings.getInstance().getLocationType() == Settings.LocationType.CUSTOM_LOCATION)  {
            status  = STATUS_CUSTOM_LOCATION;
            detectedLocation = Settings.getInstance().getCustomLocation();
            WikiGuideApplication.BUS.post(new LocationRetrievedEvent(detectedLocation, status));
        } else {
            if (retrieveThread != null && retrieveThread.getState() == Thread.State.NEW)
                retrieveThread.start();
        }
    }

    public int getStatus(){
        return status;
    }

    public void startThreadRetrievingLocation(){
        retrieveThread = new Thread(new RetrieveTask());
        retrieveThread.setDaemon(true);
        if (googleApiClient.isConnected())
            retrieveThread.start();
    }

    public void stopThreadRetrievingLocation(){
        if (retrieveThread != null) {
            retrieveThread.interrupt();
        }
    }

    private void retrieveLocation() {
        status = STATUS_RETRIEVING_LOCATION;

        LocationAvailability availability = LocationServices.FusedLocationApi.getLocationAvailability(googleApiClient);

        if (availability == null){
            WikiGuideApplication.BUS.post(new LocationRetrievedEvent(LocationServices.FusedLocationApi.getLastLocation(googleApiClient), STATUS_TIMEOUT_RESPONSE));
            return;
        }

        if (!availability.isLocationAvailable()){
            WikiGuideApplication.BUS.post(new LocationRetrievedEvent(null, STATUS_LOCATION_NOT_AVAILABLE));
            return;
        }

        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(
                googleApiClient, mLocationRequest, new com.google.android.gms.location.LocationListener() {
                    @Override
                    public void onLocationChanged(final Location location) {
                        if (status == STATUS_CUSTOM_LOCATION)
                            return;
                        status = STATUS_SUCCESS;

                        detectedLocation = location;
                        WikiGuideApplication.BUS.post(new LocationRetrievedEvent(location, STATUS_SUCCESS));
                    }
                });
    }


    public Location getDetectedLocation(){
        return detectedLocation;
    }

    public void setCustomLocation(double latitude, double longitude){
        status = STATUS_CUSTOM_LOCATION;
        detectedLocation = new Location("");
        detectedLocation.setLatitude(latitude);
        detectedLocation.setLongitude(longitude);
        WikiGuideApplication.BUS.post(new LocationRetrievedEvent(detectedLocation, STATUS_CUSTOM_LOCATION));
        stopThreadRetrievingLocation();
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        WikiGuideApplication.BUS.post(new LocationRetrievedEvent(null, STATUS_INTERNET_FAILED));
    }

    private class RetrieveTask implements Runnable{

        private final int DELAY = 20000;
        private Handler handler;

        public RetrieveTask() {
            handler = new Handler(WikiGuideApplication.getInstance().getMainLooper());
        }

        @Override
        public void run() {
            while (true) {

                if (Thread.currentThread().isInterrupted()) {
                    return;
                } else {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            retrieveLocation();
                        }
                    });
                }

                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }
}

我在AndroidManifest.xml中设置了以下权限

...

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

...

我只是在我的string.xml文件中定义了我的密钥:

<string name="google_map_api_key">AIzaXXXXXXXXXXXXXXXXXXXXXXXXXXXXXsLc</string>

我看到的症状是我的地图没有更新/检测当前位置。我收到了此代码的超时响应。

0 个答案:

没有答案