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.
Related
Note: I haven't coded anything but looking for a structure/keywords or ideas how it can be achieved.
Use Case:
I have an activity which basically shows some display/data/or does some operation etc when opened manually from button click, notification click etc. Now I want to display the same stuff when a particular condition is satisfied [like my geo location matches that I force to be my home or user home].
1. without user clicking any notification,
2. without opening the activity,
3. without clicking buttons, and
4. without opening the app.
So in short, I want my app to be launched when I am home or reach a geo fence, is it achievable?
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent, let me know if this is the only way to go.
Kindly help!
when a particular condition is satisfied
This is not possible in general. For example, Android has nothing built-in with the ability to do something automatically based upon when your neighbor's cousin's daughter posts something on Stack Overflow. Even though that is a particular condition that could be satisfied, Android does not know your neighbor, nor your neighbor's relatives, nor the neighbor's cousin's children, nor the online actions of your neighbor's cousin's daughter.
There are specific things that Android can handle that offer the ability to give you control for related conditions, such as AlarmManager for getting control at certain points in time, or JobScheduler for getting control periodically when the environment is proper (e.g., we have connectivity and are on a charger).
Your question uses a geofence as an example. The Play Services SDK offers geofence APIs that you can use, that can give you control when the user enters a particular region.
I want my app to be launched when I am home or reach a geo fence, is it achievable?
You are welcome to call those geofence APIs, providing a PendingIntent that points to a WakefulBroadcastReceiver, which in turn points to an IntentService, where you can go do something.
If by "my app is launched", you mean bring up one of your activities, while that is technically possible using an activity PendingIntent, you may make your users very unhappy for interrupting what they are doing (e.g., collecting Pokémon). Please consider using a Notification instead.
I am aware of Pending Intents, but seems they need the activity to be opened once and register the intent
Nothing of your app will ever run until the user manually runs your app (e.g., taps on your home screen launcher icon) or until something else uses an explicit Intent to start one of your components. At that point, you can call the geofence APIs, assuming that you somehow know where the user's home is.
Most likely, you need the user to spend time in the activity simply to collect the data from the user about where they want the geofences to be established.
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.
My activity opens the systems prefs when no internet connection is connected.
What is the best way to close the system prefs and go back to the activity as soon as the user activates wifi or 3g.
Is there a way to get a result using startActivityForRsults()?
Should I wake up the activity using a listener that detects when a connection is on?
Thank you or your thoughts
What is the best way to close the system prefs and go back to the activity as soon as the user activates wifi or 3g.
The user can press the BACK button to do this.
Is there a way to get a result using startActivityForRsults()?
AFAIK, none of the Settings activities are designed for startActivityForResult().
Should I wake up the activity using a listener that detects when a connection is on?
No.
Please do not break Android navigation. What you are proposing is the same as if the user clicked a link on your Web page to visit a different site, clicked on a checkbox on that third-party page, and you now expecting to have some way to force the user immediately back to your page. That's not how the Web works, and what you are proposing is not how Android works. Please allow the user to decide what to do next, whether that is press BACK to return to you, press HOME to go do something else, etc.
Yes, basically you need to register a BroadcastReceiver for android.net.conn.CONNECTIVITY_CHANGE and then check the intent that you receive to make sure that you now how network connectivity and if so then you can use startActivity to go on to what ever of your activites you want to display next.
I want my application to start when someone modifies a content provider. A setting to be specific. The settings framework calls "notify" when a value is set.
If my app was started I would use registerContentObserver() I guess, but is is not started.
Can define some intent-filter in my manifest that wakes up my application. A back up plan would be to have a service running all the time that has registered a listener, but that seems like a wast or resources.
Thanks, Ola
This isn't directly supported by the Android device because starting an app every time a ContentProvider's data changes is a path to really killing your battery. To do the query, you'd need to do it in a service, which as you said is understandably undesirable.
Secondly, starting an intent is a user action. Android really doesn't support allowing an application to start all on its own without user request... Doing so would be impolite! What if your user was doing something important and then your app pops up on top? Remember the user is in control, not you. Instead of starting an application, consider placing a Status Bar Notification so the user can deal with it when it's convenient for them.