当前位置:首页 > 行业动态 > 正文

安卓后台发送短信

安卓后台发送短信需声明SEND_SMS权限,通过JobIntentService或WorkManager实现异步处理,注意Android 10+ 后台限制,需动态申请运行时权限并处理BIND_JOB_SERVICE

权限配置与申请

AndroidManifest.xml配置

<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application>
    <service android:name=".SmsService" />
    <receiver android:name=".BootReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
</application>

运行时权限申请(Android 6.0+)

// 在Activity中检查并申请权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SEND_SMS}, REQUEST_SMS_CODE);
}

后台服务实现方案

方案类型 适用场景 核心API 存活能力 电池消耗
传统Service 简单后台任务 startService() 低(易被回收)
JobService 精确调度任务 JobScheduler
WorkManager 弹性延迟任务 WorkManager 高(兼容系统调度) 极低

推荐实现:基于WorkManager的持久化方案

// 定义Worker类
public class SmsWorker extends Worker {
    @NonNull
    @Override
    public Result doWork() {
        // 获取应用上下文
        Context context = getApplicationContext();
        // 构建短信内容
        SmsManager smsManager = SmsManager.getDefault();
        ArrayList<String> messageSegments = smsManager.divideMessage("测试短信内容");
        List<PendingIntent> sentIntents = new ArrayList<>();
        // 循环发送分段消息
        for(String segment : messageSegments){
            sentIntents.add(PendingIntent.getBroadcast(context,0,new Intent(SENT_ACTION),0));
        }
        smsManager.sendMultipartTextMessage("目标号码", null, messageSegments, sentIntents, null);
        return Result.success();
    }
}
// 调度任务
WorkManager workManager = WorkManager.getInstance(context);
OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(SmsWorker.class)
    .setInitialDelay(1, TimeUnit.HOURS) // 延迟1小时执行
    .build();
workManager.enqueue(request);

关键注意事项

  1. 电池优化白名单:需引导用户手动将APP加入电池优化白名单

    • 设置路径:系统设置 > 电池 > 应用耗电排行 > [APP名称] > 允许后台运行
    • 未加入白名单可能导致服务无法正常执行
  2. 系统版本适配
    | Android版本 | 限制措施 | 解决方案 |
    |————-|———-|———-|
    | Android 8.0+ | 后台执行限制 | 使用JobScheduler/WorkManager |
    | Android 9.0+ | 新增前台服务限制 | 添加FOREGROUND_SERVICE权限并显示通知 |
    | Android 12+ | 更严格的隐私沙盒 | 使用系统级API接口 |

  3. 网络状态监听:建议在发送前检查网络状态

    ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();

问题与解答

Q1:为什么后台发送短信时经常收不到?

A:主要原因包括:

  • 服务被系统回收:需使用WorkManager或JobScheduler保证执行
  • 权限未生效:需确保动态申请并通过用户授权
  • 设备休眠:需在WakeLock保护下执行核心代码
  • 运营商限制:部分运营商会拦截非正常时段的短信

Q2:如何实现每天定时发送报告?

A:推荐使用WorkManager的周期性任务:

PeriodicWorkRequest periodicRequest = new PeriodicWorkRequest.Builder(ReportWorker.class, 1, TimeUnit.DAYS)
    .setFlexDuration(Long.MAX_VALUE) // 允许灵活执行时间
    .build();
workManager.enqueue(periodicRequest);

需注意:

  1. 设置setConstraints()指定仅在充电/非漫游时执行
  2. 在Worker中使用doWork()方法封装发送逻辑
  3. 通过WorkContinuation处理失败重试机制
0