I am building application which can get location using NETWORK_PROVIDER periodically in background without using GPS_PROVIDER. I am using ALARM_SERVICE and WakeLock(PARTIAL_WAKE_LOCK). but the problem which i am facing is that internet connection gets disconnected once the screen goes off. when I unlocks the phone I starts receiving the location, but when the screen goes off I am not getting the locations.
Is it because:
Internet connection gets paused once the screen goes off and also when I unlocks the screen I get the USSD code messages of Data Usage, so does it means my internet connection goes off once the screen goes off?
Even though the internet connection is on but location doesn't gets updated in background as the screen is in off state.
I am using GpsTracker class to get location from here and using AlarmManager get location periodically. also in LatLongBroadcastReceiver class i am fetching a location.
Intent intent = new Intent(GPSlatlongActivity.this,
LatLongBroadcastReceiver.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
pendingIntent = PendingIntent.getBroadcast(
GPSlatlongActivity.this.getApplicationContext(), 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
(AlarmManager.INTERVAL_FIFTEEN_MINUTES / 15),
pendingIntent);
According to documentation WifiManager.WifiLock
Allows an application to keep the Wi-Fi radio awake. Normally the Wi-Fi radio may turn off when the user has not used the device in a while. Acquiring a WifiLock will keep the radio on until the lock is released. Multiple applications may hold WifiLocks, and the radio will only be allowed to turn off when no WifiLocks are held in any application.
I guess you need this lock. Acquire this lock if the device is connected to WiFi. But please
Note that WifiLocks cannot override the user-level "Wi-Fi Enabled" setting, nor Airplane Mode. They simply keep the radio from turning off when Wi-Fi is already on but the device is idle.
Unless your application has a very good reason to keep a Wi-Fi connection, you should really try to respect the user's preference to disable WiFi when the screen locks. Your application will quickly cause the device to consume significantly more power by using any sort of lock. As mentioned by others, in your case, you'll need the PowerManager.PARTIAL_WAKE_LOCK to keep the CPU running (without preventing the screen from locking) and WifiManager.WakeLock to keep Wi-Fi connected.
You'll probably find the setting causing this behaviour under the system settings for Wi-Fi, under advanced Wi-Fi settings:
By disabling this setting on a device with mobile data, your network location listener should still work as Android will continue to use Google's Location API in the background to resolve the device's location based on cellular towers.
If your device is also switching off mobile data, perhaps some power-saving application is disabling it. BlueEFFICIENCY and Juice Defender are some apps that have an option for this optimization, but HTC and Sony have included some power saving
options on their devices that may also be exhibiting this behavior.
Related
I'm developing a tracking application and I need to prevent users from turning off the basic sensors used to determine the location. I can not modify the devices ROM or have root access (or at least it would be very desirable to had not), but I thought of using the Device Administration API to perform these functions through the Profile Owner or Device Owner modes. I'm basically looking for a method to block these functions in Android settings.
I'm unsure about whether this is possible and how to do it, I have not found examples in GitHub for applications that have implemented this. Could anyone give me a light, some example or specific documentation?
I tried to follow these three documentations, without success in finding a solution to this specific feature:
https://source.android.com/devices/tech/admin
https://developer.android.com/guide/topics/admin/device-admin
https://developers.google.com/android/management/introduction
This is an excerpt from what I've been trying:
setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true);
setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, active);
setUserRestriction(UserManager.DISALLOW_CONFIG_BLUETOOTH, active);
private void setUserRestriction(String restriction, boolean disallow){
if (disallow) {
mDevicePolicyManager.addUserRestriction(mAdminComponentName, restriction);
} else {
mDevicePolicyManager.clearUserRestriction(mAdminComponentName,
restriction);
}
}
DISALLOW_CONFIG_BLUETOOTH
Added in API level 18
public static final String DISALLOW_CONFIG_BLUETOOTH
Specifies if a user is disallowed from configuring bluetooth. This does not restrict the user from turning bluetooth on or off. The default value is false.
This restriction doesn't prevent the user from using bluetooth. For disallowing usage of bluetooth completely on the device, use DISALLOW_BLUETOOTH.
This restriction has no effect in a managed profile.
Key for user restrictions.
Type: Boolean
You cannot prevent them from turning GPS, WIFI and Bluetooth off. What you can do is have an implementation as below or use this library.
https://github.com/KI-labs/gps-permission-checks-livedata
You can't, obviously for security reasons. If you want to achive something like that you'll probably need to modify the devices ROM. You should create a BroadcastReceiver and keep tracking Internet and Bluetooth connection changes, than you can properly handle it when user disconnect them pausing the service, showing a dialog, finishing the application or whatever you need to do.
It would be pretty weird if an app could have some control of user settings, imagine if you install an app, then suddently you can't disable wi-fi anymore until you unistall it. You can't do that for a good reason
Preventing bluetooth/wifi disconnection will also prevent usage of aircraft mode, that is a security issue bounded in the ROM and not overridable.
As suggested above your option is to monitor for wifi/bluetooth/gps deactivations and prompt the user with an alert.
By the way, GPS is not affected by aircraft mode, as it's a pure receiver and doesn't make active transmissions. In that case GPS will be always active and collecting informations (if active and the phone is not in power save mode, aka relying on wifi location). I suggest you to check if the user activated aircraft mode, in order to be less annoying with your alerts (air mode is mandatory in same situations, and should be considered "legal" by your application, and maybe less critical than an user voluntary disconnection
In simple words, You cannot, but you can listen to when wifi is enabled/connected, and you can prompt a dialog stating the reason.
This way it gives the user a more concise grip on what needs to be done.
Just a suggestion
I've developed an application that streams music (via internet connection) using service and having trubles streaming content without phone going idle.
While i was developing my application each time i tried case mentioned below the music was reproducing fine.
Use case : search song, select song from results, play song, screen off -> auto play next song from result list
I'm developing using real device - Huawei Mate 20 Lite - OS v8.01 so while debugging it gotta use USB cabel.
Like i said following the use case above while hooked on USB the auto play while screen off works good. The case it doesn't work good is when the cable is not connected (only mobile data turned on).
What I've figured out is that phone when connected on USB is probably keeping the device awake and it doesn't go to idle mode while when not connected after around 5mins the device probably shuts down processes that cost energy or it shuts down connection to mobile data i'm not sure and there's where i need you guys.
Also I've tested app using HTC U Play - OS v6.0 and the streaming goes smooth without interrupts while screen off and phone wasn't touched for 10+mins.
Also I've tried to acquire wakelock inside oncreate and without releasing it just to see if it helps and it doesn't.
pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wl.acquire();
This problem you are facing can be due to the fact that after Andriod 6.0, all apps are getting optimized for optimizing the battery usage.
If you really think, the reason behind the application to go killed is inactivity. Then, probably, its because of battery optimization software itself.
You can enable another permission while installing the app on the device where you can update the list of unoptimized app by adding an entry for your app.
Originally, you will be able to do the manual settings by following below instruction.
. Head for the ‘Settings‘ app and then ‘Battery‘
. On the ‘three dots‘ menu, top right, you’ll find ‘Battery optimisation‘.
. Here you’ll see a list of all applications which shouldn’t be ‘optimised‘ (for which read ‘can be handled by Doze and App Standby’) – by default the list is usually very small, with almost all apps enabled for ‘optimisation’. Which is fine for general users, but if, like me, you want a few applications to live outside of the new battery optimisations, then tap on the ‘Not optimised‘ pick list and choose ‘All apps‘
. As you’d expect, every application on your phone is listed (this may be quite long) – swipe down until you find the application(s) that you particularly want to always keep running. Tap on the application name
. From the two choices, check the box for ‘Don’t optimise‘.
I'm writing small app for our workers, to work in terrain, and I have some idea. We want to track their location for better logistics and better work control.
App is not a problem for me, but button to turning on/off GPS/Locations Manager. Is there any possibility to set GPS always ON, and unable to turn OFF, or maybe something that will detect turning OFF, and turn GPS back ON every few seconds (?bash script?).
I've rooted my device (GALAXY GIO) and I have full access to CLI. I know how to disable/enable almost every device, but GPS is still puzzle for me...
Is it possible to do something like that without changing ROM? Current ROM is 2.3.6 Gingerbread.
Thanks in advance!, Mike
Use services and place this code in your services.
String provider = Settings.Secure.getString(getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (!provider.contains("gps")) {
// if gps is disabled
final Intent poke = new Intent();
poke.setClassName("com.android.settings","com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
sendBroadcast(poke);
/*
* Toast.makeText(getApplicationContext(), "GPS On Success",
* Toast.LENGTH_SHORT).show();
*/
}
There's no reliable way of doing what you need, other than exploits (which looks like only work for 2.2 and some 2.3 builds) and custom ROMs (If you can find one that does this).
In Android, the user has control over most functions. Android is aimed for personal use, and it's not very well suited for this kind things. You migh be better off switching to another platform (e.g.: BlackBerry) that allowed you to do this, or even reading data via bluetooth from a GPS tracking device that is turned on always. They can still disable bluetooth, so you migh need to search for a fully autonomous GPS tracking device (there are many available in the market, some of them also have a SIM card so they can send data in real time).
As a final note, I'd say most workers will gladly enable the GPS if they are required to do so, and in case they disable it, you can still detect it and report to a WS or log, in order to ask them for an explanation later.
So I have a need to force an android phone to register/de-register itself repeatedly. I'm accomplishing this via AT commands while the phone is in modem/diag mode over a USB serial connection. I check the current registration state via +CGREG and then assuming it's registered I kill the RF with +CFUN, check again, then turn the RF back on and allow the phone to search out and re-register itself normally. I issue the +CGREG command every few seconds to check on the status and once it's re-registered I repeat.
Now, sometimes I'll do this once or twice, sometimes it'll go five times and then the phone will decide to restart itself... it's a little frustrating and not the desired result.
Anyone have any ideas why the phone would reboot without command due to what I'm doing here? The phone will operate normally any number of hours while I'm not running these tests.
Psudo-Process:
while(true)
AT+CGREG? // starting state < usually registered>
AT+CFUN=4,0 // turn off RF
AT+CGREG? // verify it's not registered
AT+CFUN=1,0 // turn RF back on
while ( )
AT+CGREG? // check registration state every 2 seconds
end
end
On a side note: +COPS is a better option here, however the phone doesn't [fully] support it. The phone is an HTC Thunderbolt.
I have an application in which I am sending network data over WiFI. Everything is fine until I turn the display off or the device goes to 'sleep'. I'm already locking the WiFi however, it seems to be the case that the CPU speed ramps down when in sleep which causes my streaming to not behave properly (i.e. packets don't flow as fast as I would like as they do when the device is not sleeping).
I know that I possibly can/possibly should address this at the protocol level however, that might possibly not be possible as well...
Is there any way to "prevent the CPU from going to 'sleep' when the screen is off"? If so, how? If not, any advice on how to keep the speed of my WiFi stream consistent whether the device is in sleep mode or not?
Grab a PARTIAL_WAKE_LOCK from the PowerManager. You'll also need to add the WAKE_LOCK permission to your manifest.
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Tag");
wl.acquire();
//do what you need to do
wl.release();
Okay, so, after much more research and experimenting, it seems that the real issue is the fact that, at least on some phones, their WiFi goes into a 'partial sleep' mode EVEN IF you've taken the WiFi lock. It seems that this is what the 'WIFI_MODE_FULL_HIGH_PERF' flag was invented for when taking the WiFi lock... unfortunately, this flag is only available on some devices/Android versions (I have no clue as to which but, it wasn't available to me). So, therefore, it isn't a fix for all devices.
The only "solution" (which is actually a kludge) seems to be to 'detect when the screen is turned off and then, set an alarm that turns the screen back on immediately thereafter'. The links that helped a little bit with this are:
How to keep a task alive after phone sleeps?
and
http://android.modaco.com/topic/330272-screen-off-wifi-off/
I hope that this helps people who are experiencing WiFi disruption when the phone goes to sleep/screen is turned off (and the phone is unplugged/disconnected [e.g. you won't see this effect when connected to adb; only when the phone is running with nothing connected to it]).