版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7560575.html
很久没有写新博客了,前段时间有些忙,这几天趟了几个微信分享的坑,写下来和大家分享下
接过微信分享的人,不论是直接接的微信自己的sdk还是使用了第三方插件,比如友盟、Mob之类的,估计都被微信官方恶心过。因为微信官方的文档真的是除了给了sdk,其余的等于什么都没说。
先说说接分享的流程吧:
首先,需要去微信开放平台申请账号,并注册一个应用,然后等待审核,这个过程我就不细说了,百度上到出都有。
审核通过后,就可以到管理中心查看自己的应用,点击查看进入应用详情界面
新注册的应用默认就有微信分享的权限,但是其他包括支付的功能则需要另外申请。在界面下方就是应用的开发信息了。
这里的应用签名和包名相当重要,因为对应的unity工程所使用的签名文件和包名必须和这里的一模一样,包名没什么好说的按照【com.公司名.项目名】的结构定义就好,主要说说签名,因为博主就在这个问题上栽了跟头。
这里的应用签名并非是简单的名字,也不可以随便定义,而是需要和项目的签名文件的md5相同,先说签名文件的生成,unity有比较简单的方法
在unity的PlayerSettings中的Publishing Settings页中,勾选Create a new key,然后点击下方的Browse Keystore按钮,在弹出的窗口中填写好签名文件的名字,然后保存
接下来,注意,点击保存后并不会立即就生成签名文件,而是需要先在下方的两个输入框中填写签名文件的密码,填写完毕后,再选择下方的Alias下拉框
这时候会出现一个新的选项,Create a new key
填写好相应信息,点击Create Key,然后你会发现,你刚才选择的那个路径出现一个新的keystore文件
然后接下来就可以使用这个签名文件了,不过还没完。
接下来就是第二个很重要的地方了,签名文件的md5码
网上很多人给的方法是使用eclipse创建签名文件的apk,然后使用微信提供的生成md5的工具来获取MD5,不过博主觉得很麻烦,所以选择使用命令行
把刚才生成的签名文件拷贝到你的jdk文件夹下的bin目录中,然后使用命令行
keytool -list -v -keystore xyms.keystore
输入密码后,下方的MD5就是我们要的东西了,把这串MD5码的冒号去掉,然后大写改为小写,复制到微信分享平台中应用签名一栏就ok了
网上有人说应用签名和包名一个月只能改一次,不过博主一天改了三回貌似也没啥问题。。。
OK,签名和包名的问题解决了,接下来就是干货了,首先是核心java代码

1 public class ShareUtils { 2 3 public static IWXAPI api = null; 4 5 public static void RegisterToWechat (Context context, String appId) { 6 api = WXAPIFactory.createWXAPI(context, appId, true); 7 api.registerApp(appId); 8 } 9 10 public static boolean IsWechatInstalled () { 11 return api.isWXAppInstalled(); 12 } 13 14 public static boolean IsWechatAppSupportAPI() { 15 return api.isWXAppSupportAPI(); 16 } 17 18 public static void ShareImage(int scene, byte[] imgData, byte[] thumbData) { 19 WXImageObject imgObj = new WXImageObject(imgData); 20 WXMediaMessage msg = new WXMediaMessage(); 21 msg.mediaObject = imgObj; 22 msg.thumbData = thumbData; 23 24 SendMessageToWX.Req req = new SendMessageToWX.Req(); 25 req.transaction = BuildTransaction("img"); 26 req.message = msg; 27 req.scene = scene; 28 api.sendReq(req); 29 } 30 31 public static void ShareText(int shareType, String text) { 32 WXTextObject textObj = new WXTextObject(); 33 textObj.text = text; 34 35 WXMediaMessage msg = new WXMediaMessage(); 36 msg.mediaObject = textObj; 37 msg.description = text; 38 39 SendMessageToWX.Req req = new SendMessageToWX.Req(); 40 41 req.transaction = BuildTransaction("text"); 42 req.message = msg; 43 44 req.scene = shareType; 45 api.sendReq(req); 46 } 47 48 public static void ShareWebPage(int shareType, String url, String title, String content, byte[] thumb) { 49 WXWebpageObject webpage = new WXWebpageObject(); 50 webpage.webpageUrl = url; 51 WXMediaMessage msg = new WXMediaMessage(webpage); 52 msg.title = title; 53 msg.description = content; 54 msg.thumbData = thumb; 55 56 SendMessageToWX.Req req = new SendMessageToWX.Req(); 57 req.transaction = BuildTransaction("webpage"); 58 req.message = msg; 59 req.scene = shareType; 60 api.sendReq(req); 61 } 62 63 64 static String BuildTransaction(final String type) { 65 return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis(); 66 } 67 }
然后是unity代码

