Using Xamarin Android, I need to be able to access location updates from within a service.
I have tried the native Android.LocationManager, Plugin.Geolocator, and Xamarin.Essentials.Geolocation, but none of them seem to provide location updates.
If I do it inside an activity, it works fine, but I have a requirement to post location updates from a service which launches at boot time.
Yeah, I know it's a "privacy violation" or whatever, but the app is only used on company devices for a specific internal use.
I saw somewhere that requesting permissions from a service "is tricky," so I know it's possible, but the guy didn't elaborate on how to do it.
Related
I have a similar issue to this post How to make my Android app comply with the "Background Location Policy" but that post doesn't have an answer.
I have a web browser app, which on occasion will ask for location permissions if the user visits a website that requests that. App targets API 29. The app manifest has <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> which is API 23 and higher because I didn't want to force location permission on older phones.
Today I got an email saying I have until March to fix this, but I don't understand what I have to do, I'm not requesting background location anywhere.
Anyone have any idea what I have to do?
Edit: I have read the help center, and I'm wondering if that my issue is the ACCESS_FINE_LOCATION, maybe something is accessing it on the background. I don't know how I would prevent ad networks from that if they do it. I already pause the WebViews the app is not on the foreground so websites should not be using it.
Edit2: Is there maybe a way I can log background location access so that I can monitor my app a few days to see if it happens?
I would like to answer my own question in case someone else is searching for this. I can't say that I know for certain this is correct but it has worked for me so far.
First, on this answer https://stackoverflow.com/a/65894488/704836 I was told to use AppOpsManager to log background location requests. After doing that I found a few places where that takes places. I will discuss those below:
Ad networks. I have ad network initialization on my Application.onCreate() and a lot of those accessed location. So when triggering a BroadcastReceiver, they would check location.
WifiManager.getConnectionInfo() - this will trigger a location request. Same deal as above, I had one of those on Application.onCreate().
After removing those calls the Play store stopped complaining.
The same way the android system tells about an app is using the GPS in the background.
How can I programmatically have an app that tells me that another app(s) other than mine is using the microphone or gyroscope for example?
The purpose of the App is to present to the user some statistics about the usage of the sensor by background apps/services.
Answer: you cannot without root.
You could write an app to try and monitor what's happening on the
device, but it would require elevated permissions for your app like
running as System or requesting a large set of permissions, so that
you could query the appropriate services and access system resources
to guess at what other apps are doing. The packagemanager exposes api
calls for determining the installed applications and even examining
their permissions, At best though like mentioned in the earlier answer
all apps run in their own instance of the dalvik vm.
Source:
https://security.stackexchange.com/questions/40284/how-can-i-detect-which-background-application-is-using-the-camera-microphone-or
I'm looking into porting some existing code to take Android M's new way of dealing with permissions into consideration. However the permission API needs to have an activity associated with it (for example the requestPermissions() method's first parameter is an activity).
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
Is it possible for the service to create a dummy invisible activity just for use with the permissions API? (if its possible I don't like the thought of doing that anyway though).
Or suppose its not a service but a model class that needs to perform a permissions check, in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API. Or potentially lots of code might have to migrate from model code into Activity code.
Any thoughts on how to migrate non activity based code that needs to check/prompt for permissions over to Android 6.0?
Update: I left out an important piece of information - this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time and run in the background. Therefore the usual situation of a user being prompted for permission when they launch the app or later (and there therefore being an activity at that point) does not necessarily apply.
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
There is almost always an activity, except for pre-installed apps and plugins for other apps. Otherwise, your service is unlikely to ever run, as nothing will have used an explicit Intent to start up one of your app's components, so it will remain in the stopped state.
For the ~99.9% of Android apps that have an activity already, if the permissions are needed for the whole operation of the app, request them on first run. As Snild Dolkow notes, if the user later revokes the permission through Settings, you can detect that without an activity, then use other UI options (e.g., Notification, app widget) to let the user know that operation is suspended until they grant you the permissions again, which they would then do through your activity.
Is it possible for the service to create a dummy invisible activity just for use with the permissions API?
Presumably you can have a Theme.NoDisplay activity use requestPermissions(). However, from the user's standpoint, it will not make much sense, unless there's some alternative UI (app widget?) that they are interacting with. Popping up a permission dialog out of nowhere is unlikely to make you popular.
UPDATE 2019-06-15: Note that Android Q bans services popping up activities frmo the background. Please use a notification instead.
in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API
Do not touch the models until you have requested the permission, and gracefully fail if the permission is revoked. You already have to gracefully fail in other circumstances (out of disk space, no Internet connection, etc.), so a revoked permission should be handled in much the same way.
using this new 6.0 API seems like an recipe for bad design and tight coupling
You are welcome to your opinion. Based on what I have read, the Android engineers believe that asking the user for permissions is part of the user experience and is best handled at the UI layer as a result.
Again: the vast majority of Android apps will not have a problem with this, as they have a user interface. Apps that do not have a user interface and need dangerous permissions are in for some amount of rework.
this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time
First, please understand that this is so far from normal that you can't even see normal from where you are due to the curvature of the Earth. :-) You can't really complain that Google did not optimize this particular scenario.
As I understand it, even system apps should be asking for runtime permissions. The Camera app did, for example, on the 6.0 preview. That being said, there's gotta be some database on the device somewhere that is tracking what has been granted, and presumably there is some way to pre-populate it. However, the user could still revoke it from Settings, presumably. But, the manufacturer could pull some stunts (e.g., messing with the Settings app) to possibly even preclude that scenario. I'd be looking in the same area as "how do I get it so my app cannot be force-stopped?" that device manufacturers can do.
Your alternatives would be to get rid of the dangerous permissions or to migrate your app off the SDK and into a standard Linux binary that would be run as part of the boot process and be put into a Linux user group that has access to the stuff that you need.
Ask for it when the user enables whatever feature your service provides. They'll be in one of your activities at the time. Yes, it means that your activities need knowledge of what permissions your services will require.
The service can always check for the permission by itself, though, since checkSelfPermission() is available in all Context instances. So you don't need an activity for that.
I guess an alternative would be to have your service post a notification saying "feature X requires you to approve more permissions". Actually, that may be a good idea regardless, in case the user goes into settings and revokes any permissions after the fact. That notification would then take the user to some activity with an "enable feature X" button/checkbox -- ask for the permission when that is selected.
You can send a notification. Look this library to manage the permissions: permission library
I work in QA for an company that helps market applications. Currently I have been tasked to ensure location dependent apps function if correctly (ie if im in russia the app displays the russian content and if i change to us the app updates to the us content)
I have tried numerous items to accomplish this but get no where.
What i have tried:
Proxy. Setting this up via wifi to several locations. Both the app and the device still show my current location.
Apps: I have tried all of the following apps and they all give the same result as above.
Fake Location
AutoProxy
Fake GPS
I have enabled developer mode on the devices, and have ensured that "Mock Locations" is checked.
Use case 1:
A developer whats us to test his app which is only available in england. Google Play still sees me in US
Use case 2:
A developer releases a game where the background changes based on your location if i cant force the location change I cant verify this feature works.
Im guessing the fails so far are due to the fact that the location being called in our test apps is network location not GPS?
Any help would be awesome. Even if you could just point me in a direction.
Thank you Greatly
J
Update:
Ok, Thanks to the answers about google play and mock locations. So with those in mind lets think about it from another perspective. If the app is not calling for mock location, Is there anyway to force a mock location override? im trying to cover all the bases here, One app for sure does not use this method, so I still need to find a way around.
depending on how they are calling for the location, I would think (remember im knew here) that using a proxy would work, however as stated above, i'm not getting anywhere there either. Did try a few free proxy's from hidemyass but even the browser wouldn't work with them.
Yes, network location does not get faked by mock location providers. I don't know why not, but it only fakes GPS. In addition, your app has to request the MOCK permission to get it. If it doesn't have this permission, setting a mock location will not actually fake anything to the app. This is for security purposes, so a malicious app can't start broadcasting the wrong location to the phone.
Let's say I have taken over development of an Android app, and my boss asks me why our app requires certain permissions to be displayed to users who buy the app on the Android Market.
Are there any tools or tricks I can use to determine what code triggers each permission, so I can figure out why our app functionally needs those permissions? In particular, I am interested in these permissions:
Phone Calls - Read phone status and identity
System Tools - Retrieve running applications - Allows app to retrieve information about currently and recently running tasks, May allow malicious apps to discover private information about other apps.
The app is a GPS tracking app, and it's not obvious why this permission might be needed.
It would also be helpful to get any tips on why this permission might be needed, even if you can't tell me how to directly analyze the code to find out.
Here is how I would track these down.
Step 1 - Find the manifest permissions declared in your AndroidManifest.xml
Basically everything inside the <uses-permission /> tags e.g.:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Step 2 - Search developer.android.com for classes that use these permissions
Let's take the case of READ_PHONE_STATE, the goal is to find which packages require this permission. A simple search on the dev portal for "READ_PHONE_STATE" starts our search, we are looking for classes here, in the top 5 search results I see the following classes:
TelephonyManager
PhoneStateListener
Click on the classes and get their package names:
android.telephony.TelephonyManager
android.telephony.PhoneStateListener
Step 3 Find classes in your project that import these packages
A simple grep will do, or a Ctrl-H in eclipse, File Search -> Containing text
Step 4 Comment out the import and see what breaks
These are likely candidates for why the permission is required. Confirm the methods in question by looking at the dev portal to validate that the permission is indeed required by that method.
Finally you should be able to tell your boss, READ_PHONE_STATE is required because we call function XYZ which gives us UVW.
Remove a permission and see where the app fails. The answer will be in the logcat output.
That's not an ideal solution though, since you might not know what you need to do in the app to trigger that permission.
I suspect "Read phone status and identity" means that the app is using the device IMEI or similar identifying information to uniquely identify the device to ensure that the app is only being run on a registered device. Or it might just be used as a sort of cookie to track the owner. Look for that code. And remove it, because that's the wrong way to do it. If you need to identify a specific android device, use ANDROID_ID from the Settings.Secure class. http://developer.android.com/reference/android/provider/Settings.Secure.html
As for "Retrieve running applications", I find that one somewhat suspicious. A very common way to implement GPS tracking is to launch a separate service in its own process. This way, if the app should crash, the service will keep going and can be re-attached. In this case, it's possible that the app is using the "Retrieve running applications" to identify and kill the service process. But if so, it's a clumsy way to do it.
With the latest build tools, you can run lint check which will highlight for you all the android SDK method calls which are requiring permissions.
See announcement here http://android-developers.blogspot.com/2015/07/get-your-hands-on-android-studio-13.html and documentation here https://developer.android.com/tools/debugging/annotations.html#permissions .
This is based on android annotations and after some adoption time 3rd party libraries can integrate permission annotations also
The answer for your boss is "because certain API features/calls/methods we use in our app require calee to hold certain permissions. It is for security reasons, and that's the way Android works". As for mentioned permissions - you have to check the code to see if these permissions are really required. Read phone status and identity may indicate your app try to get IMEI or something like this to uniquely identify device. Retrieve running applications - see no reason for GPS tracking app to hold this. But maybe you use 3rd party lib/code that uses this.