如何使用Flutter在Android端通过编程方式删除收件箱短信?
在Android中通过Flutter编程删除收件箱短信
由于Flutter框架本身没有提供直接操作短信系统的API,我们需要通过**原生通道(MethodChannel)**调用Android原生代码来实现该功能,步骤如下:
1. 配置权限
首先在Android项目的权限清单中添加所需权限:
- 打开
android/app/src/main/AndroidManifest.xml,添加以下权限:
<uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <!-- Android 11+ 额外需要接收短信权限 --> <uses-permission android:name="android.permission.RECEIVE_SMS" />
2. 动态申请权限
Android 6.0及以上需要动态申请敏感权限,这里可以使用permission_handler插件简化操作:
- 在
pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter permission_handler: ^10.2.0
- 编写权限申请代码:
import 'package:permission_handler/permission_handler.dart'; Future<bool> requestSmsPermissions() async { final status = await Permission.sms.request(); return status.isGranted; }
3. 创建Flutter与原生的通信通道
Flutter端代码
创建一个工具类,通过MethodChannel调用原生方法:
import 'package:flutter/services.dart'; class SmsManager { static const MethodChannel _channel = MethodChannel('sms_manager'); // 删除指定ID的短信 static Future<bool> deleteSms(int smsId) async { try { final bool result = await _channel.invokeMethod('deleteSms', {'smsId': smsId}); return result; } on PlatformException catch (e) { print('删除失败: ${e.message}'); return false; } } // 获取收件箱内所有短信的ID列表 static Future<List<int>?> getInboxSmsIds() async { try { final List<dynamic> ids = await _channel.invokeMethod('getInboxSmsIds'); return ids.cast<int>(); } on PlatformException catch (e) { print('获取短信ID失败: ${e.message}'); return null; } } }
Android原生端代码
在MainActivity中实现MethodChannel的方法处理逻辑:
import android.content.ContentResolver import android.net.Uri import android.provider.Telephony import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "sms_manager" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "deleteSms" -> { val smsId = call.argument<Int>("smsId") smsId?.let { val isDeleted = deleteSms(it) result.success(isDeleted) } ?: result.error("INVALID_ARG", "短信ID不能为空", null) } "getInboxSmsIds" -> { val ids = getInboxSmsIds() result.success(ids) } else -> result.notImplemented() } } } // 删除指定ID的短信 private fun deleteSms(smsId: Int): Boolean { val resolver: ContentResolver = contentResolver val smsUri: Uri = Telephony.Sms.CONTENT_URI val whereClause = "${Telephony.Sms._ID} = ?" val whereArgs = arrayOf(smsId.toString()) val rowsDeleted = resolver.delete(smsUri, whereClause, whereArgs) return rowsDeleted > 0 } // 获取收件箱短信ID列表 private fun getInboxSmsIds(): List<Int> { val ids = mutableListOf<Int>() val resolver: ContentResolver = contentResolver val smsUri: Uri = Telephony.Sms.CONTENT_URI val projection = arrayOf(Telephony.Sms._ID) val selection = "${Telephony.Sms.TYPE} = ?" val selectionArgs = arrayOf(Telephony.Sms.MESSAGE_TYPE_INBOX.toString()) resolver.query(smsUri, projection, selection, selectionArgs, null)?.use { cursor -> while (cursor.moveToNext()) { val id = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Sms._ID)) ids.add(id) } } return ids } }
4. 调用示例
在Flutter页面中执行删除操作:
void deleteFirstInboxSms() async { // 先申请权限 bool hasPermission = await requestSmsPermissions(); if (!hasPermission) { print("短信权限未获取"); return; } // 获取收件箱短信ID List<int>? smsIds = await SmsManager.getInboxSmsIds(); if (smsIds?.isNotEmpty == true) { // 删除第一条短信 bool isDeleted = await SmsManager.deleteSms(smsIds.first); print(isDeleted ? "短信删除成功" : "短信删除失败"); } else { print("收件箱无短信"); } }
重要注意事项
Android 10(API 29)及更高版本中,只有被设置为默认短信应用的应用才能执行删除短信操作。如果你的应用不是默认短信应用,删除请求会直接失败,需要引导用户将应用设置为默认短信应用。
内容的提问来源于stack exchange,提问作者Enes Karaçomak
相关产品推荐
相关产品推荐

