You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Oreo前台服务被杀死问题及保活诉求

Fixing Foreground Location Service Being Killed on Android 8 Huawei MediaPad T5

Let's tackle the frustrating issue you're facing: your foreground location service getting killed when opening Settings/Camera on your Huawei MediaPad T5 running Android 8, even after applying common fixes like battery optimization exclusion and START_STICKY. I'll walk through the root causes and actionable fixes to keep your service running reliably, or ensure it restarts instantly if killed.

Key Root Causes in Your Current Code

Before diving into fixes, let's highlight the biggest flaws in your existing implementation that are leaving your service vulnerable:

  • WakeLock is a local variable: You create and acquire the WakeLock inside onCreate() as a temporary local variable, which gets garbage collected immediately. This means the WakeLock doesn't stay active, letting the system put your service to sleep.
  • Notification priority is too low: Your notification channel uses IMPORTANCE_DEFAULT, which Android Oreo+ might deprioritize—this is why the system replaces it with the "App using battery" notification.
  • No proper cleanup or fallback restart: Your onDestroy() doesn't clean up resources, and START_STICKY alone isn't reliable on Huawei's custom EMUI for instant restarts.

Actionable Fixes

1. Fix the WakeLock Implementation

Make the WakeLock a class-level member to keep it in memory, and release it properly when the service is destroyed:

public class LocationUpdatesService extends Service {
    // Add this as a class member to retain the lock
    private PowerManager.WakeLock mWakeLock;

    @Override
    public void onCreate() {
        // ... existing code ...
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "wl:location");
        // Use timed acquire to avoid permanent lock (adjust duration as needed)
        mWakeLock.acquire(10 * 60 * 1000L); 
        // ... existing code ...
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Release WakeLock to avoid battery drain
        if (mWakeLock != null && mWakeLock.isHeld()) {
            mWakeLock.release();
        }
        mServiceHandler.removeCallbacksAndMessages(null);
        // Clean up location updates to avoid leaks
        removeLocationUpdates();
    }
}

2. Boost Notification Priority & Avoid System Replacement

Huawei's system replaces low-priority foreground notifications. Update your channel to use IMPORTANCE_HIGH and mark the notification as a critical service:

private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        CharSequence name = getString(R.string.app_name);
        String description = "Real-time location tracking service";
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_HIGH);
        channel.setDescription(description);
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
        channel.setSound(null, null); // Disable sound to avoid user annoyance
        mNotificationManager.createNotificationChannel(channel);
    }
}

// Update your getNotification() method to reinforce service priority
private Notification getNotification() {
    // ... existing intent setup ...
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
            // ... existing actions ...
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setCategory(NotificationCompat.CATEGORY_SERVICE) // Mark as essential service
            .setSmallIcon(R.mipmap.ic_launcher)
            .setOngoing(true) // Prevent users from dismissing the notification
            // ... existing code ...
    return builder.build();
}

3. Bypass Huawei's Custom Battery Restrictions

Huawei's EMUI has aggressive battery optimization that ignores standard Android settings. Take these steps:

  • Add and request battery optimization exemption permission:
    Add this to your AndroidManifest.xml:
    <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
    
    Request user approval in your activity:
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        if (!pm.isIgnoringBatteryOptimizations(getPackageName())) {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivity(intent);
        }
    }
    
  • Guide users to add your app to Huawei's Protected Apps:

    On Huawei devices, go to Settings > Battery > Launch Manager > [Your App] > Set to "Manual management" and enable "Allow background activity", "Auto-launch", and "Run in background".

4. Add a Fallback Restart Mechanism

START_STICKY isn't reliable on Huawei. Use WorkManager to restart the service if it's killed:

  • Add WorkManager dependency to your build.gradle:
    implementation "androidx.work:work-runtime:2.8.1"
    
  • Create a Worker to restart your service:
    public class RestartLocationServiceWorker extends Worker {
        public RestartLocationServiceWorker(@NonNull Context context, @NonNull WorkerParameters params) {
            super(context, params);
        }
    
        @NonNull
        @Override
        public Result doWork() {
            Intent intent = new Intent(getApplicationContext(), LocationUpdatesService.class);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                getApplicationContext().startForegroundService(intent);
            } else {
                getApplicationContext().startService(intent);
            }
            return Result.success();
        }
    }
    
  • Schedule the worker in your service's onDestroy():
    @Override
    public void onDestroy() {
        // ... existing cleanup code ...
        // Schedule periodic restart check
        PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(RestartLocationServiceWorker.class, 15, TimeUnit.MINUTES)
                .setConstraints(new Constraints.Builder()
                        .setRequiredNetworkType(NetworkType.CONNECTED)
                        .build())
                .build();
        WorkManager.getInstance(this).enqueue(workRequest);
    }
    

5. Optimize Location Request Frequency

Your current 1-second update interval is extremely battery-intensive, making the system more likely to kill your service. Adjust to a more reasonable interval (e.g., 5-10 seconds) unless you absolutely need 1-second precision:

private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 5000; // 5 seconds
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;

Additional Tips

  • Remove Toast from background code: Your SavetoServer() method calls Toast.makeText(), which will crash when running in a background thread. Replace it with a log statement, or use a Handler to post to the main thread if you need user feedback.
  • Test real-world scenarios: Avoid testing with adb shell am force-stop since it bypasses normal system kill logic. Instead, open camera/settings and monitor the service via adb shell dumpsys activity services.

内容的提问来源于stack exchange,提问作者ali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:12:32