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

Android 12/13中Activity Recognition后台长时间无结果问题求助

问题分析

在Android 12的Realme 12、Samsung M12设备上,Activity Recognition API在前台/后台初期(数小时内)正常工作,但运行4-5小时或2-3天后停止返回活动状态;Android 14设备无此问题,调试时onStartCommand能正常触发,尝试过Activity-Transition、独立Broadcast Receiver均无效。核心原因是Android 12的后台服务限制+厂商定制系统的后台管控策略,同时当前实现的前台服务未正确启动、PendingIntent可能被系统回收。

解决方案

1. 强制启动前台服务

你的Service声明了foregroundServiceType="location",但未实际启动前台服务。Android 12+对后台服务限制严格,未启动前台的服务会被系统快速回收。在onCreate中添加前台服务启动逻辑:

@Override
public void onCreate() {
    super.onCreate();
    // 启动前台服务
    startForeground(1, createForegroundNotification());
    startActivityRecognitionUpdates();
}

private Notification createForegroundNotification() {
    NotificationChannel channel = new NotificationChannel("activity_track", "活动追踪", NotificationManager.IMPORTANCE_LOW);
    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    manager.createNotificationChannel(channel);

    return new NotificationCompat.Builder(this, "activity_track")
            .setContentTitle("活动追踪中")
            .setContentText("正在监测您的活动状态")
            .setSmallIcon(R.drawable.ic_notification)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .build();
}

2. 定期刷新Activity Recognition注册

系统可能会自动取消Activity Updates的注册,建议在onStartCommand中检查是否收到结果,若未收到则重新注册;同时每隔固定时间(比如2小时)重新调用requestActivityUpdates:

private static final long REFRESH_INTERVAL = 2 * 60 * 60 * 1000; // 2小时
private Handler mRefreshHandler = new Handler();
private Runnable mRefreshRunnable = new Runnable() {
    @Override
    public void run() {
        startActivityRecognitionUpdates();
        mRefreshHandler.postDelayed(this, REFRESH_INTERVAL);
    }
};

@Override
public void onCreate() {
    super.onCreate();
    startForeground(1, createForegroundNotification());
    startActivityRecognitionUpdates();
    mRefreshHandler.postDelayed(mRefreshRunnable, REFRESH_INTERVAL);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    if (ActivityRecognitionResult.hasResult(intent)) {
        final ActivityRecognitionResult result = ActivityRecognitionResult.extractResult(intent);
        mHandler.post(() -> handleActivityRecognition(result));
    } else {
        // 未收到结果,重新注册更新
        startActivityRecognitionUpdates();
    }
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    mRefreshHandler.removeCallbacks(mRefreshRunnable);
    // 停止更新
    if (mActivityRecognitionClient != null && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED) {
        mActivityRecognitionClient.removeActivityUpdates(mActivityRecognitionPendingIntent);
    }
}

3. 绕过厂商后台管控

Realme、Samsung等厂商的定制系统有严格的后台冻结策略,需引导用户进行以下设置:

  • Realme:设置 → 电池 → 应用耗电管理 → 找到你的应用 → 关闭「后台冻结」「异常耗电自动优化」
  • Samsung:设置 → 电池和设备维护 → 电池 → 后台使用限制 → 找到你的应用 → 允许后台活动;关闭「自适应电池」
  • 通用操作:设置 → 应用 → 你的应用 → 电池 → 选择「不受限制」

4. 改用WorkManager保障任务持续性

WorkManager是Android推荐的后台任务调度组件,能更好对抗系统限制。可以用周期性WorkRequest定期检查并重新注册Activity Recognition:

public class ActivityRefreshWorker extends Worker {
    public ActivityRefreshWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        // 检查权限并重新注册Activity Updates
        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACTIVITY_RECOGNITION) == PackageManager.PERMISSION_GRANTED) {
            ActivityRecognitionClient client = ActivityRecognition.getClient(getApplicationContext());
            Intent intent = new Intent(getApplicationContext(), TimeLineTrackingService.class);
            PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
            client.requestActivityUpdates(ACTIVITY_RECOGNITION_DETECTION_INTERVAL, pendingIntent);
        }
        return Result.success();
    }
}

在应用启动时调度周期性任务:

PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(ActivityRefreshWorker.class, 2, TimeUnit.HOURS)
        .setConstraints(new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.NOT_REQUIRED)
                .build())
        .build();
WorkManager.getInstance(context).enqueueUniquePeriodicWork("activity_refresh", ExistingPeriodicWorkPolicy.REPLACE, workRequest);

5. 优化PendingIntent配置

确保PendingIntent的唯一性,避免被系统覆盖或回收。如果使用多个PendingIntent,需使用不同的requestCode;同时确认FLAG_MUTABLE的使用是否符合Android 12+的要求(服务类型的PendingIntent使用FLAG_MUTABLE是允许的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:44:51