Android入门开发:Broadcast SMS Receiver收信后RecyclerView无显示问题求助
问题排查及修复方案
1. 清单文件配置错误
- SmsReceiver未配置短信接收的intent-filter,无法捕获系统短信广播,修改
标签如下:
<receiver android:name=".SmsReceiver" android:enabled="true" android:exported="true"> <intent-filter android:priority="1000"> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver>
2. 权限申请逻辑缺失
- RECEIVE_SMS属于危险权限,需要和READ_SMS一起动态申请,同时要重写权限申请回调,用户授权后加载短信列表。修改MainActivity权限申请逻辑,新增onRequestPermissionsResult方法:
// 先将adapter提为全局变量,方便后续更新 private ArrayAdapter adapter; // onCreate里初始化adapter时赋值全局 adapter= new ArrayAdapter(); // onCreate里的权限申请修改为 if(ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(getBaseContext(), Manifest.permission.RECEIVE_SMS) == PackageManager.PERMISSION_GRANTED) { refreshSmsInbox(); }else { final int REQUEST_CODE_ASK_PERMISSIONS = 123; ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS, Manifest.permission.RECEIVE_SMS}, REQUEST_CODE_ASK_PERMISSIONS); } // 新增权限申请回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if(requestCode == 123){ boolean allGranted = true; for(int result : grantResults){ if(result != PackageManager.PERMISSION_GRANTED){ allGranted = false; break; } } if(allGranted){ refreshSmsInbox(); } } }
3. refreshSmsInbox方法逻辑错误
- 存在Cursor强转SmsModel的崩溃问题,同时未取全字段、未通知适配器更新、未关闭Cursor,修改如下:
public void refreshSmsInbox() { ContentResolver contentResolver = getContentResolver(); Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null, null, null); if(smsInboxCursor == null) return; int indexBody = smsInboxCursor.getColumnIndex("body"); int indexAddress = smsInboxCursor.getColumnIndex("address"); int indexId = smsInboxCursor.getColumnIndex("_id"); int indexTime = smsInboxCursor.getColumnIndex("date"); if (indexBody < 0 || indexAddress <0 || indexId <0 || indexTime <0 || !smsInboxCursor.moveToFirst()) { smsInboxCursor.close(); return; } smsModel.clear(); do { String id = smsInboxCursor.getString(indexId); String address = smsInboxCursor.getString(indexAddress); String body = smsInboxCursor.getString(indexBody); // 时间戳转格式化时间 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault()); String time = sdf.format(new Date(smsInboxCursor.getLong(indexTime))); smsModel.add(new SmsModel(id, address, body, time, address)); } while (smsInboxCursor.moveToNext()); smsInboxCursor.close(); // 通知适配器更新 adapter.setSmsModel(smsModel); }
4. SmsModel构造函数错误
- 构造函数中Number字段写死,修改如下:
public SmsModel(String id, String contactNumber, String contactSms, String time, String number) { Id = id; ContactNumber = contactNumber; ContactSms = contactSms; Time = time; // 不要写死,使用传入的参数 Number = number; }
5. 新短信更新逻辑为空
- 实现updateList方法,收到新短信后添加到列表顶部并更新:
public void updateList(final String smsMessage) { runOnUiThread(() -> { String[] split = smsMessage.split("\n", 3); if(split.length >=3){ String address = split[0].replace("SMS From: ", ""); String body = split[1]; String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date()); smsModel.add(0, new SmsModel(System.currentTimeMillis()+"", address, body, time, address)); adapter.setSmsModel(smsModel); recyclerView.scrollToPosition(0); } }); }
6. 列表项布局高度错误
- smsview.xml根布局高度设置为match_parent会导致每一项占满全屏,修改为wrap_content:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp">
7. SmsReceiver兼容高版本系统
- Android 6.0以上创建SmsMessage需要传入format参数,修改onReceive方法:
@Override public void onReceive(Context context, Intent intent) { Bundle intentExtras = intent.getExtras(); if (intentExtras != null) { Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE); String format = intentExtras.getString("format"); String smsMessageStr = ""; String address = ""; String body = ""; for (int i = 0; i < sms.length; ++i) { SmsMessage smsMessage; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { smsMessage = SmsMessage.createFromPdu((byte[]) sms[i], format); } else { smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]); } body += smsMessage.getMessageBody().toString(); address = smsMessage.getOriginatingAddress(); } smsMessageStr += "SMS From: " + address + "\n"; smsMessageStr += body + "\n"; Toast.makeText(context, smsMessageStr, Toast.LENGTH_SHORT).show(); if(MainActivity.instance() != null){ MainActivity.instance().updateList(smsMessageStr); } } }
注:上述代码需要自行导入缺失的包(SimpleDateFormat、Date、Manifest等),运行前请先在系统设置中确认app已获得短信权限。
内容的提问来源于stack exchange,提问作者user16634163
相关产品推荐
相关产品推荐

