I am looking to add a Notification when the app is started. That will ask the user if they have a WiFi or unlimited connection. If they pick yes then they can go into the app, if no then the app closes with a message 'Try again later...'
To find out if wifi is available, you don't need to ask the user, you can ask the OS to give you that information using this method:
http://developer.android.com/reference/android/net/NetworkInfo.html#getTypeName%28%29
If you wish, you can also check if there is a connection using isConnected() and if you want to test if the connection is working, you could make a network call to confirm.
If you want to have the user confirm (I don't think you need to) then create an activity that runs when the app starts, it asks them to confirm, and then depending on their selection either starts the app's main activity, or shows a message and exits.
I don't know the details of your app, but if it were me I would probably:
- Automate the network detection
- If there's no network, run the app as usual, but just grey out and disable the main UI, and show a message like "Please connect to a Wifi network".
- Consider including a user interface within the app that the user can use to turn on wifi.
I think that's much tidier than just exiting the app, as that means if they get the "no wifi" warning the app assists them by providing an option to enable it.
Related
I am having a hard time understanding the right way to handle a user changing a permission while my app is still running in the background.
In my app I have a location class that registers for location changes and when the location changes the status is sent to a server. However this runs in the background.
When my app is launched I check with the user if its ok to use location services and if so I proceed with setting up that class. However the user can background my app and go into settings and remove that permission. I can, and will certainly check that the permission is enabled in my location class before asking for a location from the location service to avoid a crash. However I am not in an activity when a location comes in so I am not sure how to prompt them that my app needs location services.
EDIT:
It does seem that android restarts your app if a permission has been revoked in settings. However I have confirmed that as of now android does NOT restart your app if a permission was granted though settings.
I read somewhere that your app gets killed when the user changes the permissions on Android-M so you can be sure that this won't change while your app is running. It will been killed when this changes.
As reference check this video: https://www.youtube.com/watch?v=f17qe9vZ8RM
However I am not in an activity when a location comes in so I am not sure how to prompt them that my app needs location services.
Raise a Notification, alerting the user that your app cannot do its intended work without the permission that they revoked. Have the Notification tie into an Activity via a PendingIntent where the user will be able to grant that permission.
Along with CommonsWare suggestion, you can have the onProviderDisabled() to know which provider (gps, network) has been disabled and accordingly requestLocationUpdate() for the one that is still enabled. If both are disabled, see if at least Cell Location is of useful for your app. If so, you can send Cell Location at least till user see notification and re-enable the permission.Use PhoneStateListener to do that.
I would like to try a more modern 2020+ answer to the core question:
However I am not in an activity when a location comes in so I am not sure how to prompt them that my app needs location services.
However I am not in an activity when a location comes in so I am not sure how to prompt them that my app needs location services.
If you are in a normal end user environment:
Respect the users choice to revoke the permission and only display the missing permissions to the user if she opens your activity.
On modern devices your service needs to display a notification in the bar to even be allowed to continue running - change the notification to show the problem.
You are allowed to just ask for most permissions but the user has the ability to deny on the 2nd attempt. After that you get auto-no without anything displayed.
Some permissions (e.g. write settings and overlay) can be accessed by opening the settingspages for this directly - which can be done from a service but will be seen as harassment.
If you are in a work environment:
Best use an official mdm solution (COPE).There you can totally zombiefy your devices allowing nothing or anything and pretty much anything in between. User cannot even enter settings if you dissallow or not even turn the device off or.. you name it.
And apps can get all permissions they need and be installed automatically from the getgo.
For both (eben in mdm sometimes a more powerful user might be wanted):
Please build an extra Activity or Fragment (if you have one that uses those) dedicated to display why your app needs a permission and a button for the user to initiate the request/opening of settings.
It may be much work but users and google will be happy :)
I am working on a test application that is going to be used for automated bluetooth device testing. My application basically connects a phone to a Bluetooth device so that the device can be tested with an Android device, the nature of the testing isn't relevant to this question really.
My issue is, one of the Bluetooth devices I am working with has voice prompts that will speak the name of your phone contact when getting an incoming call from them. In order to do this the Bluetooth device needs access to the Android's phone book. So the first time the device connects, I get a dialog message that pops up with a Phone book access request, saying the device is requesting access to contacts and call history. I am trying to find a way to respond to this request inside of the test application, the idea of this application is that it is supposed to be automated, so I don't want to have to have somebody come by the phone and click yes to this request, but I definitely need to respond yes or else the voice prompts won't work properly.
I am able to find when the request pops up using the onWindowFocusChanged function, and I confirmed using the debugger that this function is called when the request pops up. At first I thought maybe I could dismiss it with ACTION_CLOSE_SYSTEM_DIALOGS, but as it turns out this won't work, and even if it did dismiss the dialog (and it doesn't dismiss it), according to the documentation this Intent only requests that a dialog is dismissed and ultimately the dialog will decide how it wants to handle that.
//This function will be called when the dialog is shown.
#Override
public void onWindowFocusChanged(boolean isTrue) {
super.onWindowFocusChanged(isTrue);
if (!isTrue) {
Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
this.sendBroadcast(closeDialog);
}
}
Dismissing it isn't really what I wanted to accomplish anyways because I want to be able to chose the yes option so my device gets access to the contacts properly. My other idea, which is sort of a hack would be to just figure out where on the screen the notification is located and inject a touch event at the location of the yes option. This is not really how I want to do it because I would have to basically figure out the location with trial and error because I don't believe I can get access to the dialog from inside an app to figure out it's exact location. Also it would constrain me to only being able to use whatever specific devices I took the time to find the coordinates of the yes button.
Any ideas?
I am getting problem in my app .where i need to mark the particular Settings I have used the following code:
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
Its open the setting page but it does not mark the particular Entities.How could i get the automark option Could anybody help me out!!#Thanks
this is not possible, unless you have the rights and access the setting directly (not with an intent, but with the Settings class), and even though, I'm not sure you can.
What you can do is what google maps does. When your app starts, check if the gps is enabled, if it is not, display an alert notifying the user, with a button to quit the app, and a button to go to the settings screen. When the user comes back from Settings screen, test again.
If the action that you are trying to do was allowed then users would be very mad if some application would turn on their wireless connection or even worse the GPS sensor.
This change is available to change only by the user him self. So as mentioned the most you can do in case you need Internet connection or GPS sensor available is to present a user with the relevant message and fire an intent that will take them to the settings screen to change this setting them self.
My first question, (but long time lurker on StackOverflow) so please don't be too scathing.
I am creating an Android App that has the capability of using a web service to update an SQLite database. Of course, this can only happen if the phone has internet connectivity. I understand how to navigate to the phone settings from the App, but I would like to know if the phone is now connected to the internet upon the user returning to the App.
I have considered using the onStart() and onResume() methods, but is there any way to determine where the user 'came from'. A good example would be the Google Maps/Navigation App. If the user is in Google Maps and presses the Navigation icon, it opens the Navigation App/activity and if GPS is not on, a dialog box shows asking the user if he or she wants to be taken to the GPS settings. They can choose OK, turn on GPS and press the back button to return to the Navigation App. If GPS is now on, they can proceed, otherwise the App shows the dialog box again.
This is good, except the user is allowed to continue, in my case, if there is no internet connectivity. But if there is initially no connectivity, and the user goes away and turns it on, and comes back, then I want to call the method to call the service.
I only want the internet check to happen on opening the App, and upon returning from the phone settings. If I use the onStart() method, the check will happen every time the user opens the activity.
So my question is, how do I check that there is internet connectivity only in the onCreate() method AND when the user returns from the phone settings?
Thanks in advance.
I am writing a service to collect location readings while my application is running in the foreground. In the LocationListener, I would like to use the onProviderDisabled() method to open a dialog telling the user that the location provider is disabled, and have a button on the dialog that will launch the system's location settings panel, allowing the user to enable the location provider if they choose. If this was an activity, I would launch the system settings using startActivityforResult(), but I can only use startActivity from a service.
My question is this: is there a way I can open the settings from a service, and have this new activity close and return to my application after the user changes a setting?
EDIT: What I'm trying to achieve is a Service running from the moment the application opens until it closes and collecting location readings, maintaining a best estimate of location for use in the application. If the LocationListener within the service has onProviderDisabled called, I want this to cause a dialog to open that will give the user the option to go to the System Settings and enable location providers (or cancel and carry on, although some of the application's features won't work without location). I agree that the perhaps the Service isn't the place to do the dialog/activity launch part as it is a background component with no UI, but I'm not sure where the code for this should go.
From the edit to your question and the comment to Sam's answer, I'd basically do a check in the Activity (or all Activities) of the app and launch the dialog and subsequent 'Settings' page from there (if the user chooses to go to Settings).
Basically, have the Service do what it needs to based on the current environment the main Activity encounters (provider disabled/enabled). If your Service will be running when there is no user front-end then have it compensate and reduce its 'duties' accordingly.
Also, in that scenario, Sam's idea of using a notification (which in turn could cause the Settings to be opened) is a good middle ground.
EDIT To explain a little further. Take something as simple as an email app. There are two aspects to this...
Firstly there's a UI - when the user opens their email app if 'the network' is disabled the user is told so with a dialog with the option to go to network settings to enable the network. Pressing BACK (from Settings) will return to the email app and it will attempt to download any new emails. If the user decides not to enable the network they can still view previously downloaded emails (similar to partial functionality in you situation).
Secondly there is a background service which periodically (every 15 mins, 30 mins, 1 hr etc) will attempt to download any new emails even if the UI is closed. If the network is disabled it will simply go to sleep (until next download time).
In theory if a user disables the network, the background email service 'could' provide a dialog or notification to say "You do realise I can't work now?"...this is kind of what you want to do BUT if the service has other things to do it can simply do those and ignore any network-related tasks. Next time the user fires up the Activity, they then get a dialog with the option to enable the network.
Does that make more sense?
Yes, Service has the ContextWrapper.startActivity() method which will open the desired Settings menu. The user will select what they would like to enable then touch back to return your Activity. Once back in your activity you can check LocationManager.isProviderEnabled(). Unfortunately a service cannot take an Activity result.
just curious. service may run even if the user is not seeing the screen, or even the screen may be turned off. is it a good idea, showing a dialog from the service.
anyway, since you know how to show an activity, in the onCreate fire the intent for the settings and finish it once you get to onActivityResult.
sure this is a simple hack.
EDIT: if you are not sure where it should go. the best i can think, and even seen in some apps is the notification area.