How to check for Mock Location in Android Marshmallow?

时光总嘲笑我的痴心妄想 提交于 2019-11-28 23:49:28

If you are using FusedLocationProviderApi and have set mock location using setMockLocation(mGoogleApiClient, fakeLocation); in the callback/pendingIntentCallback the returned Location object contains KEY_MOCK_LOCATION extra, a boolean that indicates that received object is mock.

@Override

public void onLocationChanged (Location location){    
   Bundle extras = location.getExtras();
   boolean isMockLocation = extras != null && extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false);

}

The accepted answer is a working solution, however, I would like to add some points for the sake of completeness.

The best built-in way to detect a mock location (not just since Marshmallow, but since API 18+) is to use Location.isFromMockProvider(), as stated in other answers and comments.

I extensively experimented with mock locations on different devices and OS versions and came to the following conclusion:

  • The KEY_MOCK_LOCATION extra bears the exact same information as .isFromMockProvider(), i.e. .isFromMockProvider() will return true when the extra is present and false when it isn't. In other words, it provides no added value and is just a more complicated way of finding out whether an individual location was labeled as a mock by its provider. See here for more info.
    So I would definitely recommend using .isFromMockProvider().

  • Both the extra and the getter can sporadically return false negatives, i.e. the location in question is a mock but not labeled as such. This is obviously really bad for certain use cases. I have written a detailed blog post on this subject if you want to learn more.

After struggling with Android location (and the mock labeling problem) for quite some time I published the LocationAssistant, a utility class that will reliably reject mock locations on non-rooted devices with API 15+. It also unburdens you from most of the FusedLocationProvider boilerplate. Maybe you'll find it useful for your next location-aware app project.

sethwhite

This answer didn't seem to be work for me. extras.getBoolean(FusedLocationProviderApi.KEY_MOCK_LOCATION, false) always returned false.

However, I did this:

@Override
public void onLocationChanged (Location location){
    boolean isMockLocation = location.isFromMockProvider();
}

and I started getting the correct results.

Marlon

In marshmallow you can check mock_location by using the AppOpsManager.

Similar answer here: How to read selected mock location app in Android M - API 23

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!