Open mohanchalla opened 7 years ago
I cannot try right now, but maybe using a loop of installed apps and check if any of this is selected as mock location app
would work. I cannot try the next code, but I think something like this will work for Marshmallow:
//////////// Package manager
final PackageManager pm = getPackageManager();
//////////// List of all installed apps.
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
//////////// AppOpsManager
AppOpsManager opsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
boolean isMockEnabled = false;
for (ApplicationInfo packageInfo : packages) {
//////////// The package name.
String packageName = packageInfo.packageName;
//////////// I think this will get the UID
int UID = packageInfo.uid;
//////////// Check this app is selected as mock location app
if(opsManager.checkOp(AppOpsManager.OPSTR_MOCK_LOCATION, UID, packageName) == AppOpsManager.MODE_ALLOWED){
isMockEnabled = true;
}
}
If this works (I cannot try right now) I will combine this block with my current code for Android < 6.0
@tomloprod what is this mContext where is the object creation for this? getPackageManager() without reference will it work?
Inside the cordova plugin, you can get the context
with:
Context mContext = this.cordova.getActivity().getApplicationContext();
getPackageManager()
should work. See this stackverflow answer.
final PackageManager pm = getPackageManager(); ^ symbol: method getPackageManager() location: class FakeLocation D:\projects\mo-jess\platforms\android\src\tomloprod\fakelocation\FakeLocation.java:25: error: cannot find symbol
and uid is an integer value
I find the solution in this http://stackoverflow.com/questions/22396382/cant-find-getpackagemanager-method-in-android
Perfect. Yes uid
is an integer. (As I said, I cannot try this right now)
After adding the code whatever you have suggested me. I am getting following error. uid 10214 does not have android.permission.UPDATE_APP_OPS_STATS. Do I need add any permission for this?
Hmmm, I don't know this permission. Try to add this in plugin.xml
:
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS"/>
</config-file>
While iterating installed apps, If any of the app has not updated with this permission then we will get this exception I think so. Even If I add for this plugin there will be no use. Because while iterating the apps, lets say we got first object is fake GPS then this app has have UPDATE_APP_OPS_STATS permission.
I thought you got that exception out of the loop, on this line:
AppOpsManager opsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
Well... If what you said it's true, there is no way to check if there is an application marked as mock location app
. At least, not by the means we have tried...
Yes! Even I am also thinking There no way to check by iterating all installed apps and checking the permissions of the other apps. I think we can not do that in android because we can see the permissions of another apps from our application.
Maybe it's possible to see the permissions of another apps. See this: http://stackoverflow.com/questions/5385957/how-to-get-apps-permission-for-each-app-how-to-do-it-programmatically-on-andro#14672557
But these permission will be set at the time of installation requested by the app to the user. User will select the particular app to mock the locations right? I don't think for this any permission will set. And one more issue is there, If the user has rooted his phone then without changing settings he spoof the GPS Coordinates. check the below link to get the app permissions http://stackoverflow.com/questions/6880232/disable-check-for-mock-location-prevent-gps-spoofing
Root devices can do all. I'm thinking of NO rooted devices. Anyway I only answer your question:
I think we can not do that in android because we can't see the permissions of another apps from our application.
I guess the way to check if the devices is using mock locations in Android Marshmallow is using the isFromMockProvider
method of location, but as I know this isn't 100% relaible... And we are on Cordova, so we cannot have the android Location
object.
Maybe the solution goes through to change the code you are use to get the location (cordova-plugin-geolocation, cordova-plugin-background-geolocation, ...) and return, with the coordinates, a boolean. Lot of work for something like this... But if its a requirement, is the only way to do that, I guess.
Any progress on this? This is a great plugin just that it doesnt work on Marshmallow and above, which is 98% of our target users.
@rafialikhan I have not had time to inquire into this problem. I think the solution is to implement the "[isFromMockProvider](https://developer.android.com/reference/android/location/Location.html#isFromMockProvider())" method in the plugin that provides the locations.
In Android Marshmallow the plugin is always returning true.