Search code examples
androidgpslocationandroid-wifi

Incorrect Location updates with wifi/mobile network but not with GPS


Following is the coding i got from some one else work. I am trying to implement bit of his work with necessary changes in my app. The problem here is that it is not returning the proper address when the GET ADDRESS button is clicked. Besides, it works only with the wifi/mobile network but not with the GPS. Meanwhile, i wonder how to make auto-posting of data to sever when the call is making to a contact. Thank you!

package com.yang.address;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class AddressActivity extends Activity {
    /** Called when the activity is first created. */
    Double lat, lon;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btnLocation = (Button)findViewById(R.id.btnLocation);
        btnLocation.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                // Acquire a reference to the system Location Manager
                LocationManager locationManager = (LocationManager) AddressActivity.this.getSystemService(Context.LOCATION_SERVICE);
                // Define a listener that responds to location updates
                LocationListener locationListener = new LocationListener() {
                    public void onLocationChanged(Location location) {
                        // Called when a new location is found by the network location provider.
                        lat = location.getLatitude();
                        lon = location.getLongitude();
                        TextView tv = (TextView) findViewById(R.id.txtLoc);
                        tv.setText("Your Location is:" + lat + "--" + lon);
                    }

                    public void onStatusChanged(String provider, int status, Bundle extras) {}
                    public void onProviderEnabled(String provider) {}
                    public void onProviderDisabled(String provider) {}
                };
                // Register the listener with the Location Manager to receive location updates
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
            }
        });

        Button btnSend = (Button)findViewById(R.id.btnSend);
        btnSend.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                postData(lat, lon);
            }
        });

        Button btnAdd = (Button)findViewById(R.id.btnAddress);
        btnAdd.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                TextView tv = (TextView)findViewById(R.id.txtAddress);
                tv.setText(GetAddress(lat, lon));
            }
        });

    }

    public void postData(Double lat2, Double lon2) {
        // Create a new HttpClient and Post Header
        HttpClient httpclient = new DefaultHttpClient();
        HttpGet  htget = new HttpGet("http://myappurl.com/Home/Book/"+lat2+"/"+lon2);

        try {
            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(htget);
            String resp = response.getStatusLine().toString();
            Toast.makeText(this, resp, 5000).show();


        } catch (ClientProtocolException e) {
            Toast.makeText(this, "Error", 5000).show();
        } catch (IOException e) {
            Toast.makeText(this, "Error", 5000).show();
        }
    } 
    public String GetAddress(Double lat2, Double lon2)
    {
        Geocoder geocoder = new Geocoder(this, Locale.ENGLISH);
        String ret = "";
        try {
            List<Address> addresses = geocoder.getFromLocation(lat2,lon2, 1);
            if(addresses != null) {
                Address returnedAddress = addresses.get(0);
                StringBuilder strReturnedAddress = new StringBuilder("Address:\n");
                for(int i=0; i<returnedAddress.getMaxAddressLineIndex(); i++) {
                    strReturnedAddress.append(returnedAddress.getAddressLine(i)).append("\n");
                }
                ret = strReturnedAddress.toString();
            }
            else{
                ret = "No Address returned!";
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ret = "Can't get Address!";
        }
        return ret;
    }
}

Solution

  • Looks like you've made some progress since your last question.

    First off, the LocationManager system on androids is Listening Service in that you register it as a listener and allow the OS to notify when updates are made. This means you should have the code you put in your OnClick method run before you need it. Your best option is to have the OnCreate method of your Activity register the listener as the Activity starts and use the onLocationChanged callback as a way to store the new Location on a class variable.

    private Location lastKnownLocation;
    private TextView tv;
    
    public void onCreate(Bundle savedInstanceState) {
      //....
      setupLocationServices();
      //....
      tv = (TextView) findViewById(R.id.txtLoc);
      Button btnLocation = (Button)findViewById(R.id.btnLocation);
      btnLocation.setOnClickListener(new OnClickListener() {
        public void onClick(View arg0) {
          updateLocation();
        }
      });
      //....
    }
    
    private void setupLocationServices() {
      //....
      LocationListener locationListener = new LocationListener() {
      public void onLocationChanged(Location location) {
        // Called when a new location is found by the network location provider.
        lastKnownLocation = location;
        updateLocation();
      }
      ....
    }
    
    private void updateLocation() {
      double lat = lastKnownLocation.getLatitude();
      double lat = lastKnownLocation.getLongitude();
      tv.setText("Your Location is:" + lat + "--" + lon);
    }
    

    As for your reasoning as to why it doesn't work with GPS it is because you never register the GPS listener. Where you have this line:

    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    

    You would need to substitude in this value:

    LocationManager.GPS_PROVIDER
    

    Again, as I recommended before I really suggest taking the time to fully understand the Android Developer documentation

    As for your other problem regarding listening to the state of incoming calls you should start off by checking the TelephonyManager documentation here. Specifically look for the use of ACTION_PHONE_STATE_CHANGED and its extras for incoming calls. For outgoing calls google the use of ACTION_NEW_OUTGOING_CALL Intents.