Android "slows down" when screen is off - android

I’m working on an app that posts to the internet every 30 sec. Everything is working fine until the screen goes off. The timer appears to have slowed down. It takes like 5 min to post. I’ve tried acquiring wake-lock and setforegroundactivity but nothing works. Any ideas here?
Its running as a service, I use this for wake-lock:
PowerManager mgr = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
And the example here to set foreground: http://developer.android.com/reference/android/app/Service.html
I’ve also tried to check what it can be using the debugger, but everything works fine when the USB is connected.
More detail:
To check with regular intervals I use this:
Private void startCheck() {
mCheckHandler.sleep(30000);
}
private CheckHandler mCheckHandler = new CheckHandler();
private class CheckHandler extends Handler {
#Override
public void handleMessage(Message msg) {
Pservice.this.startCheck();
}
public void sleep(long delayMillis) {
this.removeMessages(0);
sendMessageDelayed(obtainMessage(0), delayMillis);
}
};
I set it to acquire wake lock every time it checks the internet. Now it works fine :) Thanks for all your help :)

When the screen goes off, the device will eventually go into a low power state. This low power state basically means your code will not be executed. The reason it takes 5 minutes is because some other app is waking the device up and then your app gets the chance to run again.
By having the device connected via USB, you are preventing the low power state from ocurring.
It sounds like your wake lock is not actually being acquired or it's being released too soon.

Have you tested on any other devices, roms, emulators? Sometimes a simple problem with the way a device manufacture's code can cause issues like that.
What device and rom are you using?

I for one aggressively underclock my android devices when the screen is off.
Also, you mentioned:
I’ve also tried to check what it can be using the debugger, but everything works fine when the USB is connected.
Try using ADB Wireless to debug without being on USB power or just use logging instead.

Related

Android Vibrator on Samsung

I have an issue with Android Vibrator. Basically, I have only one Singletone - scoped class incapsulating the android.os.Vibrator in a way, that it has two methods
startVibrating() {
if (VERSION.SDK_INT < VERSION_CODES.O) {
vibrator.vibrate(PATTERN, 0);
} else {
vibrator.vibrate(VibrationEffect.createWaveform(PATTERN, 0));
}
}
stopVibrating() {
vibrator.cancel();
}
The issue is that on some Samsung devices the Vibrator stops when the phone screen is turned off even I have a WakeLock for CPU.
Recently, we've got into the same situation.
According to Android docs:
If your process exits, any vibration you started will stop.
And you would expect that if you have any CPU-related WakeLock, it should work fine. However, we found that Samsung devices on Android 6 and Android 7 stop the Vibrator in some other cases too. For example, each time when the screen is turned off using PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, even if you take some other wake lock explicitly.
The good news that Samsung stops the Vibrator but it does not prohibit it from the future starts.
We've ended up with the next workaround:
When the screen goes off, the current activity gets onStop() call. So, we check if we should vibrate on that moment, and if we do, we simple start the Vibrator again. Maybe, not the best solution, but it works.

Running a foreground service in Chinese ROMs

I've made a foreground service to constantly scan for BLE devices around me. For some reason it seems to work flawlessly on my stock android device Google pixel and also on Samsung S9+.
But recently I tested the app with a Chinese ROM(Oneplus 6T, Xiaomi Poco F1) the foreground service seems to be killed there after a few minutes. I've used workmanager to restart service but the app is not restarting and I get a bug report instead for the app.
Also on Chinese ROM devices below android 8.0(Xiaomi redmi 3s prime), simple service wont work, I need to use a foreground service there as well. Is there any solution to solving this?
Ask users to whitelist your app. This is the only solution. Even foreground service + wake lock won't work.
There was a discussion last month: Workmanager reliability for periodic tasks on Chinese roms (Xiaomi, Huawei, and so on). There are some useful links in there but eventually you'll have to let users whitelist your app in every ROM's specific battery optimization(or other name) settings.
A simple approach would be to ask user to put your app in non-optimized apps by opening the battery optimization settings at the starting of your app
Use below code to open the setting:
Intent batterySaverIntent=new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS);
startActivity(batterySaverIntent);
Or you can try this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
startForegroundService(new Intent(this, ServiceClass.class));
}

how to disable the question (Do you want to ignore battery optimization?) android studio

