You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Automotive下无需知晓包名,为任意客户端授予FileProvider读取权限

解决方案

方案一:动态捕获访问客户端包名并授权

你可以自定义FileProvider子类,在客户端首次访问时获取其包名并授予临时读取权限。核心思路是利用Binder.getCallingUid()拿到调用方UID,再转换为包名完成授权:

  1. 自定义FileProvider子类:
public class AutoMediaFileProvider extends FileProvider {
    @Override
    public Cursor query(@NonNull Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, @Nullable CancellationSignal cancellationSignal) {
        handleUriPermission(uri);
        return super.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
    }

    @Override
    public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode) throws FileNotFoundException {
        handleUriPermission(uri);
        return super.openFile(uri, mode);
    }

    private void handleUriPermission(Uri uri) {
        String callerPackage = getContext().getPackageManager().getNameForUid(Binder.getCallingUid());
        if (callerPackage != null) {
            getContext().grantUriPermission(callerPackage, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
    }
}
  1. 替换Manifest中的FileProvider配置:
<provider
    android:name=".AutoMediaFileProvider"
    android:authorities="com.your.package.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

临时权限会在系统重启或应用进程销毁后失效,但足以覆盖媒体播放周期内的访问需求。

方案二:将图片纳入MediaStore实现无权限访问

如果你的媒体封面允许公开访问,可将文件插入系统MediaStore,生成的URI默认对所有合法客户端开放(Android 10+无需额外权限):

  1. 插入文件到MediaStore的代码示例:
public Uri insertImageToMediaStore(Context context, File imageFile, String displayName, String mimeType) {
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DISPLAY_NAME, displayName);
    values.put(MediaStore.Images.Media.MIME_TYPE, mimeType);
    values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/YourMediaFolder");

    Uri contentUri = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
            ? MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
            : MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    Uri insertedUri = context.getContentResolver().insert(contentUri, values);
    if (insertedUri == null) return null;

    try (OutputStream os = context.getContentResolver().openOutputStream(insertedUri);
         FileInputStream fis = new FileInputStream(imageFile)) {
        byte[] buffer = new byte[1024];
        int length;
        while ((length = fis.read(buffer)) > 0) {
            os.write(buffer, 0, length);
        }
        return insertedUri;
    } catch (IOException e) {
        context.getContentResolver().delete(insertedUri, null, null);
        return null;
    }
}

生成的insertedUri可直接放入媒体元数据,无需额外授权,缺点是文件会出现在系统图库中,适合公开的媒体资源。

内容的提问来源于stack exchange,提问作者Oderik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:20:24