模拟GPS位置问题

我正在开发一个获取用户指定的纬度,经度和海拔高度的APP,然后在手机上伪造这个GPS位置,并显示我在谷歌地图中的那个位置。 我对清单文件具有所需权限,并且在开发人员设置中启用了模拟位置。

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); //lm.clearTestProviderEnabled(mocLocationProvider); lm.addTestProvider(mocLocationProvider, false, false, false, false, false, false, false, 0, 10); lm.setTestProviderEnabled(mocLocationProvider, true); mockLocation = new Location(mocLocationProvider); // a string mockLocation.setLatitude(Integer.parseInt(latitude.getText().toString())); // double mockLocation.setLongitude(Integer.parseInt(longitude.getText().toString())); mockLocation.setAltitude(Integer.parseInt(altitude.getText().toString())); mockLocation.setTime(System.currentTimeMillis()); lm.setTestProviderLocation( mocLocationProvider, mockLocation); 

但看起来我的GPS位置在谷歌地图上根本没有改变,有什么问题?

更新:我刚刚在我的手机上安装了一个名为“伪GPS位置”的应用程序,该应用程序工作正常,但我仍然不知道我的代码有什么问题,但我认为我的正式方法是实现这一点。

更新#2:虽然一些类似的应用程序可以在我的手机上运行,​​但我发现了一些例外, http://www.cowlumbus.nl/forum/MockGpsProvider.zip ,这个应用程序无法在我的手机上运行。 有人可以帮我解决这个问题吗? 数百万的谢谢! 每次设置位置时我都没有收到任何错误消息。

更新#3:我注意到这个应用程序相当陈旧,所以它不能在4.1上运行。 如果是这样,如何在新版本中做同样的事情? 我的手机是三星galaxy s3,希望它有所帮助。

更新#4:对于您的信息,我的更新#2中的应用程序代码是:

 package nl.cowlumbus.android.mockgps; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.TextView; public class MockGpsProviderActivity extends Activity implements LocationListener { public static final String LOG_TAG = "MockGpsProviderActivity"; private static final String MOCK_GPS_PROVIDER_INDEX = "GpsMockProviderIndex"; private MockGpsProvider mMockGpsProviderTask = null; private Integer mMockGpsProviderIndex = 0; /** Called when the activity is first created. */ /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); /** Use saved instance state if necessary. */ if(savedInstanceState instanceof Bundle) { /** Let's find out where we were. */ mMockGpsProviderIndex = savedInstanceState.getInt(MOCK_GPS_PROVIDER_INDEX, 0); } /** Setup GPS. */ LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){ // use real GPS provider if enabled on the device locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } else if(!locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) { // otherwise enable the mock GPS provider locationManager.addTestProvider(MockGpsProvider.GPS_MOCK_PROVIDER, false, false, false, false, true, false, false, 0, 5); locationManager.setTestProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER, true); } if(locationManager.isProviderEnabled(MockGpsProvider.GPS_MOCK_PROVIDER)) { locationManager.requestLocationUpdates(MockGpsProvider.GPS_MOCK_PROVIDER, 0, 0, this); /** Load mock GPS data from file and create mock GPS provider. */ try { // create a list of Strings that can dynamically grow List data = new ArrayList(); /** read a CSV file containing WGS84 coordinates from the 'assets' folder * (The website http://www.gpsies.com offers downloadable tracks. Select * a track and download it as a CSV file. Then add it to your assets folder.) */ InputStream is = getAssets().open("mock_gps_data.csv"); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); // add each line in the file to the list 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 onSaveInstanceState(Bundle savedInstanceState) { // store where we are before closing the app, so we can skip to the location right away when restarting savedInstanceState.putInt(MOCK_GPS_PROVIDER_INDEX, mMockGpsProviderIndex); super.onSaveInstanceState(savedInstanceState); } @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 { 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(GPS_MOCK_PROVIDER); location.setLatitude(latitude); location.setLongitude(longitude); location.setAltitude(altitude); location.setTime(System.currentTimeMillis()); location.setLatitude(latitude); location.setLongitude(longitude); location.setAccuracy(16F); location.setAltitude(0D); location.setTime(System.currentTimeMillis()); location.setBearing(0F); // show debug message in log Log.d(LOG_TAG, location.toString()); // provide the new location LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationManager.setTestProviderLocation(GPS_MOCK_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]; } } } 

问题解决了:我添加了以下代码来设置我当前的位置,它可以成功显示在谷歌地图应用程序中。

 location.setLatitude(latitude); location.setLongitude(longitude); location.setBearing(bearing); location.setSpeed(speed); location.setAltitude(altitude); location.setTime(new Date().getTime()); location.setProvider(LocationManager.GPS_PROVIDER); location.setAccuracy(1); 

结论:如果你想在新版本的android中使用模拟位置服务,你必须自己设置每个属性。