zoukankan      html  css  js  c++  java
  • unity探索者之微信分享所有流程,非第三方插件

    版权声明:本文为原创文章,转载请声明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 }
    View Code

     然后是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 }
    View Code

    现在,亮点来了,即使上面全部正确,依然有可能出现点击分享打不开界面然后还不报错的情况(这可能是最坑的地方了,让人完全摸不着头脑)

    出现这种情况的原因有好几种:

    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     }
    View Code

    第3种情况就恶心了,因为清空微信的缓存也不一定有用,还得卸载微信重装,就博主的测试结果来看,如果其余的问题都解决了之后还是不行,那这是唯一的解决办法

    第4种情况按照本文前面的做法就ok

    微信分享的坑可能还有很多,不过博主目前就遇到了这些,也耽搁了近一天时间,如果大家还有遇到其他的坑,欢迎留言互相讨论

    由于环境不同关系,并非所有的博客内容都会上传完整的源码,大部分的源码,大家可以到我的github主页上的UGCFramework查找

    传送门:https://github.com/wulonghao/UGCFramework
  • 相关阅读:
    【译】常用网络端口号列表
    使用Simian进行重复代码检测
    使用GCOV进行代码覆盖率统计
    AFL Fuzz安装及完成一次简单的模糊测试
    数据可视化概述
    完成下方的 which_date() 函数,并返回某一起始时间后特定一段时间的日期
    linux用户不在sudoers文件中
    linux /lib64/libc.so.6: version `GLIBC_2.17′ not found
    web api 2.0 上传文件超过4M时,出现404错误
    Centos7 编译安装 Nginx Mariadb Asp.net Core2 (实测 笔记 Centos 7.7 + Openssl 1.1.1d + Mariadb 10.3.7 + Nginx 1.16.1 + Asp.net. Core 2 )
  • 原文地址:https://www.cnblogs.com/unityExplorer/p/7560575.html
Copyright © 2011-2022 走看看