下载sdk文件,位置如下图所示
之后可以按照官方文档进行开发,接入也较简单,这里主要是说明一些隐藏的坑点
一、分享应用内的文件到小红书(这里主要是指应用包名下的文件内容),需要注意setFileProviderAuthority()这个方法。
例如我的代码如下:
AndroidManifest文件 <providerandroid:name="androidx.core.content.FileProvider"android:authorities="${applicationId}.FileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/provider_paths"/></provider>
res目录下的xml配置文件 <?xml version="1.0" encoding="utf-8"?> <paths><cache-pathname="cache"path="."/> <!--Context.getCacheDir() --><files-pathname="files"path="."/> <!--Context.getFilesDir() --><external-pathname="external"path="."/> <!-- Environment.getExternalStorageDirectory()--><external-cache-pathname="external-cache"path="."/> <!-- Context.getExternalCacheDir() --><external-files-pathname="external-files"path="."/> <!-- Context.getExternalFilesDir() --><external-files-pathname="opensdk_external"path="Images"/><root-pathname="opensdk_root"path=""/> </paths>
像我的项目配置的话,需要设置的代码如下
XhsShareSdk.registerApp(context, XHS_APP_KEY,XhsShareGlobalConfig().setEnableLog(true).setClearCacheWhenShareComplete(true) //重点是下面的这句话,设置为自己应用的 Authority .setFileProviderAuthority("${context.packageName}.FileProvider"),object : XhsShareRegisterCallback {override fun onSuccess() {log { "xhs---onSuccess: 注册成功!" }}override fun onError(errorCode: Int,errorMessage: String,@Nullable exception: Exception?) {log { "xhs---onError: 注册失败!errorCode: $errorCode errorMessage: $errorMessage exception: $exception" }}})
二、小红书构造方法的坑:
XhsNote().apply {title = getTitleString() // 正文,Stringcontent = getContentString() // 标题,StringimageInfo = XhsImageInfo(listOf(XhsImageResourceBean.fromUrl("网络图片 url"), XhsImageResourceBean.fromUrl("网络图片 url"))) }
小红书的示例代码和说明,都说的很简单,可以直接使用fromUrl这个方法进行构造,他会自动识别是网络图片还是本地图片。不需要手动处理了。
但是,之后,你就会发现,分享网络资源没有问题,但是如果分享的内容是自己应用内部的文件,就无论如何,都分享不成功,到了小红书APP,就提示未获取到图片或者视频。
请看SDK代码
小红书SDK里面判断了是否是网络地址,然后通过File的构造方法,调用了顶部的Uri.fromFile(filePath),这个方法是存在问题的。
安卓7.0强制启用了striceMode策略,无法直接暴露file://类型的URI了。如果使用的公共目录分享文件,还是可以成功的,但是如果分享的是应用内部的文件,就会出现没有访问权限的问题。所以小红书APP,就会一直报为获取资源的问题。
解决办法:
使用XhsImageResourceBean(Uri)方式去构造视频和图片的对象。示例代码如下:
fun shareXHS(activity: Activity = requireNotNull(SnsHelper.mainActivity),filePath: String//传递过来文件地址 ) {val xhsPackageNames = arrayOf("com.xingin.xhs")//获取赋予权限的URIval uri = getContentUriForFileProvider(filePath = filePath,packages = xhsPackageNames)log { "xhs--- FilePath=$filePath \n,uri:$uri, " }val title="标题内容"val content="内容文字"try {//获取视频的首帧作为封面图val bitmap= getThumbnailFromVideo(filePath)val tempFile = File("${activity.cacheDir.absolutePath}/cameraShooting", "tempFileForShare.png")val stream = FileOutputStream(tempFile)bitmap?.compress(Bitmap.CompressFormat.PNG, 100, stream)stream.close()//获取首帧的图片URIval picUri = getContentUriForFileProvider(filePath = tempFile.absolutePath,packages = xhsPackageNames)val xhsNote= XhsNote().apply {this.title = titlethis.content = contentvideoInfo = XhsVideoInfo(//通过URI的方式,构建数据 XhsVideoResourceBean(uri),XhsImageResourceBean(picUri)) // 封面 }//分享数据val sessionId = XhsShareSdk.shareNote(activity, xhsNote)}catch (e:Exception){ }}fun getContentUriForFileProvider(filePath: String,packages: Array<String> = emptyArray(),context: Context = CoreApp.getContext(),): Uri {//根据文件路径,生成关联的 content:// 内容 URI val file = File(filePath)val contentUri = FileProvider.getUriForFile(context,"${context.packageName}.FileProvider",file)//赋予权限 packages.forEach {context.grantUriPermission(it,contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)}return contentUri}fun getThumbnailFromVideo(path: String, percent: Int = 0): Bitmap? {val retriever = MediaMetadataRetriever()var bitmap: Bitmap? = nulltry {retriever.setDataSource(path)val duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull() ?: 0val timePositionUs = (duration / 100f * percent).toLong() * 1000bitmap = retriever.getFrameAtTime(timePositionUs, MediaMetadataRetriever.OPTION_CLOSEST)} catch (e: Exception) {log(type = LogType.E, errorThrowable = e)e.printStackTrace()} finally {retriever.release()}return bitmap}