Android Fused Location API。位置始终为空

时间:2014-12-27 09:51:27

标签: android fusedlocationproviderapi

我想实现融合位置以获取当前位置。 我是在link

的帮助下完成的

我的googleAPiCLient已连接。但位置始终为空

在我的清单文件中,我已经把这个

   <meta-data android:name="com.google.android.gms.version"
        android:value="5089000" />

我创建了一个单独的Fusionclass。

我的融合课 -

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;

import com.XXX.constants.LogConstants;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

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



private static final long INTERVAL = 1000 * 30;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    private static final long ONE_MIN = 1000 * 60;
    private static final long REFRESH_TIME = ONE_MIN * 5;
//  private static final float MINIMUM_ACCURACY = 50.0f;
    Activity LauncherActivity; 
    private LocationRequest locationRequest;
    private GoogleApiClient googleApiClient;
    private Location location;
    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
public FusedLocation(Activity LauncherActivity) {
    locationRequest = LocationRequest.create();
//  locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(INTERVAL);
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    this.LauncherActivity = LauncherActivity;

    googleApiClient = new GoogleApiClient.Builder(LauncherActivity)
            .addApi(LocationServices.API).addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();

    if (googleApiClient != null) {
         Log.i(LogConstants.INFO_LOG, "googleApiClient is not null");
  //the console prints this
        googleApiClient.connect();

    }
}

@Override
public void onConnected(Bundle connectionHint) {
     Log.i(LogConstants.INFO_LOG, "GoogleApiClient connected");
    Location currentLocation = fusedLocationProviderApi.getLastLocation(googleApiClient);
    if (currentLocation != null && currentLocation.getTime() > REFRESH_TIME) {
        location = currentLocation;
    } else {
          fusedLocationProviderApi.requestLocationUpdates(googleApiClient,locationRequest, locListen);
        // Schedule a Thread to unregister location listeners
        Executors.newScheduledThreadPool(1).schedule(new Runnable() {
            @Override
            public void run() {
                fusedLocationProviderApi.removeLocationUpdates(googleApiClient, locListen);
            }
        }, ONE_MIN, TimeUnit.MILLISECONDS);
    }
}




 com.google.android.gms.location.LocationListener locListen=new           com.google.android.gms.location.LocationListener() {

    @Override
    public void onLocationChanged(Location location) {

         Log.i(LogConstants.INFO_LOG, "75location::"+location);



    }
};

public Location getLocation() {
    return this.location;
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

}

我的活动课程我正在调用oncreate

中的FusedLOcation课程
 //show error dialog if GoolglePlayServices not available
    if (!isGooglePlayServicesAvailable()) {
        finish();
    }
    fusedLocation = new FusedLocation(this);
    Location location = fusedLocation.getLocation();
    String locationResult = "";
    if (null != location) {
        Log.i(LogConstants.INFO_LOG, location.toString());
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();
        Log.i(LogConstants.INFO_LOG, "longitude::!"+longitude);
        float accuracy = location.getAccuracy();
        /*double elapsedTimeSecs = (double) location.getElapsedRealtimeNanos()
                / 1000000000.0;*/
        String provider = location.getProvider();
        double altitude = location.getAltitude();
        locationResult = "Latitude: " + latitude + "\n" +
                "Longitude: " + longitude + "\n" +
                "Altitude: " + altitude + "\n" +
                "Accuracy: " + accuracy + "\n" +
                "Elapsed Time: "  + " secs" + "\n" +
                "Provider: " + provider + "\n";
    } else {
        locationResult = "Location Not Available!";
        Log.i(LogConstants.INFO_LOG, "Location Not Available!");
    }

 private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        Log.i(LogConstants.INFO_LOG, "status:"+status);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

LOcation始终为null。听众似乎没有工作。

2 个答案:

答案 0 :(得分:3)

首先,如果您正在使用模拟器,则必须手动设置位置:

telnet localhost 5554

连接时运行命令

geo fix <longitude> <latitude>

如此处所述 Using the emulator #geo或此处how-to-emulate-gps-location-in-the-android-emulator。我建议你在模拟器启动时立即这样做,显然是在应用程序启动之前。

其次,您的 FusedLocation 未实现 LocationListener ,因为它是您发布的示例中的内容。您必须实现该接口,然后在 FusedLocation 中实现 onLocationChanged 方法。 无论如何,我认为你试图在应用程序启动后立即加载该位置,对吧?那么你发布的例子不会以这种方式工作,但是用户通过可见的按钮询问位置。如果要在开头加载位置,可以修改示例代码,如下所示:

