【问题标题】:Using a Mock Location in Navigation App在导航应用程序中使用模拟位置
【发布时间】:2011-10-27 15:34:55
【问题描述】:

我正在尝试开发一个应用程序来模拟通过 Google 导航应用程序的路线。我在本网站 (Android mock location on device?) 的其他帖子中找到了一些关于如何实现模拟位置提供程序的优秀示例。
通过对源代码http://www.cowlumbus.nl/forum/MockGpsProvider.zip 的简单修改,我的模拟位置会显示在 Google 的地图应用程序中。 (唯一的变化是将模拟提供程序名称更改为 LocationManager.GPS_PROVIDER)。
我的问题是,当我打开导航应用程序时,它显示“正在搜索 GPS 信号”。我仍然看到我的位置在地图上移动;但是,它不会生成到目的地的路线。我想知道是否有人知道我需要做些什么来伪造导航以将我的模拟位置视为 GPS 信号。
谢谢。

public class MockGpsProviderActivity extends Activity implements LocationListener {

private MockGpsProvider mMockGpsProviderTask = null;
private Integer mMockGpsProviderIndex = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    String mocLocationProvider = LocationManager.GPS_PROVIDER;
    locationManager.addTestProvider(mocLocationProvider, false, false,
            false, false, true, false, false, 0, 5);
    locationManager.setTestProviderEnabled(mocLocationProvider, true);
    locationManager.requestLocationUpdates(mocLocationProvider, 0, 0, this);

    try {

        List<String> data = new ArrayList<String>();

        InputStream is = getAssets().open("test.csv");
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));

        String line = null;
        while ((line = reader.readLine()) != null) {
            data.add(line);
        }

        // convert to a simple array so we can pass it to the AsyncTask
        String[] coordinates = new String[data.size()];
        data.toArray(coordinates);

        // create new AsyncTask and pass the list of GPS coordinates
        mMockGpsProviderTask = new MockGpsProvider();
        mMockGpsProviderTask.execute(coordinates);
    } 
    catch (Exception e) {}
}

@Override
public void onDestroy() {
    super.onDestroy();

    // stop the mock GPS provider by calling the 'cancel(true)' method
    try {
        mMockGpsProviderTask.cancel(true);
        mMockGpsProviderTask = null;
    }
    catch (Exception e) {}

    // remove it from the location manager
    try {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.removeTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER);
    }
    catch (Exception e) {}
}

@Override
public void onLocationChanged(Location location) {
    // show the received location in the view
    TextView view = (TextView) findViewById(R.id.text);
    view.setText( "index:" + mMockGpsProviderIndex
            + "\nlongitude:" + location.getLongitude() 
            + "\nlatitude:" + location.getLatitude() 
            + "\naltitude:" + location.getAltitude() );     
}

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


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


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


/** Define a mock GPS provider as an asynchronous task of this Activity. */
private class MockGpsProvider extends AsyncTask<String, Integer, Void> {
    public static final String LOG_TAG = "GpsMockProvider";
    public static final String GPS_MOCK_PROVIDER = "GpsMockProvider";

    /** Keeps track of the currently processed coordinate. */
    public Integer index = 0;

    @Override
    protected Void doInBackground(String... data) {         
        // process data
        for (String str : data) {
            // skip data if needed (see the Activity's savedInstanceState functionality)
            if(index < mMockGpsProviderIndex) {
                index++;
                continue;
            }               

            // let UI Thread know which coordinate we are processing
            publishProgress(index);

            // retrieve data from the current line of text
            Double latitude = null;
            Double longitude = null;
            Double altitude= null;
            try {
                String[] parts = str.split(",");
                latitude = Double.valueOf(parts[0]);
                longitude = Double.valueOf(parts[1]);
                altitude = Double.valueOf(parts[2]);
            }
            catch(NullPointerException e) { break; }        // no data available
            catch(Exception e) { continue; }                // empty or invalid line

            // translate to actual GPS location
            Location location = new Location(LocationManager.GPS_PROVIDER);
            location.setLatitude(latitude);
            location.setLongitude(longitude);
            location.setAltitude(altitude);
            location.setTime(System.currentTimeMillis());

            // show debug message in log
            Log.d(LOG_TAG, location.toString());

            // provide the new location
            LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, location);

            // sleep for a while before providing next location
            try {
                Thread.sleep(200);

                // gracefully handle Thread interruption (important!)
                if(Thread.currentThread().isInterrupted())
                    throw new InterruptedException("");
            } catch (InterruptedException e) {
                break;
            }

            // keep track of processed locations
            index++;
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        Log.d(LOG_TAG, "onProgressUpdate():"+values[0]);
        mMockGpsProviderIndex = values[0];
    }
}
}

【问题讨论】:

    标签: android google-maps navigation mocking location


    【解决方案1】:

    这是我所缺少的:

    location.setLatitude(latitude);
    location.setLongitude(longitude);
    location.setAccuracy(16F);
    location.setAltitude(0D);
    location.setTime(System.currentTimeMillis());
    location.setBearing(0F);
    

    此外,计算导航方位也很重要。否则,路由更新将不准确。

    【讨论】:

    • 您是否曾经让语音导航与模拟位置一起使用?路线被重新计算,但在启动应用程序后我无法获得任何语音导航。
    • 对不起,我之前没有看到这个。是的,一切对我来说都很好。如果您有具体的问题需要我帮助,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2018-04-28
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多