如何让Android自定义DocumentsProvider仅本应用可访问
实现仅本应用可访问的自定义DocumentsProvider
DocumentsProvider属于Android系统文档访问框架的一部分,直接设置exported=false会导致系统服务无法调用它,进而触发安全异常,这是正常现象。以下是两种可靠的实现方案:
方案一:签名级自定义权限
创建一个签名级保护的自定义权限,确保只有与你的应用签名一致的应用(也就是你自己的应用)才能获取权限,其他应用无法申请访问:
- 在Manifest中声明签名级权限:
<permission android:name="com.yourapp.private.DOC_PROVIDER_PERM" android:protectionLevel="signature" />
- 在Provider标签中配置该权限,同时保持
exported="true":
<provider android:name=".YourCustomDocumentsProvider" android:authorities="com.yourapp.documents.provider" android:permission="com.yourapp.private.DOC_PROVIDER_PERM" android:exported="true" />
之前你尝试自定义权限但失效,大概率是因为protectionLevel设为了normal或dangerous,这类权限其他应用可以主动申请,所以才会被其他应用访问到。
方案二:在Provider内部校验调用者包名
直接在DocumentsProvider的核心方法中校验调用者的包名,非本应用调用直接拦截:
@Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // 获取调用者的包名 String callerPackage = getContext().getPackageManager().getNameForUid(Binder.getCallingUid()); String myPackage = getContext().getPackageName(); if (!myPackage.equals(callerPackage)) { throw new SecurityException("Unauthorized access: only " + myPackage + " is allowed"); } // 执行正常的查询逻辑 return super.query(uri, projection, selection, selectionArgs, sortOrder); }
你需要在所有对外暴露的核心方法(比如openDocument、createDocument、deleteDocument等)中添加这段校验逻辑。这样即使其他应用能发现Provider的存在,也无法执行任何操作。
额外注意
- 不要设置
grantUriPermissions="true",避免通过Uri权限授予的方式让其他应用获得访问权; - 本应用内部访问Provider时,直接通过
ContentResolver调用即可,无需额外权限申请,因为应用自身默认拥有访问自身组件的权限。
内容的提问来源于stack exchange,提问作者user38561
相关产品推荐
相关产品推荐

