抖音开放平台Logo
开发者文档
控制台

Android 分享支持 FileProvider 方式
收藏
我的收藏

如果分享的媒体文件中涉及文件路径(如图片类型、视频类型),建议开发者使用 Android 7.0 版本及其以上设备,判断抖音版本支持的情况下,更新为 FileProvider 方式进行分享。​

背景信息​

从 Android N(7.0) 开始,将严格执行 StrictMode 模式,将不允许在 App 间使用 file:// 的方式传递一个 File ,仍使用 file 方式会抛出 FileUriExposedException 的错误,直接引发崩溃。因此需要使用 FileProvider 方式来文件分享。​

操作步骤​

第一步:集成支持 FileProvider 的 SDK​

参见 Android 接入。​

第二步:接入​

    1.在 Application 中,初始化 DouYinOpenApiFactory。​
@Override public void onCreate() { super.onCreate(); String clientkey = "[Client Key]"; // 修改为在开发者应用登记页面申请的clientkey DouYinOpenApiFactory.init(new DouYinOpenConfig(clientkey)); }
    2.在 Manifest 中申请权限,注册接收回调 activity。​
<uses-permission android:name="android.permission.INTERNET" /> <!--如果第三方自定义了接收回调的activity则可以跳过此步骤--> <!--置于application结点下--> <activity android:name=".douyinapi.DouYinEntryActivity" android:launchMode="singleTask" android:taskAffinity="你的包名" android:exported="true"> </activity>
抖音 12.5.0 及以上版本已经适配使用 FileProvider 的方式来进行媒体文件分享。以下是具体的适配说明。​

第三步:FileProvider 适配​

    1.配置。​
在项目的 AndroidManifest.xml 中添加相关配置,示例如下:​
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_paths" /> </provider> <!--${applicationId}为你的应用包名-->
res/xml 目录(如果没有 xml 目录,则新建一个)下,添加文件file_provider_paths.xml,内容如下:​
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="sharedata" path="shareData/" /> </paths>
external-files-path 表示通过 Context.getExternalFilesDir(null) 接口获取到的目录下的文件才可被共享,其他未配置的路径均不可被分享。同样的节点可以配置多个,以支持多个不同的子目录,如下所示:​
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="sharedata" path="shareData/" /> </paths>
paths 内部还支持节点配置其他的路径,比如:files-path,对应于 Context.getFilesDir() 获取到的目录 cache-path,对应于 Context.getCacheDir() 获取到的目录还有一些其他可配置的路径,开发者可自行了解使用。​
    2.使用 FileProvider 接口。将路径通过 FileProvider 的接口转换成 content://URI 形式,示例如下:​
public String getFileUri(Context context) { String filePath = context.getExternalFilesDir(null) + "/shareData/test.png"; // 该filePath对应于xml/file_provider_paths里的第一行配置:,因此才可被共享 File file = new File(filePath); // 使用contentPath作为文件路径进行分享 // 要与`AndroidManifest.xml`里配置的`authorities`一致,假设你的应用包名为com.example.app Uri contentUri = FileProvider.getUriForFile(context, "com.example.app.fileprovider",file); context.grantUriPermission("com.ss.android.ugc.aweme", contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); context.grantUriPermission("com.ss.android.ugc.aweme.lite", contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); return contentUri.toString(); // contentUri.toString() 即是以"content://"开头的用于共享的路径 }
    3.分享图片。​
DouYinOpenApi douYinOpenApi = DouYinOpenApiFactory.create(this); if (douyinOpenApi.isShareSupportFileProvider() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { ArrayList<String> images = new ArrayList<>(); images.add(xxx); // 将FileProvider格式的路径传的该list中 Share.Request request = new Share.Request(); ImageObject imageObject = new ImageObject(); imageObject.mImagePaths = images; // 该路径可以传FileProvider格式的路径 MediaContent mediaContent = new MediaContent(); mediaContent.mMediaObject = imageObject; request.mMediaContent = mediaContent; douyinOpenApi.share(request); } else { Toast.makeText(TestFileProviderActivity.this, "版本不符合", Toast.LENGTH_LONG).show(); }
    4.分享视频。​
if (douyinOpenApi.isShareSupportFileProvider() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { ArrayList<String> videos = new ArrayList<>(); videos.add(xxx路径) Share.Request request = new Share.Request(); VideoObject videoObject = new VideoObject(); videoObject.mVideoPaths = videos; // 该地方路径可以传FileProvider格式的路径 MediaContent content = new MediaContent(); content.mMediaObject = videoObject; request.mMediaContent = content; douyinOpenApi.share(request); } else { Toast.makeText(TestFileProviderActivity.this, "版本不符合", Toast.LENGTH_LONG).show(); }
接收回调等相关后续工作,请参见 Android 发布。​