如何在Xamarin.Forms中列出收件箱所有短信?
问题解决指南
1. 错误原因(CS0120)
ContentResolver是非静态成员,不能直接通过类名调用,必须通过上下文(Context)实例访问,比如当前Activity的this.ContentResolver。
2. 修正后的完整代码
using System.Collections.Generic; using Android.Content; using Android.Database; using Android.Net; // 假设在Activity类中实现 public class SmsActivity : Activity { private List<string> _smsItems = new List<string>(); public void GetAllSms() { // Android 6.0及以上必须动态申请权限 if (CheckSelfPermission(Android.Manifest.Permission.ReadSms) != Android.Content.PM.Permission.Granted) { RequestPermissions(new string[] { Android.Manifest.Permission.ReadSms }, 100); return; } string inboxUri = "content://sms/inbox"; string[] reqCols = new string[] { "_id", "thread_id", "address", "person", "date", "body", "type" }; Uri uri = Uri.Parse(inboxUri); // 通过当前上下文的ContentResolver执行查询 ICursor cursor = this.ContentResolver.Query(uri, reqCols, null, null, null); if (cursor != null && cursor.MoveToFirst()) { do { string messageId = cursor.GetString(cursor.GetColumnIndex(reqCols[0])); string threadId = cursor.GetString(cursor.GetColumnIndex(reqCols[1])); string address = cursor.GetString(cursor.GetColumnIndex(reqCols[2])); string name = cursor.GetString(cursor.GetColumnIndex(reqCols[3])); string date = cursor.GetString(cursor.GetColumnIndex(reqCols[4])); string msg = cursor.GetString(cursor.GetColumnIndex(reqCols[5])); string type = cursor.GetString(cursor.GetColumnIndex(reqCols[6])); // 用List收集所有短信,避免循环中覆盖数据 _smsItems.Add($"{messageId},{threadId},{address},{name},{date},{msg},{type}"); } while (cursor.MoveToNext()); // 关闭cursor释放资源 cursor.Close(); } // 此处可将_smsItems绑定到UI组件(如ListView/RecyclerView)展示 // 示例:var adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, _smsItems); // listView.Adapter = adapter; } // 处理权限申请结果 public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults) { base.OnRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100 && grantResults.Length > 0 && grantResults[0] == Android.Content.PM.Permission.Granted) { // 权限通过后重新获取短信 GetAllSms(); } } }
3. 关键修正点
- ContentResolver调用:将
ContentResolver.Query改为this.ContentResolver.Query(Activity内);若在非Activity类中,需传入Context对象调用context.ContentResolver.Query。 - 数据存储优化:原代码用数组会覆盖之前的短信,改用
List<string>存储所有条目。 - 资源释放:查询完成后关闭
ICursor,避免内存泄漏。 - 权限处理:Android 6.0(API 23)及以上必须动态申请
READ_SMS权限,否则查询会失败。
4. 额外说明
- 若要获取所有短信(含发件箱、草稿),可将Uri改为
content://sms/,通过type字段区分类型(1=收件箱,2=发件箱)。 - 部分高版本Android系统对第三方应用读取短信有额外限制,需确保用户已授权。
内容的提问来源于stack exchange,提问作者Duy Anh
相关产品推荐
相关产品推荐

