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

如何在Android 11上用Delphi 10.4分享二进制文件(SQLite数据库)

Android 11下Delphi分享SQLite文件失败的解决方案

你的问题核心在于Android 11(API 30+)的Scoped Storage权限限制,其他应用无法直接通过文件路径Uri(file://)访问你的应用存储目录下的文件,即使是你创建的共享目录。之前Android 10的代码逻辑在Android 11下失效,必须改用FileProvider来生成带临时访问权限的内容Uri,具体步骤如下:

1. 配置FileProvider

1.1 修改AndroidManifest.xml

在项目的AndroidManifest.xml中添加FileProvider配置,注意替换com.yourpackage.name为你的应用包名:

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="com.yourpackage.name.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

1.2 创建文件路径配置文件

创建res/xml/file_paths.xml文件(需添加到Delphi项目的Deployment列表,部署路径设为res\xml),根据你的文件存储位置选择对应配置:

  • 如果文件在应用外部私有目录(即ExternalPath下的myapp):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-files-path name="myapp_files" path="myapp/" />
</paths>
  • 如果文件在公共文档目录(如Documents/myapp):
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="public_myapp" path="Documents/myapp/" />
</paths>

2. 修改Delphi分享代码

替换原有的Uri生成逻辑,改用FileProvider生成内容Uri,并添加临时访问权限:

var    
  Database : String;
  intent : JIntent;
  FileObj : JFile;
  fileuri : JParcelable;
  Authority : string;

begin
  Database := TPath.Combine(ExternalPath, 'file.db'); // 或对应公共目录路径
  intent := TJIntent.Create;   
  intent.setAction(TJIntent.JavaClass.ACTION_SEND);   
  // 使用更精确的SQLite MIME类型,替代*/*
  intent.setType(StringToJString('application/x-sqlite3')); 
  intent.putExtra(TJIntent.JavaClass.EXTRA_TEXT, StringToJString('Important data'));

  // 构建FileProvider的authority(与AndroidManifest中配置一致)
  Authority := JStringToString(SharedActivity.getPackageName) + '.fileprovider';
  FileObj := TJFile.JavaClass.init(StringToJString(Database));
  // 通过FileProvider生成带权限的Uri
  fileuri := JParcelable(TJFileProvider.JavaClass.getUriForFile(SharedActivity, StringToJString(Authority), FileObj));

  intent.putExtra(TJIntent.JavaClass.EXTRA_STREAM, fileuri);
  // 给接收应用添加临时读取权限
  intent.addFlags(TJIntent.JavaClass.FLAG_GRANT_READ_URI_PERMISSION);

  SharedActivity.startActivity(TJIntent.JavaClass.createChooser(intent, StrToJCharSequence('Share with')));
end;

关键说明

  • Scoped Storage限制:Android 11禁止跨应用直接访问file://类型的Uri,必须通过FileProvider这类ContentProvider机制提供临时访问权限。
  • MIME类型优化:使用application/x-sqlite3替代*/*,能让接收应用(如Telegram、邮件客户端)更准确识别文件类型,避免处理异常。
  • 权限临时授予:FLAG_GRANT_READ_URI_PERMISSION确保接收应用在本次分享过程中能读取该文件,无需永久权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:33:18