I was having problem whit android media player because when I turn off the screen the system goes to sleep mode and stop it and I didnt want that because nobody wants to listen music and have the screen on (who do that?).
I noticed that the problem was on the battery optimizations because if the mobile was plug to power cable it keeps the music playin even if it goes to sleep mode.
I tried with a lot of posibilities to fix it (reading android documentation and trying every thing I was finding in the net) but what works was this code:
public void doPower() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String packageName = getActivity().getPackageName();
PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
try {
//some device doesn't has activity to handle this intent
//so add try catch
Intent intent = new Intent();
intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivity(intent);
} catch (Exception e) {
}
}
}
}
The problem here is: The app at the beginning shows an alert asking the user to disable the battery optimizations and I dont want that, because some users may thinks "this is a bad thing" or "why its asking this?" Because an app like spotify doesnt do it.
How can I avoid the alert message? If I cant, how can I add something else to the message? (something like this: "So you will able to listen the radio with the screen turn off")
Thanks in advance and best regards.
You can't avoid that dialog and asking to avoid battery optimizations is absolutely not needed.
What is needed is a wakelock, as described in the MediaPlayer Using wake locks documentation:
When designing applications that play media in the background, the device may go to sleep while your service is running. Because the Android system tries to conserve battery while the device is sleeping, the system tries to shut off any of the phone's features that are not necessary, including the CPU and the WiFi hardware. However, if your service is playing or streaming music, you want to prevent the system from interfering with your playback.
In order to ensure that your service continues to run under those conditions, you have to use "wake locks." A wake lock is a way to signal to the system that your application is using some feature that should stay available even if the phone is idle.
If you're using MediaPlayer, this only requires you use the setWakeMode() method:
mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
(Note the additional note on the documentation page about holding a wifi lock if you're streaming your media from the network.)

Android Wear - Wake lock not waking up watch

I am trying to make the watch vibrate at specific moments that are not at regular intervals.
I have no problem doing it when the watch's screen is on but it is not working when the watch screen dims out.
I have read a few questions on here and android developer's pages on WakeLocks and I think it's what I need... However it does not work for me. Below is my code, am I doing something wrong?
First, in my Manifest file, I have:
<uses-permission android:name="android.permission.WAKE_LOCK" />
Here is parts of my code:
PowerManager.WakeLock wakeLock;
#Override
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, TAG);
}
private void vibrate(int duration) {
wakeLock.acquire();
Vibrator v = (Vibrator) getBaseContext().getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(duration);
wakeLock.release();
}
The screen doesn't turn on and the watch doesn't vibrate... What am I doing wrong?
Thank you!
If your watch doesn't vibrate when you get a notification or you're not seeing notifications at all, check your watch after each step to see if notifications start working. try the troubleshooting steps below:
Make sure that your watch isn't in Cinema mode.
Make sure that you're getting notifications on your phone.
Make sure that you haven't turned off (block) notifications for specific apps.
Make sure that app notifications and system notifications on your phone are turned on.
Check that your phone is connected to the Internet.
Make sure that your watch is paired with your phone or tablet.
Try restating your phone and your watch.
Check that these apps are up to date: Google Play Services, Google, Android Wear.
Try to awake device by using the flag FLAG_KEEP_SCREEN_ON.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
The advantage of this approach is that unlike wake locks, it doesn't require special permission, and the platform correctly manages the user moving between applications, without your app needing to worry about releasing unused resources.
Another way to implement this is in your application's layout XML file, by using the android:keepScreenOn attribute:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
...
</RelativeLayout>
Using android:keepScreenOn="true" is equivalent to using FLAG_KEEP_SCREEN_ON. You can use whichever approach is best for your app.
You need to keep the wake lock acquired for as long as you want the watch to stay interactive (and vibration to continue -- you must be in interactive to vibrate), but you seem to be releasing the wake lock immediately after acquiring it.
Acquiring wake locks can be risky, so if you're running that code from a watch face service (not clear from your snippet), start a transparent activity when acquiring your wake lock and release it when the activity dies -- this way, you are using the activity lifecycle as a means to stop the vibration and release a wake lock. This is something I implemented in the ustwo Timer Watch Faces (the watch face starts flashing and vibrating in interactive mode when the timer expires), and it's worked well.
Also, remember that to make vibration work, you need to declare the vibrate permission in the manifest:
<uses-permission android:name="android.permission.VIBRATE" />

How can I prevent Galaxy S3 from stopping my app when turning idle?

I am currently updating my Android app with Samsung Galaxy S3 and was shocked that I couldn't stop the phone pausing my app when turning idle. With the Galaxy S2 of our department there doesn't occur this particular problem, if the screen goes black the app still streams data to the sd-card and over the wifi-network. The S3 stops any data-stream.
I tried now fiddling with the energy- and display-settings but I have no solution to the problem so far. My Internet-search was not succesfull either.
Possible solutions are rooting the new phone and thus making advanced settings visible
or increasing the time-out (which i dont like so much as a solution).
Do you have any ideas how to solve the issue or general input that might enlighten me?
Thnx!
BTW: here is the app in question (no ad):
Google Play Link
I have an app which needs to do something similar (it's a running trainer, so it needs to keep talking while the user keeps their phone in their pocket for half an hour or so.)
First off, a caveat for other people reading: don't do this if you don't have to. If you only need to do something periodically, rather than continuously, consider using AlarmManager, which can wake the phone up from sleep every now and again to do something, so won't hit the user's battery so hard.
But, if you're sure you need to keep the phone awake, you need to use a WakeLock. Here's roughly what I do in my service's onStartCommand:
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK;, "RunClockService");
mWakeLock.acquire();
...where mWakeLock is an instance variable of type PowerManager.WakeLock. PARTIAL_WAKE_LOCK keeps the CPU running, but doesn't keep the screen on. The "RunClockService" tag is just used for debugging, according to the documentation. Change it to your class name.
Then, when I finish needing to keep the phone awake:
mWakeLock.release();
You'll also need to add WAKE_LOCK permission to your AndroidManifest.xml:
<uses-permission android:name="android.permission.WAKE_LOCK"/>

Categories

Resources