1 public class ShareManager : MonoBehaviour 2 { 3 static ShareManager _instance; 4 5 public static ShareManager Instance 6 { 7 get 8 { 9 if (_instance == null) 10 { 11 GameObject go = new GameObject(); 12 _instance = go.AddComponent<ShareManager>(); 13 go.name = _instance.GetType().ToString(); 14 } 15 return _instance; 16 } 17 } 18 19 void OnDestory() 20 { 21 _instance = null; 22 } 23 24 public enum WXScene 25 { 26 // 好友 27 WXSceneSession = 0, 28 // 朋友圈 29 WXSceneTimeline = 1, 30 // 收藏 31 WXSceneFavorite = 2, 32 } 33 34 public static string WechatAppId = "xxxxxxx"; 35 static string shareUtils = "com.xxxx.xxx.mytool.ShareUtils"; 36 37 public void RegisterAppWechat() 38 { 39 #if UNITY_ANDROID 40 AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 41 AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); 42 AndroidJavaClass utils = new AndroidJavaClass(shareUtils); 43 utils.CallStatic("RegisterToWechat", currentActivity, WechatAppId); 44 #endif 45 } 46 47 public void ShareImage(WXScene scene, byte[] data, byte[] dataThumb) 48 { 49 #if UNITY_ANDROID 50 AndroidJavaClass utils = new AndroidJavaClass(shareUtils); 51 utils.CallStatic("ShareImage", (int)scene, data, dataThumb); 52 #endif 53 } 54 55 public void ShareText(WXScene scene, string content) 56 { 57 #if UNITY_ANDROID 58 AndroidJavaClass utils = new AndroidJavaClass(shareUtils); 59 utils.CallStatic("ShareText", (int)scene, content); 60 #endif 61 } 62 63 public void ShareWebPage(WXScene scene, string url, string title, string content, byte[] thumb) 64 { 65 #if UNITY_ANDROID 66 AndroidJavaClass utils = new AndroidJavaClass(shareUtils); 67 utils.CallStatic("ShareWebPage", (int)scene, url, title, content, thumb); 68 #endif 69 } 70 71 /// <summary> 72 /// 是否安装了微信 73 /// </summary> 74 /// <returns></returns> 75 public bool IsWechatInstalled() 76 { 77 #if UNITY_ANDROID 78 AndroidJavaClass utils = new AndroidJavaClass(shareUtils); 79 return utils.CallStatic<bool>("IsWechatInstalled"); 80 #else 81 return false; 82 #endif 83 } 84 }
现在,亮点来了,即使上面全部正确,依然有可能出现点击分享打不开界面然后还不报错的情况(这可能是最坑的地方了,让人完全摸不着头脑)
出现这种情况的原因有好几种:
1、分享的图片的缩略图尺寸很大或者质量很高(PS:明明微信自己给的demo工程中的质量都是100,然而实际使用中缩略图的质量不能用100,博主用的40)
2、分享的图片的缩略图尺寸比例太悬殊,比如100*1000这种。。。
3、之前使用过不同的签名或者包名
4、项目的签名或包名和微信平台上填的不同
1、2两种情况都得改传入的缩略图的尺寸,这里提供一个压缩方法,建议缩略图压到150*150

1 /// <summary>将图片缩放为指定尺寸</summary> 2 public static Texture2D SizeTextureBilinear(Texture2D originalTexture, Vector2 size) 3 { 4 Texture2D newTexture = new Texture2D(Mathf.CeilToInt(size.x), Mathf.CeilToInt(size.y)); 5 float scaleX = originalTexture.width / size.x; 6 float scaleY = originalTexture.height / size.y; 7 int maxX = originalTexture.width - 1; 8 int maxY = originalTexture.height - 1; 9 for (int y = 0; y < newTexture.height; y++) 10 { 11 for (int x = 0; x < newTexture.width; x++) 12 { 13 float targetX = x * scaleX; 14 float targetY = y * scaleY; 15 int x1 = Mathf.Min(maxX, Mathf.FloorToInt(targetX)); 16 int y1 = Mathf.Min(maxY, Mathf.FloorToInt(targetY)); 17 int x2 = Mathf.Min(maxX, x1 + 1); 18 int y2 = Mathf.Min(maxY, y1 + 1); 19 20 float u = targetX - x1; 21 float v = targetY - y1; 22 float w1 = (1 - u) * (1 - v); 23 float w2 = u * (1 - v); 24 float w3 = (1 - u) * v; 25 float w4 = u * v; 26 Color color1 = originalTexture.GetPixel(x1, y1); 27 Color color2 = originalTexture.GetPixel(x2, y1); 28 Color color3 = originalTexture.GetPixel(x1, y2); 29 Color color4 = originalTexture.GetPixel(x2, y2); 30 Color color = new Color(Mathf.Clamp01(color1.r * w1 + color2.r * w2 + color3.r * w3 + color4.r * w4), 31 Mathf.Clamp01(color1.g * w1 + color2.g * w2 + color3.g * w3 + color4.g * w4), 32 Mathf.Clamp01(color1.b * w1 + color2.b * w2 + color3.b * w3 + color4.b * w4), 33 Mathf.Clamp01(color1.a * w1 + color2.a * w2 + color3.a * w3 + color4.a * w4) 34 ); 35 newTexture.SetPixel(x, y, color); 36 37 } 38 } 39 newTexture.Apply(); 40 return newTexture; 41 }
第3种情况就恶心了,因为清空微信的缓存也不一定有用,还得卸载微信重装,就博主的测试结果来看,如果其余的问题都解决了之后还是不行,那这是唯一的解决办法
第4种情况按照本文前面的做法就ok
微信分享的坑可能还有很多,不过博主目前就遇到了这些,也耽搁了近一天时间,如果大家还有遇到其他的坑,欢迎留言互相讨论