我有一个使用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>
我看到的症状是我的地图没有更新/检测当前位置。我收到了此代码的超时响应。