In my android app there are certain requirements required in order to use the app (Internet access, GPS, etc.). Now I haven't really found anything dealing with this so I don't know if its a mute point or not. A user can leave your app at any time and turn things off/on on the phone. If I am checking to ensure that data access is available as well GPS in the app oncreate and onresume and just tell the user they need to switch it on, would that probably be enough? I'm thinking not. I'm thinking of redirecting the user to a new layout telling them what is missing and what needs to be done in order to use the app. This layout would also include a button for them to continue once settings are turned on. Is this a good idea or bad? I don't know if there is a better way of handling this or not so all input is appreciated. What do you do?
You might find some of your answers in Find Success on Google Play. If a user performs an action without satisfying all of the requirements, you could present a dialog explaining to the user what the requirements are and why they are necessary. You might also provide a link to redirect the user to the proper settings.
EDIT: The best practices in this situation are probably similar to Requesting Permissions at Run Time. Permissions Best Practices suggests something similar to what you are proposing, which is to show some sort of message or tutorial explaining to the user what is required and why, and then redirecting the user to the appropriate settings.
EDIT: One more example: That Android Documentation shows you how to use the Settings API to check which settings are enabled, and present the Location Settings dialog for the user to update their settings with a single tap. See Prompt the User to Change Location Settings
Related
Currently in my main activity, I employ the Google API Client to manage the Nearby lifecycle. If Nearby isn't enabled or doesn't have permission to run, the client's OnConnectionFailedListener will trigger. From there, I enter a new activity with startActivityForResult, and listen to its closure event to check again if Nearby is enabled and functioning. This has been my take on the issue, since google doesn't seem to officially provide a way of listening to the dialog it displays prompting you about the permission, or something close to that.
I have devised at least one strategy to achieve my goal, which is to monitor the user input when they accept/decline giving permission to Nearby usage.
My strategy would be to find among the views that dialog presented by google and listen to the buttons it has. I debugged my code at the time the Dialog was displayed and couldn't find it anywhere. That might be because apparently the Dialog is initiated inside a new "GoogleApiActivity" (which I could even see enter and leave the screen). How can I access that?
I am also looking for other ways of dealing with this issue. But I'd like to lose this secondary screen I'm using today, and depend only on the API dialog. I am trying to make my app must run on API 16+ and several kinds of devices without compatibility issues.
Thank you in advance for your time and for sharing your knowledge.
Turns out I actually answered myself in my own question. I stated in my question that google opens a GoogleApiActivity to show the dialog, and opening this activity would pause my Main activity's lifecycle, just like when I used that auxiliary new activity I described in my question. More than that, when google calls its GoogleApiActivity, the command used is startActivityForResult(), and it uses the code 65537 for ID purposes. If I check this code at onActivityResult(), I can verify whether the user has given permission based on the resultCode. If the resultCode equals Activity.RESULT_OK, it means the permission was given.
I only wish this had been on the docs, I couldn't find it anywhere.
I'm creating an app, that heavily relies on LocationServices.
For now I'm asking user to turn them on, and everything works fine.
However, when user clicks "No", the whole point of this app goes to hell.
I can spam user to turn location services on from my Service, however I find this solution extremely non-elegant.
Is there a way to turn this setting on programatically? I don't care for additional permissions or so.
I did my research and I only got what I already did - ask user to turn on location services with a dialog etc.
Is there a way to turn this setting on programatically?
Fortunately, no, for obvious privacy and security reasons, except perhaps on rooted devices.
However, when user clicks "No", the whole point of this app goes to hell.
Then advise the user once (per run of your UI) that your app cannot function, and the user should uninstall your app.
Bear in mind that many more permissions will have this same sort of user-recovable behavior with Android M.
You simply cant , if that was possible then you can easily gather locations which is for some unethical reasons could be sold ... so for security reasons its not possible at all .
you can always force the user to click yes by making a really useful and helpful application that the user simply want to try and cant click no because it wont function at all ...
I would like to ask about something. I'm now aware that there's no possibility to turn GPS on via normal SDK application. My problem is that I need to do it without user's confirmation (my application's fundamental is to work silently). I need it because my application is meant to be used by a company to track their devices (tablets). It needs to turn on GPS to obtain location and after that turn it off. That means, if we prompt user to turn GPS on, he may not do it and the application (a service actually) will not work properly.
My next step is to find an alternative solution, I mean, if we turn GPS on using settings, it eventually gets turned on by a core application/service. My assumption is that it uses native code to access the GPS device and turn it on (if I'm wrong, please correct me and point to the right answer).
Therefore my question is - if possible, how can I do that in NDK and later on how to integrate it with my application. If NDK can't handle it, how it can be done? There must be a way, since it's eventually done in settings.
I would also like to ask the same question about Internet connection (to alternatively use network provider to obtain location).
Thanks in advance for any contribution!
You might find a way to handle GPS with NDK/JNI calls, but there's no such thing as GPS without notice to the user on an Android device. He can switch GPS off or refuse to switch it on. In such a case, that device itself (the hardware) switches the GPS sensor off.
What might be possible is to use other ways to locate the device:
Wifi gives you the position not as accurate as GPS, but better then nothing
Carrier track the position of a device according to the signal strength arriving at their antennas. But I haven't seen any Android interface able to handle that (might be a question to ask here, if anybody knows how to get that information)
The way, I'd handle your problem is on the organizational side (as this is company internal stuff): You basically say to the user: "Switch on GPS and you, user, get access to your emails" (well, as an example)
Give something and you will get something back :-)
"Settings" is not an application to begin with.
So if you already made an application you should understand somehow the basics of Android applications but if you didn't really understand them then I'd like to say that the applications generally run in a "sandbox" and these applications may be destroyed / terminated by the system should it deem it necessary. There's also no such thing as "silent mode" either. The user MUST ACCEPT / DECLINE permissions and the user MUST be in control of his device should you have the Android OS installed on your devices.
There are ways to circumvent that of course and those ways may be ranging from:
Make all devices have one central account on Google Play and activate the service to erase / destroy the device if they get lost, (You can find that in settings since you mentioned it ... under administrator accounts) and leave things right there as they are since that's all you need at the end of the day.
(Requires 1 to be enabled) You should make all your corporate devices (if you want to be that kind of jailer but going that path will make your employees just see you as a not so great employer) to run your piece of software and every single thing that needs access to your network will be running on a proprietary custom encrypted channel (no public encryption) and with the usage of the administrator account you being able to control what the users can install on their devices you can restrict that the only application is that said application that was mentioned above. Now make all that your employees need as a subapplication of your application ;) and on top of that enable these applications to be able to run ONLY if there's GPS signal (so if your employee gets in the tube ... his device will stop working) add / subtract whatever you feel right from this.
Be a good employer and just leave them do whatever they please with the devices you gave them. If you give trust you'll receive joy for the work they're doing meanwhile if you jail people you receive negative emotions and bad performance (eventually it can even go in the direction that people will just leave for a better employer)
From all the 3 I would certain go for the third option if I were in your shoes. From a technology challenge the #2 is I think the only way and a very interesting architecture that you could implement ... in a long time ... so you also need to make sure the effort invested in this is worth the 2 hours your employer will play angry birds at home with his child ;) nevertheless if you're in it for the challenge more than any real world application this is a great chance for you to learn the android operating system from all its perspectives. NDK may help you here but not the way you want it... more along the lines of custom encryption and so on.
EDIT: Sorry for my twisted logic and way of expressing but it's pretty late and has been a very long day.
I am using the syncadaptor extensively in my application for its core functionality. I also use the periodic refresh provided by the syncadaptor. Hence it the "Accounts and sync" is disabled on a phone my application will be pretty much useless. Is it considered a bad practice or rude to do a ContentResolver.setMasterSyncAutomatically(true) to turn the sync on. By just doing a ContentResolver.setIsSyncable doesnt help since if the main account and sync is disabled then periodic syncs dont work.
What is the common way of handling this scenario?
Thanks in advance,
-v-
I would call this bad practice.
There are two different enable flags for sync which serve different functions.
Master Sync is a single enable flag for ALL syncrhonization regardless of account type or content type. This setting is "Auto-Sync" on the Accounts & Sync page and a user typically turns it off to save battery. Some users might (ab)use it to go into a sort of "do not disturb" mode. Programatically, this is checked and unchecked through ContentResolver.setMasterSyncAutomatically()
Secondly, your Account/Authority pair has an enable flag. So, say a google account. You click on the google account and then you get a subpage... Sync drive, sync google play music, sync contacts, sync gmail... etc. Each of those is an Account(com.google) and an Authority(com.android.contacts), paired together. They are individually controllable, so I can have a google account that syncs contacts but not my calendar. Further, even the available items in the list can vary -- I might have one account that has google music installed but another that does not -- so the list of things in that subpage can vary, and what's checked or unchecked can vary. Note that the account shows a green sync circle if there is an authority attached that is syncable, but the account itself is not sycable in isolation. Programatically, this is checked and unchecked through ContentResolver.setSyncAutomatically(), and is enabled/disabled (greyed out) through ContentResolver.setIsSyncable(). You would grey it out when it's not configured.
Your app is well within its rights to turn sync on and off for its own account/authority pair (Though you should respect the user's wishes.) Think like a "sync enabled" checkbox on your app's sync settings page that reflects state to/from the A&S subpage through (get/set)SyncAutomatically()
Yes, your app can change the master sync flag -- But in doing so, you really need to consider whether you're going over the user's head to make decisions about how their phone works. This can help users who don't know how to work their phones, and will seriously piss off users who do. I would instantly uninstall an app that changed my phone-wide sync settings without my permission. The furthest I personally would go is to perhaps popup a dialog to the user when they configure sync -- "Sync is configured, but will not be performed until Auto-Sync is turned on in the Accounts & Sync page. Would you like to turn Auto-Sync on?" and then fire an intent to take them them to the A&S page to turn it on if they say yes. That helps a user understand how their phone works, rather than just changing things behind their back and making it even more a mystery.
Overall, you should never reconfigure the phone without getting consent from the user.
I am developing an application where I have to change the screen lock password on a button click,can anybody tell me how can I do this.
If you are talking about the unlock pass word set in the device settings by the user then the answer is you can't.
If an application could change the unlock password/pattern without user interaction then these security features would be mostly useless. A rogue application could in theory lock the user out of their own device if this were possible.
Edit: if your aim is not to change this value without interaction but just to send them to the correct settings page. You might be able to do that some how. You'd want to look into what intents you can use to start the Settings Activities. But if you are developing this application for use by the general public I would strongly recommend you rethink having try to do anything with the users security settings. As a user if an application prompted and then sent me to the security settings page with the intention of having me change something in there I would immediately uninstall it.
Edit 2: I've never seen it until just now so I don't know for sure what they used to achieve that. Since it states that must be android 2.2+ though I would assume they are using the Device Administration APIs The docs seem to indicate that it can "Prompt user to set a new password." Which I would think means that it is just going to start the settings activity for them. It is not actually changing the password value by itself. This whole API is subject to user activation also. So even if you get installed on a device the user must explicitly "activate" your app before it is able to make use of any of the admin APIs
I am sure the only way this is possible is if you signed your APK with the device key. This way it could access API's that are limited to system applications. This isn't possible for a normal app, only one that is baked into a custom ROM or device manufacturer ROM when building Android from source.
I do not exactly understand what you are trying to do. If you wish to change the lock screen password programmatically, and your'e application is A device administration than you can call:
resetPassword method of DevicePolicyManager like this for example:
m_policyManager.resetPassword("bla bla", DevicePolicyManager.PASSWORD_QUALITY_SOMETHING);