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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 17:51:13