Allowing an Android App to Stop Normally While Keeping Battery Optimization Exemption

In many Android projects—especially those involving background processing, real-time synchronization, tracking, IoT, streaming, or enterprise integrations—developers often implement two distinct mechanisms:

  1. Preventing the application from stopping
  2. Preventing Android from restricting the application due to battery optimization

At first glance, these may seem similar. In reality, they are technically different behaviors controlled by different Android components.

In this article, we’ll explain:

  • The difference between “preventing app stop” and “battery optimization exemption”
  • Where this behavior is typically implemented
  • How to safely remove the “prevent app stop” logic
  • How to keep battery optimization exemptions intact
  • Best practices for modern Android versions (Android 10+ and beyond)

This guide is fully anonymized and applies to any Android application architecture (native Java, Kotlin, hybrid frameworks, etc.).


Understanding the Two Mechanisms

1️⃣ Preventing the App from Stopping

This usually involves:

  • Foreground services
  • Sticky services (START_STICKY)
  • WakeLocks
  • stopWithTask="false" in the Manifest
  • Auto-restart via BroadcastReceivers
  • AlarmManager or WorkManager restart loops

This mechanism forces the application or service to continue running even when:

  • The user swipes the app away
  • The system attempts to kill it
  • The task is removed from recent apps

This is often implemented for:

  • Tracking applications
  • Messaging apps
  • VoIP services
  • Real-time monitoring systems

2️⃣ Preventing Battery Optimization Restrictions

This mechanism tells Android:

“Do not apply Doze mode or background battery restrictions to this app.”

It typically involves:

  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission
  • Prompting the user via:
Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS

This does NOT prevent the app from stopping.

It only allows it to:

  • Run background tasks more reliably
  • Avoid aggressive system throttling

Where to Look in Your Codebase

If you want to remove only the “prevent app stop” logic, search for the following patterns.


🔎 1. Foreground Services

Look for:

startForeground(notificationId, notification);

Or:

startForeground(...)

Also check for:

service.stopForeground(false);

What to Change

If the service is no longer required to run permanently:

  • Remove startForeground(...)
  • Convert to a normal background service
  • Or migrate to WorkManager if appropriate

🔎 2. Sticky Services

Search for:

return START_STICKY;

or:

START_REDELIVER_INTENT

Replace With:

return START_NOT_STICKY;

This ensures that if the system kills the service, it will NOT automatically restart it.


🔎 3. AndroidManifest.xml Service Configuration

Check your manifest for:

<service
    android:name=".YourService"
    android:stopWithTask="false" />

Fix:

android:stopWithTask="true"

This ensures the service stops when the user removes the app from recent apps.


🔎 4. WakeLocks

Search for:

PowerManager.WakeLock

Example:

wakeLock.acquire();

If your app no longer needs to keep the CPU awake continuously:

if (wakeLock.isHeld()) {
    wakeLock.release();
}

Failing to release a WakeLock can make the app appear “unstoppable.”


🔎 5. BroadcastReceivers Restarting the App

Search for:

BOOT_COMPLETED
ACTION_PACKAGE_REPLACED
ACTION_MY_PACKAGE_REPLACED

Or custom receivers restarting services in:

onReceive()

Example:

context.startService(new Intent(context, MyService.class));

Remove automatic restarts if no longer needed.


How to Keep Battery Optimization Exemption

If you still want Android to avoid battery restrictions, keep:

Manifest Permission

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

User Prompt

Intent intent = new Intent(
    Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
    Uri.parse("package:" + getPackageName())
);
startActivity(intent);

This allows:

  • Background tasks
  • Periodic sync
  • Network operations
  • Push-based services

Without forcing the app to resist system termination.


Recommended Modern Approach (Android 12+)

For most production applications, the ideal architecture is:

Use CaseRecommended Component
Periodic background workWorkManager
Immediate but short taskForegroundService (temporary)
Long-running background workForegroundService (user-visible only)
Deferred syncWorkManager + battery exemption

Avoid:

  • Permanent sticky services
  • Infinite restart loops
  • Aggressive WakeLocks

Modern Android aggressively restricts background execution, and fighting the system often leads to:

  • Play Store policy violations
  • Battery drain complaints
  • App suspension risks

Safe Refactoring Strategy

If you are unsure where the “prevent stop” behavior lives:

Step 1

Search entire project for:

START_STICKY
startForeground
WakeLock
stopWithTask
BOOT_COMPLETED

Step 2

Temporarily log service lifecycle:

@Override
public void onDestroy() {
    Log.d("ServiceDebug", "Service destroyed");
}

Step 3

Swipe the app from recent apps and observe:

  • Does the service restart?
  • Does a notification remain?
  • Is CPU still active?

Common Mistake

Many teams assume that:

“Ignoring battery optimizations” = “App cannot be stopped”

This is incorrect.

Battery exemption:

  • Allows background execution
  • Does not prevent manual or system termination

Sticky services + foreground services:

  • Are what keep apps running forcibly

Final Architecture Recommendation

If your requirement is:

✔ Allow the user to close the app normally
✔ Prevent Android from aggressively restricting background tasks

Then the correct combination is:

  • START_NOT_STICKY
  • No permanent foreground service
  • No forced restart receiver
  • Keep battery optimization exemption
  • Use WorkManager for background reliability

Conclusion

Separating “prevent app stop” from “prevent battery optimization restriction” is critical in modern Android development.

Removing:

  • Sticky services
  • Permanent foreground services
  • WakeLocks
  • Auto-restart receivers

Will restore normal stop behavior.

Keeping:

  • Battery optimization exemption
  • Proper background scheduling

Ensures system compatibility and stable execution.

A clean architecture aligned with Android lifecycle principles leads to:

  • Better battery performance
  • Higher Play Store compliance
  • Improved user trust
  • Easier long-term maintenance
This article is inspired by real-world challenges we tackle in our projects. If you're looking for expert solutions or need a team to bring your idea to life,

Let's talk!

    Please fill your details, and we will contact you back

      Please fill your details, and we will contact you back