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

Android如何不打开应用24小时后台运行任务 实现定时发送短信功能

方案1:前台服务(Foreground Service)+ 定时触发器

你当前使用的普通后台Service在Android 8.0(API 26)及以上版本会被系统严格限制,应用退到后台几分钟后就会被回收,转成前台服务后优先级更高,会在通知栏显示常驻通知,被系统杀死的概率大幅降低。具体实现步骤如下:

  • 第一步:添加必要权限,在AndroidManifest.xml中声明:
<!-- 基础前台服务权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- Android 14以上数据同步类前台服务需要额外加这个权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<!-- Android 13以上需要通知权限才能显示前台服务通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 发送短信权限 -->
<uses-permission android:name="android.permission.SEND_SMS" />
  • 第二步:改造现有Service为前台服务,在Service的onCreate方法中添加如下代码:
@Override
public void onCreate() {
    super.onCreate();
    // Android 8.0以上必须先创建通知渠道
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel("sms_sync_channel", "短信同步服务", NotificationManager.IMPORTANCE_LOW);
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);
    }
    // 构建前台服务通知
    Notification notification = new NotificationCompat.Builder(this, "sms_sync_channel")
            .setContentTitle("短信同步服务运行中")
            .setContentText("正在定时拉取短信发送任务")
            .setSmallIcon(R.mipmap.ic_launcher) // 替换为你应用的图标资源
            .build();
    // 启动前台服务,通知ID不能为0
    startForeground(1001, notification);
}
  • 第三步:替换原有Handler定时逻辑,Handler在后台容易因为系统休眠出现偏差甚至被回收,推荐用WorkManager实现定时任务,兼容性更好还能适配Doze模式:
    首先在Module级的build.gradle中添加依赖:
dependencies {
    def work_version = "2.8.1"
    implementation "androidx.work:work-runtime:$work_version"
}

创建执行核心逻辑的Worker类:

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

    @NonNull
    @Override
    public Result doWork() {
        // 在这里写你的Retrofit拉取服务器数据、发送短信的逻辑
        return Result.success();
    }
}

在Service的onStartCommand方法中启动周期任务:

// 定义每2分钟执行一次的周期任务
PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(SmsSyncWorker.class, 2, TimeUnit.MINUTES)
        .build();
// 启动唯一周期任务,避免重复创建
WorkManager.getInstance(this).enqueueUniquePeriodicWork("sms_sync_task", ExistingPeriodicWorkPolicy.KEEP, periodicWork);
  • 第四步:启动服务时适配高版本系统要求:
Intent intent = new Intent(context, YourSmsService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(intent);
} else {
    context.startService(intent);
}
注意事项
  • 小米、华为、OPPO等国产ROM有自定义的后台管控逻辑,即使配置了前台服务,也需要引导用户手动打开应用的「自启动权限」「后台活动权限」,否则应用退到后台依然可能被杀死。
  • 系统进入Doze模式后会拉长周期任务的执行间隔,如果你必须严格保证2分钟执行一次,可以申请忽略电池优化权限,先在清单中声明权限:
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

再主动弹框引导用户同意权限申请即可。

  • Android 6.0以上SEND_SMS属于危险权限,需要先动态申请权限,不能只在清单文件中声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:15:03