在Android Marshmallow中启用模拟位置和addTestProvider崩溃(v6)

时间:2016-07-27 00:48:42

标签: android unit-testing mocking android-6.0-marshmallow

我试图在我的代码中启用模拟位置,但无法使其正常工作。它会使应用程序崩溃。

这是我做的:

- (使用Android工作室)我将AndroidManifest.xml从正常位置复制到androidTest并测试,添加了以下行

composer = new Three.EffectComposer renderer
composer.addPass renderPass
composer.addPass transparentPass
composer.addPass copyPass

(顺便说一下,我应该在androidTest下复制整个AndroidManifest.xml并进行测试,还是只在上面排队?)

- 我的代码在以下地方崩溃

<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />

顺便说一下,这段代码在

 final String providerName = "MyWalkPokemonGPSProvider";
 private LocationManager mLocationManager;

 public void setMyGPS(){
    mLocationManager = (LocationManager) getSystemService(getApplicationContext().LOCATION_SERVICE);

    // this is where it crashes
    // if it is commented out, then it runs (but still does not allow MOCK)
    mLocationManager.addTestProvider(providerName, true, false, false, false, true, true, true,
            Criteria.POWER_LOW, Criteria.ACCURACY_FINE);
    Location loc = new Location(providerName);
    loc.setTime(System.currentTimeMillis());
    loc.setLongitude(37.331784);
    loc.setLatitude(-121.885547);
    mLocationManager.setTestProviderLocation(providerName, loc);
    new Location(LocationManager.GPS_PROVIDER);

}

因为我在这里定义了一些叠加按钮。 (更新:为了澄清,我在manifest.xml中声明了服务)

所以,我的问题是

  1. 当我运行它时(通过评论崩溃的部分),我仍然无法在设置 - &gt;下找到该应用程序。开发者选项 - &gt;模拟位置应用程序。它没有在那里列出。

    我通过构建构建应用程序 - &gt;生成签名APK - &gt;并使用build type = debug。

    我在这里做错了什么?我尝试了Enable Mock Locations in Android Marshmallow下的建议,但无效

  2. 为什么mLocationManager.addTestProvider崩溃了?有什么建议吗?

  3. 更新:为了澄清,这里是清单(用于测试):

    public class OverlayShowingService extends Service { }
    

2 个答案:

答案 0 :(得分:0)

您是否在清单中添加了服务?您需要在<application.../>

中执行此操作

我在上一个项目中的addTestProvider下也有这一行 mLocationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);

请注意,您还要在开发者设置下选择您将用于模拟位置的应用程序(以上关于手机)

答案 1 :(得分:0)

示例如何

final String PROVIDER_NAME_GPS = android.location.LocationManager.GPS_PROVIDER;

public void enableProvider(android.content.Context context, String providerName, int status) {
    android.location.LocationManager locationManager = getLocationManager(context);
    locationManager.addTestProvider(providerName, false, false, false, false, true, true, true, android.location.Criteria.POWER_LOW, android.location.Criteria.ACCURACY_FINE);
    locationManager.setTestProviderEnabled(providerName, true);
    locationManager.setTestProviderStatus(providerName, status, null, System.currentTimeMillis());
}

public void setLocation(android.content.Context context, String providerName, double latitude, double longitude, double altitude, float accuracy) {
    android.location.LocationManager locationManager = getLocationManager(context);
    android.location.Location loc = new android.location.Location(providerName);
    loc.setTime(System.currentTimeMillis());
    loc.setAccuracy(accuracy);
    loc.setAltitude(altitude);
    loc.setSpeed(0);
    loc.setElapsedRealtimeNanos(android.os.SystemClock.elapsedRealtimeNanos()); //System.nanoTime())
    loc.setLatitude(latitude);
    loc.setLongitude(longitude);
    locationManager.setTestProviderLocation(providerName, loc);
}

public static LocationManager getLocationManager(Context context) {
    return (LocationManager)context.getSystemService("location");
}

public void notifyForeground(Context context, SimpleLocation simpleLocation) {
    // set new location 
    setLocation(context, PROVIDER_NAME_GPS, simpleLocation.getLongitude(), simpleLocation.getLongitude(), ...);
    // notify via not manager we have new fix 
}

public static boolean isMockLocationEnabled(Context context) {
    ContentResolver contentResolver = context.getContentResolver();
    return Secure.getString(contentResolver, "mock_location").equals("0");
}

private boolean _providerEnabled = false;

/**
 *   MAIN METHOD - ENABLE PROVIDER IF NOT ENABLED YET 
 *   PASS NEW FIX TO LOCATION MANAGER 
 */
protected boolean enableProviderAndNotify(android.content.Context context, SimpleLocation simpleLocation) 
   if (isMockLocationEnabled(context)) {
      if (!_providerEnabled) {
           enableProvider(context, PROVIDER_NAME_GPS, android.location.LocationProvider.AVAILABLE);
           _providerEnabled = true;
       }
       notifyForeground(context, simpleLocation);
       return true;
   } else {
       _providerEnabled = false;
       disableAll();
       warnNoMockLocationEnabled(context);
   }
   return false;
}
  • 在开发者设置中显示应用选择模拟位置应用为api&gt; M添加清单

    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>