FusedLocationService 是你的 FusedLocation

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class FusedLocationService implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "FusedLocationService";

    private static final long INTERVAL = 1000 * 30;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    private static final long ONE_MIN = 1000 * 60;
    private static final long REFRESH_TIME = ONE_MIN * 5;
    private static final float MINIMUM_ACCURACY = 50.0f;
    Activity locationActivity;
    private LocationRequest locationRequest;
    private GoogleApiClient googleApiClient;
    private Location location;
    private FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;

    FusedLocationReceiver locationReceiver = null;

    public FusedLocationService(Activity locationActivity, FusedLocationReceiver locationReceiver) {
        this.locationReceiver = locationReceiver;
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(INTERVAL);
        locationRequest.setFastestInterval(FASTEST_INTERVAL);
        this.locationActivity = locationActivity;

        googleApiClient = new GoogleApiClient.Builder(locationActivity)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        if (googleApiClient != null) {
            googleApiClient.connect();
        }
    }

    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "I'm connected now");
        Location currentLocation = fusedLocationProviderApi.getLastLocation(googleApiClient);
        if (currentLocation != null && currentLocation.getTime() > REFRESH_TIME) {
            location = currentLocation;
        } else {
            fusedLocationProviderApi.requestLocationUpdates(googleApiClient, locationRequest, this);
            // Schedule a Thread to unregister location listeners
            Executors.newScheduledThreadPool(1).schedule(new Runnable() {
                @Override
                public void run() {
                    fusedLocationProviderApi.removeLocationUpdates(googleApiClient,
                            FusedLocationService.this);
                }
            }, ONE_MIN, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.i(TAG, "Location is changed!");
        //if the existing location is empty or
        //the current location accuracy is greater than existing accuracy
        //then store the current location
        if (null == this.location || location.getAccuracy() < this.location.getAccuracy()) {
            this.location = location;
// let's inform my client class through the receiver
            locationReceiver.onLocationChanged();
            //if the accuracy is not better, remove all location updates for this listener
            if (this.location.getAccuracy() < MINIMUM_ACCURACY) {
                fusedLocationProviderApi.removeLocationUpdates(googleApiClient, this);
            }
        }
    }

    public Location getLocation() {
        return this.location;
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

}

这是接收器

public abstract class FusedLocationReceiver {
    public abstract void onLocationChanged();
}

这是活动

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;

public class MainActivity extends Activity {

    private static final String TAG = "MyActivity";
    Button btnFusedLocation;
    TextView tvLocation;
    FusedLocationService fusedLocationService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }

        setContentView(R.layout.activity_main);
        tvLocation = (TextView) findViewById(R.id.tvLocation);

        fusedLocationService = new FusedLocationService(this, new FusedLocationReceiver(){

            @Override
            public void onLocationChanged() {
                Log.i(TAG, "I'm the receiver, let's do my job!");
                updateUI();
            }
        });

        btnFusedLocation = (Button) findViewById(R.id.btnGPSShowLocation);
        btnFusedLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                updateUI();
            }
        });
    }

    private void updateUI() {
        Location location = fusedLocationService.getLocation();
        String locationResult = "";
        if (null != location) {
            Log.i(TAG, location.toString());
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            float accuracy = location.getAccuracy();
            double elapsedTimeSecs = (double) location.getElapsedRealtimeNanos()
                    / 1000000000.0;
            String provider = location.getProvider();
            double altitude = location.getAltitude();
            locationResult = "Latitude: " + latitude + "\n" +
                    "Longitude: " + longitude + "\n" +
                    "Altitude: " + altitude + "\n" +
                    "Accuracy: " + accuracy + "\n" +
                    "Elapsed Time: " + elapsedTimeSecs + " secs" + "\n" +
                    "Provider: " + provider + "\n";
        } else {
            Log.i(TAG, "Location Not Available!");
            locationResult = "Location Not Available!";
        }
        tvLocation.setText(locationResult);
    }


    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }
}

基本上,当您实例化 FusedLocationService 时,您会为该位置准备好的 FusedLocationService 调用一个对象(接收方)。警告:这只会给你一次位置。

答案 1 :(得分:2)

请检查您的位置服务。

它可能已关闭,请将其打开,然后进行测试。

您还可以启用或不启用GPS条件:

//exceptions will be thrown if provider is not permitted.
try {
    gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    if(gpsEnabled) {
        // Your Code....
    }
} catch (Exception ex) {
    Log.e("TAG", "GPS Error : " + ex.getLocalizedMessage());
}

感谢。

相关问题