Android读取全部短信的方法返回空值问题排查求助
排查Android短信读取方法返回空值的问题
1. IMessage类的id属性Setter存在无限递归问题
你的IMessage类中id属性的setter逻辑错误,会触发无限递归调用,无法正确设置id值,进而可能导致短信对象初始化失败:
public string id { get => _message_id; set => id = value; // 错误:赋值给属性本身导致无限递归 }
修复方案:
修改setter为直接赋值给私有字段:
public string id { get => _message_id; set => _message_id = value; }
2. Cursor未做判空处理,直接访问引发异常或空列表
cr.Query()在权限未正确获取、URI无效或系统限制时会返回null,你的代码直接访问cursor.Count和cursor.MoveToFirst(),会导致两种情况:
- 若cursor为null,
cursor.Count直接抛出空指针异常,后续代码无法执行,返回空列表 - 即使未崩溃,cursor为null时
MoveToFirst()不会进入循环,列表始终为空
修复方案:
在使用cursor前先判空,并通过try-finally确保cursor始终被关闭:
List<IMessage> GetMessages() { string message_uri = "content://sms/"; List<IMessage> lstSms = new List<IMessage>(); Uri message = Uri.Parse(message_uri); ContentResolver cr = ContentResolver; ICursor cursor = cr.Query(message, null, null, null, null); // 先判空避免空指针 if (cursor == null) { return lstSms; } try { if (cursor.MoveToFirst()) { do { IMessage sms = new IMessage(); sms.id = cursor.GetString(cursor.GetColumnIndexOrThrow("_id")); sms.Address = cursor.GetString(cursor.GetColumnIndexOrThrow("address")); sms.Message = cursor.GetString(cursor.GetColumnIndexOrThrow("body")); sms.ReadState = cursor.GetString(cursor.GetColumnIndexOrThrow("read")); sms.Time = cursor.GetString(cursor.GetColumnIndexOrThrow("date")); string type = cursor.GetString(cursor.GetColumnIndexOrThrow("type")); sms.FolderName = type == "1" ? "inbox" : "sent"; lstSms.Add(sms); } while (cursor.MoveToNext()); } } finally { // 确保cursor在异常时也能关闭 cursor.Close(); } return lstSms; }
3. Android版本权限与URI兼容性问题
- Android 10+权限限制:即使声明并请求了
READ_SMS权限,Android 10(API 29)及以上系统对短信读取有更严格的限制,部分设备可能需要验证权限是否真正被授予。 - URI有效性:旧的
content://sms/URI在部分Android版本中可能被限制,建议使用更精确的URI分别读取收件箱和已发送短信:- 收件箱:
content://sms/inbox - 已发送:
content://sms/sent
- 收件箱:
权限验证方案:
调用GetMessages()前添加权限检查:
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadSms) != Permission.Granted) { ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.ReadSms }, 100); return; } // 权限已授予,执行读取逻辑 List<IMessage> messages = GetMessages();
内容的提问来源于stack exchange,提问作者TechGeek
相关产品推荐
相关产品推荐

