分享使用的SDK:均为官方SDK,个人建议不使用第三方分享库。
一、微信、新浪微博分享图片过大无法分享异常?
微信SDK版本:6.6.22
微博SDK版本:4.3.1
无论微信还是新浪,分享图片超过1m左右会提示如下异常信息,并且分享失败.

可以看到如下,异常大致为我们使用的数据超出了某规定值

以下是异常微信分享以及新浪分享的代码:
1. 微信分享
Bitmap bmp = BitmapFactory.decodeFile(imgPath);
WXImageObject imgObj = new WXImageObject();
// 通过bitmap数据分享
WXImageObject imgObj = new WXImageObject(bmp);
2. 新浪分享
// 单图分享(暂不使用)
ImageObject imageObject = new ImageObject();
Bitmap bitmap = BitmapFactory.decodeFile(imgPath);
File imgFile = new File(imgPath);
// 图片流分享(大小有限制)
imageObject.setImageObject(bitmap);
从上面代码看不出到底是哪里的问题,不过微博和微信这两种分享方式很是相似,所以会不会是两个平台内部SDK导致的二进制数据的大小限制,所以我们看下具体的SDK内部如何处理的图片二进制数据。
所以微博和微信中我找到了如下方法:
1.微信
public static Bundle toBundle(WXMediaMessage var0) {
Bundle var1;
Bundle var10001 = var1 = new Bundle;
var1.<init>();
var1.putInt("_wxobject_sdkVer", var0.sdkVer);
var1.putString("_wxobject_title", var0.title);
var1.putString("_wxobject_description", var0.description);
var10001.putByteArray("_wxobject_thumbdata", var0.thumbData);
WXMediaMessage.IMediaObject var2;
if ((var2 = var0.mediaObject) != null) {
var1.putString("_wxobject_identifier_", pathNewToOld(var2.getClass().getName()));
var0.mediaObject.serialize(var1);
}
var1.putString("_wxobject_mediatagname", var0.mediaTagName);
var1.putString("_wxobject_message_action", var0.messageAction);
var1.putString("_wxobject_message_ext", var0.messageExt);
return var1;
}
public static WXMediaMessage fromBundle(Bundle var0) {
WXMediaMessage var1;
WXMediaMessage var10001 = var1 = new WXMediaMessage;
var1.<init>();
var1.sdkVer = var0.getInt("_wxobject_sdkVer");
var1.title = var0.getString("_wxobject_title");
var1.description = var0.getString("_wxobject_description");
var1.thumbData = var0.getByteArray("_wxobject_thumbdata");
var1.mediaTagName = var0.getString("_wxobject_mediatagname");
var1.messageAction = var0.getString("_wxobject_message_action");
var10001.messageExt = var0.getString("_wxobject_message_ext");
String var2;
......
2. 微博
public Bundle toBundle(Bundle data) {
if (this.textObject != null) {
data.putParcelable("_weibo_message_text", this.textObject);
data.putString("_weibo_message_text_extra", this.textObject.toExtraMediaString());
} else {
data.putParcelable("_weibo_message_text", (Parcelable)null);
data.putString("_weibo_message_text_extra", (String)null);
}
if (this.imageObject != null) {
data.putParcelable("_weibo_message_image", this.imageObject);
data.putString("_weibo_message_image_extra", this.imageObject.toExtraMediaString());
} else {
data.putParcelable("_weibo_message_image", (Parcelable)null);
data.putString("_weibo_message_image_extra", (String)null);
}
if (this.mediaObject != null) {
data.putParcelable("_weibo_message_media", this.mediaObject);
data.putString("_weibo_message_media_extra", this.mediaObject.toExtraMediaString());
} else {
data.putParcelable("_weibo_message_media", (Parcelable)null);
data.putString("_weibo_message_media_extra", (String)null);
}
if (this.multiImageObject != null) {
data.putParcelable("_weibo_message_multi_image", this.multiImageObject);
} else {
data.putParcelable("_weibo_message_multi_image", (Parcelable)null);
}
if (this.videoSourceObject != null) {
data.putParcelable("_weibo_message_video_source", this.videoSourceObject);
} else {
data.putParcelable("_weibo_message_video_source", (Parcelable)null);
}
return data;
}
如上可以看到,微博、微信都是使用的bundle这个对象传输的图片二进制数据,值得注意的是Bundle这个对象,以下是官方说法:
“The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all
transactions in progress for the process. Consequently this exception can be thrown when
there are many transactions in progress even when most of the individual transactions are of
moderate size.”
大概意思就是,这个缓冲区最大为1MB,并且是该进程的共享数据流传输空间。
也就是说这个空间最大单次传输的数据量为1MB,所以微信所说的10MB为可分享的最大图片,在这个情况下是不成立的,因为Bundle的限制图片最大只能1MB之内。
解决方案
了解了基本原理,我们开始着手解决方案,首先二进制这种方式指定是无法使用了,通过查询官方开发者社区以及文档和demo,发现微信分享、微博分享都有另一种分享方式:
① 微信:使用fileProvider用uri的形式分享。
② 微博:使用多图方式分享图片(多图方式采用的同样是uri形式,也需要fileProvider配置)。
分享方式如下:
微博
// 多图分享
ArrayList<Uri> pathList = new ArrayList<Uri>();
if (Build.VERSION.SDK_INT >= 23) {
Uri fileUri = null;
try {
fileUri = Uri.parse(MediaStore.Images.Media.insertImage(context.getContentResolver(), imgPath, StreamUtil.getFileName(imgPath), null));
if (fileUri == null) {
fileUri = MyShareUtil.getImageContentUri(context, new File(imgPath));
if (fileUri == null) {
fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", new File(imgPath));
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
pathList.add(fileUri);
} else {
Uri fileUri = Uri.fromFile(new File(imgPath));
pathList.add(fileUri);
}
MultiImageObject multiImageObject = new MultiImageObject();
multiImageObject.setImageList(pathList);
微信
// 通过path进行分享*(path分享方式不会限制大小)
File imgFile = new File(imgPath);
String contentPath = getFileUri(context, imgFile, 0);
WXImageObject imgObj = new WXImageObject();
imgObj.setImagePath(contentPath)
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;
getFileUri方法如下:
public static String getFileUri(Context context, File file, int nType) {
if (file == null || !file.exists()) {
return null;
}
Uri contentUri = FileProvider.getUriForFile(context,
"com.etop.scantreasure.fileProvider", // 要与`AndroidManifest.xml`里配置的`authorities`一致,假设你的应用包名为com.example.app
file);
if (nType == 1) {
// 授权给微博访问路径
context.grantUriPermission("com.sina.weibo", // 这里填微博包名
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
// 授权给微信访问路径
context.grantUriPermission("com.tencent.mm", // 这里填微信包名
contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
return contentUri.toString(); // contentUri.toString() 即是以"content://"开头的用于共享的路径
}
到此,微信、微博分享的图片过大的问题已经解决。
文章会持续收集和更新常见问题~
网友评论