Android SDK 30+ SMS Content Provider空校验后仍报Uri null问题
你看到的getAuthority()空指针/Uri必须不为空异常并不是你本地的Uri为空导致的,这是Android Binder跨进程通信的异常堆栈重写现象:短信Provider运行在系统进程,处理你的插入请求时抛出的异常,经过序列化传递到你的应用进程后,打印的堆栈会混淆调用来源,看起来像是本地代码的空指针,实际问题出在配置、权限或入参上,按以下步骤修复即可:
1. 修正清单文件queries配置
你当前的queries是占位符配置,完全没有生效,需要替换为实际匹配短信Provider的配置:
<queries> <intent> <action android:name="android.intent.action.VIEW" /> <data android:mimeType="vnd.android-dir/mms-sms" /> </intent> <!-- 明确声明需要访问的短信Provider authority --> <provider android:authorities="sms" /> <provider android:authorities="mms-sms" /> </queries>
QUERY_ALL_PACKAGES属于敏感权限,仅访问短信Provider不需要申请,上线时如果保留这个权限会被应用商店驳回,建议直接移除。
2. 补充ContentProviderClient非空校验
Android 10以上acquireContentProviderClient如果找不到对应Provider会直接返回null,你当前代码没有做非空判断就调用insert会触发空指针,同时推荐用close()替代已废弃的release()方法:
public void save(AppCompatActivity context, SMSListener listener) { mContext = context; try { ContentValues values = returnContentValues(); ContentResolver resolver = context.getContentResolver(); Uri uri = Telephony.Sms.CONTENT_URI; if (resolver != null && uri != null) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { ContentProviderClient client = resolver.acquireContentProviderClient(Telephony.Sms.CONTENT_URI); if (client != null) { client.insert(uri, values); client.close(); } else { listener.onCompleted(false); return; } } else { resolver.insert(uri, values); } else { listener.onCompleted(false); return; } listener.onCompleted(true); } catch (Exception ex) { ex.printStackTrace(); listener.onCompleted(false); } }
3. 检查ContentValues必填字段
Android 10以上插入短信时必须包含以下字段,缺省会导致Provider内部处理时抛出异常:
Telephony.Sms.ADDRESS:发件人/收件人号码Telephony.Sms.BODY:短信内容Telephony.Sms.DATE:毫秒级时间戳Telephony.Sms.TYPE:短信类型(1=收件箱,2=已发送,3=草稿)Telephony.Sms.READ:已读状态(0=未读,1=已读)
4. 权限校验
确认你已经动态申请了WRITE_SMS、READ_SMS运行时权限,且应用已经被设置为系统默认短信应用,这是Android 4.4以后写入短信Provider的必要条件。
内容的提问来源于stack exchange,提问作者exploitr
相关产品推荐
相关产品推荐

