Android emulator, Finding mock user location coord

2019-04-15 20:20发布

问题:

Hey guys, I'm having trouble trying to find the user's longitude and location as I run my program and set the telnet command for geo fix for the mock location. While the emulator is running, I set the mock coordinates only for the emulator to become unresponsive and have my program fail in detecting the input coordinates.

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class LBSact extends Activity{
    /** Called when the activity is first created. */
    public double longitude;
    public double latitude;
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        longitude = 0;
        latitude = 0;
        //Creating the listener and manager
        LocationManager LManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

        LocationListener createListen = new LocationListener(){
            @Override
            public void onLocationChanged(Location location) {
                //longitude = location.getLongitude();
                //latitude = location.getLatitude();
                String printout1 = "My current location is: " + "Latitude = " + location.getLatitude() +
                "Longitude = " + location.getLongitude();
                    Toast.makeText(getApplicationContext(),printout1,Toast.LENGTH_LONG).show();

            }
            @Override
            public void onProviderDisabled(String provider) {
                Toast.makeText(getApplicationContext(), "GPS disabled", Toast.LENGTH_LONG).show();

            }
            @Override
            public void onProviderEnabled(String provider) {
                Toast.makeText(getApplicationContext(), "GPS enabled", Toast.LENGTH_LONG).show();

            }
            @Override
            public void onStatusChanged(String provider, int status,
                    Bundle extras) {
            }
        };

        //Cant use Network with emulator, can only use GPS mock locations
        //Toast.makeText(getApplicationContext(), "Does this work?", Toast.LENGTH_LONG).show();
        LManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, createListen);
    }

}

回答1:

First of all. I'm assuming you have read the following: http://developer.android.com/guide/topics/location/obtaining-user-location.html

Since you mentioned injecting mock location data. There are a couple other things you could try to, for instance you could use a KML file to inject GPS locations: http://developer.android.com/guide/developing/tools/ddms.html#emulator-control

But the main thing you should do is create logging messages so that you can more accurately detect where your program is failing. Here's an article on how to setup logcat: http://www.droidnova.com/debugging-in-android-using-eclipse,541.html

I would suggest this as sending text to the screen might not always work as your application can crash before it gets to those calls.

Also, have you tried debugging your application through Eclipse? It will break on the crash and give you the location of where the app is failing.

I'll update this answer as you give more details on the issue as it's kind of hard to see what's happening without a stack trace or logging trace.



回答2:

A couple of things:

  1. What is your AVD API level? Crashes like this one are a known issue under 2.3.

  2. How are you setting the mock coordinates? Via the emulator controls in Eclipse, or via Telnet?

  3. Let's have a look at the permissions in your manifest. Several permissions are necessary after the manifest tag for localisation to work properly:

    uses-permission android:name="android.permission.INTERNET" uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"

Here's how I request updates for the user position and set POIs for as overlay items:

 package com.snackrocket.location;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.graphics.drawable.Drawable;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.snackrocket.R;

public class SrPlacesActivity extends MapActivity implements LocationListener {
    private final static ArrayList<HashMap<String, Object>> POIS = new ArrayList<HashMap<String, Object>>();

    static {
        HashMap<String, Object> row = new HashMap<String, Object>();
        row.put("Name", "Sushi Tei");
        row.put("Description", "Sushi and Much More");
        row.put("Longitude", (101.6769441 * 1E6));
        row.put("Latitude", (3.1184736 * 1E6));
        POIS.add(row);
        row = new HashMap<String, Object>();
        row.put("Name", "Devi's Corner");
        row.put("Description", "Quality Mamak");
        row.put("Longitude", (101.6716426 * 1E6));
        row.put("Latitude", (3.1313672 * 1E6));
        POIS.add(row);
        row = new HashMap<String, Object>();
        row.put("Name", "KFC");
        row.put("Description", "The Colonel's Secret Recipe");
        row.put("Longitude", (101.650006 * 1E6));
        row.put("Latitude", (3.117497 * 1E6));
        POIS.add(row);
        row = new HashMap<String, Object>();
        row.put("Name", "McDonalds");
        row.put("Description", "I'm lovin it");
        row.put("Longitude", (101.6723386 * 1E6));
        row.put("Latitude", (3.1328851 * 1E6));
        POIS.add(row);
        row = new HashMap<String, Object>();
        row.put("Name", "DHaven");
        row.put("Description", "Thai Food and Chicha");
        row.put("Longitude", (101.6710465 * 1E6));
        row.put("Latitude", (3.1315682 * 1E6));
        POIS.add(row);
    }

