各位开发者:
最新版本(7.0.13)的微信 SDK 已经适配使用FileProvider的方式来进行消息分享。
如果分享的消息中涉及文件路径(如图片类型消息),建议开发者针对Android 7.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
,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="sharedata" path="shareData/"/>
</paths>
external-files-path
表示通过 Context.getExternalFilesDir(null)
接口获取到的目录下的文件才可被共享,其他未配置的路径均不可被分享。同样的节点可以配置多个,以支持多个不同的子目录,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="sharedata" path="shareData/"/>
<external-files-path name="sharedata2" path="shareData2/"/>
</paths>
paths
内部还支持节点配置其他的路径,比如:
files-path
,对应于Context.getFilesDir()
获取到的目录cache-path
,对应于Context.getCacheDir()
获取到的目录- ...
- 还有一些其他可配置的路径,开发者可自行了解使用。
2. 使用FileProvider接口
将路径通过FileProvider的接口转换成content://URI
形式,示例如下:
public void shareToWechat(Context context) {
// ...
String filePath = context.getExternalFilesDir(null) + "/shareData/test.png";
// 该filePath对应于xml/file_provider_paths里的第一行配置:,因此才可被共享
File file = new File(filePath);
String contentPath = getFileUri(context, file);
// 使用contentPath作为文件路径进行分享
// ...
}
public String getFileUri(Context context, File file) {
if (file == null || !file.exists()) {
return null;
}
Uri contentUri = FileProvider.getUriForFile(context,
"com.example.app.fileprovider", // 要与`AndroidManifest.xml`里配置的`authorities`一致,假设你的应用包名为com.example.app
file);
// 授权给微信访问路径
context.grantUriPermission("com.tencent.mm", // 这里填微信包名
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
return contentUri.toString(); // contentUri.toString() 即是以"content://"开头的用于共享的路径
}
微信版本支持
- OpenSDK版本:必须大于或等于 5.4.3 版本,建议开发者升级至最新版本 5.5.8
- 微信版本:当且仅当通过 IWXAPI.getWXAppSupportAPI() 接口获取到的值 >= 0x27000D00,才能支持FileProvider的方式进行分享。示例代码如下:
private IWXAPI api; // api的初始化这里省略
public void shareToWechat(Context context) {
// ...
if (checkVersionValid(context) && checkAndroidNotBelowN()) {
String filePath = context.getExternalFilesDir(null) + "/shareData/test.png";
File file = new File(filePath);
String contentPath = WXOpenSDKFileProviderHelper.getFileUri(context, file);
// 使用contentPath作为文件路径进行分享
// ...
}
else {
// 使用原有方式传递文件路径进行分享
// ...
}
}
// 判断微信版本是否为7.0.13及以上
public boolean checkVersionValid(Context context) {
return api.getWXAppSupportAPI() >= 0x27000D00;
}
// 判断Android版本是否7.0及以上
public boolean checkAndroidNotBelowN() {
return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N;
}
详细参考 OpenSDK 消息分享文档:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Share_and_Favorites/Android.html
微信团队
2020年03月31日
目前版本6.6.19 分享图片可以 分享文件微信界面直接闪退
WXFileObject fileObj = new WXFileObject(); fileObj.filePath = FileUtil.file2Uri(context, new File(wxMsg.getPath())) ;
打印出来uri是
content://com.starnet.rainbow.cordova.dev.file.provider/name/storage/emulated/0/Android/data/com.starnet.rainbow.cordova.dev/cache/nim/file/%E9%99%84%E4%BB%B6%E4%B8%80%EF%BC%9A2020%E5%B9%B4%E5%BA%A6%E7%89%A9%E8%81%94%E7%A0%94%E5%8F%91%E4%B8%AD%E5%BF%83%E9%83%A8%E9%97%A8%E4%BC%98%E7%A7%80%E5%91%98%E5%B7%A5%E8%AF%84%E9%80%89%E6%8E%A8%E8%8D%90%E8%A1%A8.doc
能分享的图片uri是
content://com.starnet.rainbow.cordova.dev.file.provider/name/storage/emulated/0/Android/data/com.starnet.rainbow.cordova.dev/cache/nim/file/shareImage.jpg
报错信息
2021-01-22 17:52:11.332 29918-29918/? E/Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory
java.lang.Throwable
at android.app.Instrumentation.getFactory(Instrumentation.java:1262)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at com.tencent.mm.splash.k.newActivity(SourceFile:58)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2021-01-22 17:52:11.380 1477-3074/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.384 1477-3074/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.405 1477-2153/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.407 1477-5705/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.410 1477-7741/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.520 1477-2153/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.547 1477-5705/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.566 1477-7741/? E/WifiService: Permission violation - getConfiguredNetworks not allowed for uid=10344, packageName=com.tencent.mm, reason=java.lang.SecurityException: UID 10344 has no location permission
2021-01-22 17:52:11.891 29918-29918/? E/Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory
java.lang.Throwable
at android.app.Instrumentation.getFactory(Instrumentation.java:1262)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at com.tencent.mm.splash.k.newActivity(SourceFile:58)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2021-01-22 17:52:11.934 29918-29918/? E/Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory
java.lang.Throwable
at android.app.Instrumentation.getFactory(Instrumentation.java:1262)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at com.tencent.mm.splash.k.newActivity(SourceFile:58)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2021-01-22 17:52:13.990 29918-29918/? E/Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory
java.lang.Throwable
at android.app.Instrumentation.getFactory(Instrumentation.java:1262)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at com.tencent.mm.splash.k.newActivity(SourceFile:58)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2021-01-22 17:52:16.167 1477-1477/? E/NotificationService: Muting recently noisy 0|com.tencent.mm|1|null|10344
2021-01-22 17:52:16.513 29918-29918/? E/Instrumentation: Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory
java.lang.Throwable
at android.app.Instrumentation.getFactory(Instrumentation.java:1262)
at android.app.Instrumentation.newActivity(Instrumentation.java:1253)
at com.tencent.mm.splash.k.newActivity(SourceFile:58)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3353)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
这个类
改成:String contentPath = getFileUri(context, file);
getFileUri使用网页上已经提供的函数。
WXWebpageObject webpage = new WXWebpageObject(); webpage.webpageUrl = url; //用 WXWebpageObject 对象初始化一个 WXMediaMessage 对象 WXMediaMessage msg = new WXMediaMessage(webpage); msg.title = title; msg.description = content; Bitmap thumbBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_xinfuguanjia); msg.thumbData = bmpToByteArray(thumbBmp, 32);
没有用到 文件啊,为何还提示分享异常呢
Android11上还是无法分享文件啊,targetSdkVersion是28
分享pdf文件,但是微信中icon 显示一个问号,望赶紧修复
Android 11 上面的双开微信还是没有办法正常分享
更改为Fileprovider方式后,在Android11版本上,部分手机出现提示图片不存在的情况,有人遇到过吗?