我正在使用开放天气图API构建一个简单的五天天气预报Android应用。我正在尝试使用Google Play服务将用户坐标插入到我的请求网址中,但当我将其传递到网址时,纬度和经度的值为空。我只是想知道是否有任何方法可以通过从Google Play服务的onConnected方法传递坐标来解决这个问题。
MainActivity
public class MainActivity extends AppCompatActivity implements OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private String latitude;
private String longitude;
private String requestUrl = "http://api.openweathermap.org/data/2.5/forecast?lat="+latitude+"&lon="+longitude+"&units=metric&APPID={insert api key here}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
new WeatherAsyncTask().execute(requestUrl);
}
public void updateUi(final ArrayList<Weather> weather) {
// Find a reference to the {@link ListView} in the layout
ListView weatherListView = (ListView) findViewById(R.id.list);
// Create a new {@link ArrayAdapter} of earthquakes
WeatherAdapter adapter = new WeatherAdapter(this, weather);
// Set the adapter on the {@link ListView}
// so the list can be populated in the user interface
weatherListView.setAdapter(adapter);
}
private class WeatherAsyncTask extends AsyncTask<String, Void, ArrayList<Weather>> {
protected ArrayList<Weather> doInBackground(String... requestUrl) {
// Dont perform the request if there is no URL, or first is null
if (requestUrl.length < 1 || requestUrl[0] == null) {
return null;
}
ArrayList<Weather> weather = QueryUtils.fetchWeatherData(requestUrl[0]);
return weather;
}
protected void onPostExecute(ArrayList<Weather> weather) {
// if there is no result do nothing
if (weather == null) {
return;
}
updateUi(weather);
}
}
// if connection not established to google play services
@Override
public void onConnectionFailed(ConnectionResult result) {
// An unresolvable error has occurred and a connection to Google APIs
// could not be established. Display an error message, or handle
// the failure silently
// ...
}
// get latitude and longitude of last known location when connected to google play services
public void onConnected(Bundle connectionHint) {
try {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
} catch (SecurityException e) {
Log.e("MainActivity", "Security exception thrown", e);
}
if (mLastLocation != null) {
latitude = String.valueOf(mLastLocation.getLatitude());
longitude = String.valueOf(mLastLocation.getLongitude());
}
}
}
当应用程序运行时,我得到一个NullPointerException。我意识到纬度和经度的值是null但我不确定如何正确检索它们。感谢您的帮助,我在Android开发方面相当新。
P.S。我已从URL
中省略了API密钥答案 0 :(得分:0)
请参阅本指南:Retrieving-Location-with-LocationServices-API
如果最近的应用使用了某个位置(设备有最近的位置),首先LocationServices.FusedLocationApi.getLastLocation
将返回一个位置,否则它将返回null
。
因此,如果值为null,则必须在onConnected
内进行检查。
要获得非空位置,您必须侦听设备位置。(FusedLocationApi,LocationManager ...)
此外,您必须检查Android M
更高设备的权限,幸运的是您在FusedLocationApi
内使用Activity
。
我的代码的基本样本:
@Override
public void onConnected(@Nullable Bundle bundle) {
if( HelperUtils.isGpsOpen(getApplicationContext()) ) {
startListenLocation();
}
}
@Override
public void startListenLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//ask permission whatever you want to do
} else {
if(mGoogleApiClient==null) {
buildGoogleApiClient();
} else {
if(mGoogleApiClient.isConnected()) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//here I am checking null thats where you get null
if(mCurrentLocation!=null) {
mPresenter.onNewLocation(getDeviceId(),mCurrentLocation.getLatitude(),mCurrentLocation.getLongitude());
}
// then I am tracking user location , this will trigger onLocationChanged method when a new location arrived so you can handle new location
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
if(!mGoogleApiClient.isConnecting())
buildGoogleApiClient();
}
}
}
}
@Override
public void onLocationChanged(Location location) {
// I am just checking null again, more cautious I am :)
if(location!=null) // handle it
}
然后重要的一部分是在您Activity's
onPause
或onDestroy
时删除位置请求:
if(mGoogleApiClient!=null){
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
if(mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
}