传递到网址

时间:2017-05-26 13:23:36

标签: java android mobile

我正在使用开放天气图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密钥

1 个答案:

答案 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 onPauseonDestroy时删除位置请求:

if(mGoogleApiClient!=null){
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        if(mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
}