    private MapView myMap;
    private MyLocationOverlay myLocOverlay;
    private GeoPoint homebase = new GeoPoint((int) (3.1 * 1E6),
            (int) (101.7 * 1E6));
    private int lat;
    private int lng;
    private GeoPoint myPoint = homebase;;
    private Geocoder geocoder;
    private MapController mapController;
    private LocationManager locationManager;
    private TextView locationText;

    private void initMap() {
        myMap = (MapView) findViewById(R.id.mapview);

    }

    private void initMyLocation() {
        myLocOverlay = new MyLocationOverlay(this, myMap);
        myLocOverlay.enableMyLocation();
        myMap.getOverlays().add(myLocOverlay);

    }

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

        // Get location manager
        locationManager = (LocationManager) this
                .getSystemService(LOCATION_SERVICE);

        // Create geocoder
        geocoder = new Geocoder(this);

        GeoPoint userPosition = new GeoPoint((int) (lng * 1E6), (int) (lat * 1E6));

        // Prevents NullPointerException
        if (userPosition != null) {
            userPosition = myPoint;
        }

        // Inits
        initMap();
        initMyLocation();

        // Zoom
        int zoomLevel = 14;
        myMap.setBuiltInZoomControls(true);
        MapController mapController = myMap.getController();
        mapController.setCenter(myPoint);
        mapController.setZoom(zoomLevel);

        // Set custom overlay template
        List<Overlay> mapOverlays = myMap.getOverlays();

        // Create my location overlay
        myLocOverlay = new MyLocationOverlay(this, myMap);
        myLocOverlay.enableMyLocation();

        // Enable compass
        myLocOverlay.enableCompass();

        // Add my location overlay
        mapOverlays.add(myLocOverlay);

        // Cycle through POIs and do some magic
        GeoPoint point;
        OverlayItem overlayItem;
        Drawable drawable = getResources().getDrawable(R.drawable.iconr);
        for (HashMap<String, Object> poi : POIS) {
            // Create POI overlay
            SrItemizedOverlay itemizedOverlay = new SrItemizedOverlay(drawable, this);
            point = new GeoPoint(((Double) poi.get("Latitude")).intValue(), ((Double) poi.get("Longitude")).intValue());
            overlayItem = new OverlayItem(point, (String) poi.get("Name"), (String) poi.get("Description"));
            itemizedOverlay.addOverlay(overlayItem);

            // Add POI overlay
            mapOverlays.add(itemizedOverlay);
        }
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

    @Override
    protected void onResume() {
        super.onResume();
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                1000, 10, this);

    }

    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);

    }

    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    public void onLocationChanged(Location location) {
        location = locationManager
                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
        lat = (int) (location.getLatitude());
        lng = (int) (location.getLongitude());

    }
}

And here's my itemised overlay logic:

package com.snackrocket.location;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class SrItemizedOverlay extends ItemizedOverlay<OverlayItem> {
    Context mContext;

    // Creates ArrayList for ItemizedOverlay
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();


    public SrItemizedOverlay(Drawable defaultMarker) {
        super(boundCenterBottom(defaultMarker));
    }

    public SrItemizedOverlay(Drawable defaultMarker, Context context) {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    // Adds OverlayItems to the ArrayList
    public void addOverlay(OverlayItem overlay) {
        mOverlays.add(overlay);
        populate();
    }

    // Returns OverlayItem specified by integer
    @Override
    protected OverlayItem createItem(int i) {
        return mOverlays.get(i);
    }

    // Returns current number of OverlayItems in the ArrayList
    @Override
    public int size() {
        return mOverlays.size();
    }

    @Override
    protected boolean onTap(int index) {
        OverlayItem item = mOverlays.get(index);
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        dialog.setTitle(item.getTitle());
        dialog.setMessage(item.getSnippet());
        dialog.show();
        return true;
    }
}

Hope that helps!