【问题标题】:Failed opening content provider (FileProvider)未能打开内容提供程序 (FileProvider)
【发布时间】:2019-12-04 17:25:19
【问题描述】:

我正在尝试通过FileProvider API 共享文件。在服务器端,文件已配置如下:

public void prepareData() {
    File apkFile = new File(context.getCacheDir(), "ngp-187002.apk");


    Uri apkFileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", apkFile);
    Log.i(TAG, "Apk file Uri: " + apkFileUri.toString() + ", fileSize = " + apkFile.length());

    context.grantUriPermission(NGP_UPDATER_PACKAGE_NAME, apkFileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);

    Intent updaterIntent = new Intent();

    updaterIntent.setClassName(NGP_UPDATER_PACKAGE_NAME, NGP_UPDATER_SERVICE_CLASS_NAME);
    updaterIntent.setAction(EXTERNAL_ACTION_UPDATE_NGP);
    // updaterIntent.putExtra(EXTERNAL_PARAM_APK_LOC, TARGET_APK_DIR);
    updaterIntent.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
    updaterIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    // Since NgpApp & NgpUpdater are signed by the same key, we can start the process
    context.startService(updaterIntent);
}

并且AndroidManifest.xml已经配置如下:

<provider
  android:authorities="${applicationId}.fileprovider"
  android:exported="false"
  android:grantUriPermissions="true"
  android:name="android.support.v4.content.FileProvider">
  <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/fileproviderpath"/>
</provider>

文件路径xml文件如下

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="."/>
</paths>

接收方是一个 IntentService,我正在尝试获取如下流:

String apkLocUri = intent.getData();
is = getBaseContext().getContentResolver().openInputStream(apkLocUri);

但我明白了

12-05 11:57:44.941   784   827 I NGPPackageInstallerService: the apkLocUri is: content://com.xxx.yyy.fileprovider/cache/ngp-187002.apk
12-05 11:57:44.989   784   827 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 416)
12-05 11:57:44.990   784   827 I ActivityThread: Removing dead content provider:android.content.ContentProviderProxy@40db0b5
12-05 11:57:44.994  2831  8889 W ActivityManager: unstableProviderDied: caller 10058 says ContentProviderConnection{a983e7c/com.xxx.yyy/android.support.v4.content.FileProvider->784:com.xxx.yyyupdater/u0a58 s1/1 u1/1 +29s191ms} died, but we don't agree
12-05 11:57:44.999 31747 31747 W Binder:31433_5: type=1400 audit(0.0:103879): avc: denied { read } for path="/data/data/com.xxx.yyy/cache/ngp-187002.apk" dev="dm-0" ino=2972 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:system_app_data_file:s0 tclass=file permissive=0
12-05 11:57:45.041   784   827 E JavaBinder: !!! FAILED BINDER TRANSACTION !!!  (parcel size = 416)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService: apk file does not exist
12-05 11:57:45.046   784   827 E NGPPackageInstallerService: java.io.FileNotFoundException: Failed opening content provider: content://com.xxx.yyy.fileprovider/cache/ngp-187002.apk
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1187)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:984)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:837)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:791)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at com.xxx.yyyupdater.PackageInstallerService.installPackage(PackageInstallerService.java:60)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at com.xxx.yyyupdater.PackageInstallerService.onHandleIntent(PackageInstallerService.java:51)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.os.Handler.dispatchMessage(Handler.java:102)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.os.Looper.loop(Looper.java:154)
12-05 11:57:45.046   784   827 E NGPPackageInstallerService:    at android.os.HandlerThread.run(HandlerThread.java:61)

【问题讨论】:

  • 请同时显示文件路径 xml 文件。
  • @blackapps 已按请求附加
  • 我没看错。它打印的文件大小是否正确?
  • 是的,文件大小正确
  • 我在这个问题上附加了更多的 adb 日志

标签: android android-fileprovider


【解决方案1】:

上次我与内容提供商合作时,我这样创建权限: 通过在您的AndroidManifest,xml 文件中添加这些代码来创建读写权限:

    <uses-permission android:name="com.anystring.READ_PERMISSION"/>
    <uses-permission android:name="com.anystring.WRITE_PERMISSION"/>

    <permission android:name="com.anystring.READ_PERMISSION"
        android:protectionLevel="signature" />
    <permission android:name="com.anystring.WRITE_PERMISSION"
        android:protectionLevel="signature" />
<application
// ... rest of the code ...
/>

接下来在你的提供者中,你在你的提供者代码中赋予这些权限,所以它看起来像这样:

<provider
  android:authorities="${applicationId}.fileprovider"
  android:readPermission="com.anystring.READ_PERMISSION"
  android:writePermission="com.anystring.WRITE_PERMISSION"
  android:enabled="true"
  android:exported="true"
  android:multiprocess="true"
  android:grantUriPermissions="true"
  android:name="android.support.v4.content.FileProvider">
  <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/fileproviderpath"/>
</provider>

所以基本上这种方式,你创建一个权限。只有在清单文件中被授予权限的应用才能访问数据。签名级保护确保只有您公司的应用程序才能读取彼此的数据。因此,根据您的需要更改/删除它。 我希望这有效,祝你好运。

【讨论】:

  • 当 android:exported="true" 我得到一个运行时崩溃说 FileProvider 不应该设置为导出。所以我想这不是一个选择
【解决方案2】:

这很有趣,日志消息avc: denied { read } 提示了我,this post 启发了我。所以我的第一反应是为什么不更改文件夹。所以我将文件夹更改为context.getExternalCacheDir() 一切都按预期工作!

context.getCacheDir() = /data/user/0/com.xxx.yyy/cache
context.getExternalCacheDir() = /storage/emulated/0/Android/data/com.xxx.yyy/cache

还有一点值得一提的是provider app是一个system app,它的uid是system,可能这就是SELinux阻止其他的原因应用程序来访问它。

【讨论】:

  • 奇怪的故事。使用 FileProvider 会认为私有路径无关紧要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多