问题描述:

I am sending android user location lat and longitude to server together with registration ID and other parameters as json object in Asynctask(a nested class of the activity). But the Location object(that had values at the start of the app) instantiated in the activity as such

location = LocationServices.FusedLocationApi

.getLastLocation(mgoogleapiclient);

is returning null in the Asynctask Class. Can someone explain to me why? Do I have to use separate class to get user location and send it in another asynctask or service(which doesn't make sense from architectural standpoint)?

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(

mGoogleApiClient);

if (mLastLocation != null) {

PostData pdata = new PostData();

double latitude = mLastLocation.getLatitude();

double longitude = mLastLocation.getLongitude();

pdata.execute(String.valueOf(latitude), String.valueOf(longitude));

}

I am retrieving this from the AsyncTask class as such:

json.put("latitude", String.valueOf(args[1]));

json.put("longitude", String.valueOf(args[2]));

But when I debug it, I am getting the getting the registration ID which I sent to the AsyncTask class from another method.

I hope I am making myself clear.

@Override

protected String doInBackground(String... args) {

try {

try {

URL url;

HttpURLConnection urlConn;

url = new URL ("myphp.php");

urlConn = (HttpURLConnection)url.openConnection();

urlConn.setDoInput (true);

urlConn.setDoOutput (true);

urlConn.setUseCaches (false);

urlConn.setRequestProperty("Content-Type","application/json");

urlConn.setRequestProperty("Accept", "application/json");

urlConn.setChunkedStreamingMode(0);

urlConn.setRequestMethod("POST");

urlConn.connect();

//get google account

AccountManager am = AccountManager.get(getBaseContext()); // "this" references the current Context

Account[] accounts = am.getAccountsByType("com.google");

//Create JSONObject here

JSONObject json = new JSONObject();

json.put("regID", String.valueOf(args[0]));

json.put("Google account", accounts[0].name);

json.put("name", "Amanda");

json.put("tel", "2069994444");

json.put("latitude", String.valueOf(args[1]));

json.put("longitude", String.valueOf(args[2]));

String postData=json.toString();

// Send POST output.

OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");

os.write(postData);

Log.i("NOTIFICATION", "Data Sent");

os.close();

BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));

String msg="";

String line = "";

while ((line = reader.readLine()) != null) {

msg += line; }

Log.i("msg=",""+msg);

} catch (MalformedURLException muex) {

// TODO Auto-generated catch block

muex.printStackTrace();

} catch (IOException ioex){

ioex.printStackTrace();

}

} catch (Exception e) {

e.printStackTrace();

Log.e("ERROR", "There is error in this code");

}

return null;

}

The following is how I sent the registration ID

gcm = GoogleCloudMessaging.getInstance(this);

regid = getRegistrationId(context);

if (!regid.isEmpty()) {

PostData pd = new PostData();

pd.execute(regid);

} else {

//register

registerInBackground();

}

网友答案:

The problem is that you are sending two separate sets of varargs to the AsyncTask at different times.

You should be sending all necessary data to the AsyncTask when you call execute() in order for it to have the data is needs.

So, you need to get all of the data ready, and send it in one call to execute(), something like this:

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
        mGoogleApiClient);

gcm = GoogleCloudMessaging.getInstance(this);
regid = getRegistrationId(context);
if (!regid.isEmpty() && mLastLocation != null) {
    double latitude = mLastLocation.getLatitude();
    double longitude = mLastLocation.getLongitude();
    PostData pd = new PostData();
    pd.execute(regid, String.valueOf(latitude), String.valueOf(longitude));
} else {
    //register if regid is empty
    if (regid.isEmpty()){
       registerInBackground();
    }
}

Also, there is no need to call String.valueOf() on your String arguments that are passed in to doInBackground(), so you can remove those calls:

@Override
protected String doInBackground(String... args) {
    try {
        try {
            URL url;
            HttpURLConnection urlConn;
            url = new URL ("myphp.php");
            urlConn = (HttpURLConnection)url.openConnection();
            urlConn.setDoInput (true);
            urlConn.setDoOutput (true);
            urlConn.setUseCaches (false);
            urlConn.setRequestProperty("Content-Type","application/json");
            urlConn.setRequestProperty("Accept", "application/json");
            urlConn.setChunkedStreamingMode(0);
            urlConn.setRequestMethod("POST");
            urlConn.connect();
            //get google account
            AccountManager am = AccountManager.get(getBaseContext()); // "this" references the current Context
            Account[] accounts = am.getAccountsByType("com.google");

            //Create JSONObject here
            JSONObject json = new JSONObject();
            json.put("regID", args[0]); //modified
            json.put("Google account", accounts[0].name);
            json.put("name", "Amanda");
            json.put("tel", "2069994444");
            json.put("latitude", args[1]); //modified
            json.put("longitude", args[2]); //modified

            String postData=json.toString();

            // Send POST output.
            OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
            os.write(postData);
            Log.i("NOTIFICATION", "Data Sent");
            os.close();

            BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
            String msg="";
            String line = "";
            while ((line = reader.readLine()) != null) {
                msg += line; }
            Log.i("msg=",""+msg);
        } catch (MalformedURLException muex) {
            // TODO Auto-generated catch block
            muex.printStackTrace();
        } catch (IOException ioex){
            ioex.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
        Log.e("ERROR", "There is error in this code");

    }
    return null;

}

Edit: It sounds like you should register a location listener in order to explicitly request a location. Here is sample code that you can use as a reference in order to register a location listener in your code:

public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onPause(){
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
        //mLocationRequest.setSmallestDisplacement(0.1F);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

        Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude());

        Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();


        //unregister here if you only need one location update:
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }
}
网友答案:
private void startReceivingLocationUpdates() {
        if (locationManager == null) {
            locationManager = (android.location.LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        }

        if (locationManager != null) {
            try {locationManager.requestLocationUpdates(android.location.LocationManager.NETWORK_PROVIDER, 1000, 0F, 
                    (android.location.LocationListener) listener);
            } 
         catch (SecurityException ex) 
             {
                Log.i(TAG, "fail to request location update, ignore", ex);
            } 

           catch (IllegalArgumentException ex)
           {
                Log.d(TAG, "provider does not exist " + ex.getMessage());
            }

            try {
                locationManager.requestLocationUpdates(android.location.LocationManager.GPS_PROVIDER, 1000, 0F, 
                        (android.location.LocationListener) listener);
                //if (listener != null) listener.showGpsOnScreenIndicator(false);
            }
           catch (SecurityException ex) {
                Log.i(TAG, "fail to request location update, ignore", ex); 
                } 

            catch (IllegalArgumentException ex) {
                Log.d(TAG, "provider does not exist " + ex.getMessage());  
                }

            Log.d(TAG, "startReceivingLocationUpdates");
        }
    }

This solved the null pointer exception on my Location object, I got it from here

相关阅读:
Top