上一篇
安卓后台发送短信
- 行业动态
- 2025-04-24
- 1
安卓后台发送短信需声明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);
关键注意事项
电池优化白名单:需引导用户手动将APP加入电池优化白名单
- 设置路径:系统设置 > 电池 > 应用耗电排行 > [APP名称] > 允许后台运行
- 未加入白名单可能导致服务无法正常执行
系统版本适配
| Android版本 | 限制措施 | 解决方案 |
|————-|———-|———-|
| Android 8.0+ | 后台执行限制 | 使用JobScheduler/WorkManager |
| Android 9.0+ | 新增前台服务限制 | 添加FOREGROUND_SERVICE
权限并显示通知 |
| Android 12+ | 更严格的隐私沙盒 | 使用系统级API接口 |网络状态监听:建议在发送前检查网络状态
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);
需注意:
- 设置
setConstraints()
指定仅在充电/非漫游时执行 - 在Worker中使用
doWork()
方法封装发送逻辑 - 通过
WorkContinuation
处理失败重试机制