Android开发知识(十一):让你的应用接入微信分享,完美绕过微信分享的大坑

版权声明:本文为博主原创文章,未经博主允许不得转载,如若需要转载请注明原文出处以及作者。 https://blog.csdn.net/lc_miao/article/details/79855687

一、申请应用


1、首先到 [ 微信开放平台官网] 申请注册帐号,这些流程就忽略了到官网一看自然就知道怎么走,感觉在这里没有必要说很多。
2、申请一个移动应用,填写完成你的应用信息。其他的没啥,最主要的是要填对你的签名和包名,否则SDK调不起来。包名大家都懂,主要是这个签名的过程需要提醒一下:
1)签名全部是小写,没有大写。
2)签名填的是MD5,不是SHA1更不是SHA256,有的同学不小心就搞错了
这里获取应用签名的方法有二。

第一个方法:先假设我们的应用已经有签名文件了(这里就不讲解生成签名文件的过程了,Android Studio提供的生成签名文件的方法已经很简单了,这里不赘述)。在命令行输入以下命令:

keytool -list -v -keystore 目标签名文件路径

然后输入一下签名文件的密码后就出来很多签名文件的信息:
签名
注意是复制出里面的指纹证书下的MD5那一串。
然后自己手动把大写字母改成小写字母,并且把冒号都去掉。这样子就得到了签名。

第二个方法:简单粗暴,微信开放平台提供给我们一个签名获取的工具,点击这里跳转
这里写图片描述
然后把apk安装到手机后,正确输入你的应用包名后就获取到了一串签名:
这里写图片描述

把这串签名填写到你申请的应用配置里面。

搞定,等待微信审核。
审核完成后得到AppID 和 AppSecret 。注意这两个,等下要用到。

二、配置微信分享的SDK


可以直接到官网下载jar包或者配置依赖:

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}

或者

dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

(其中,前者包含统计功能)

然后我们添加如下权限:


<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

三、微信分享示例


1、首先我们需要像微信注册我们申请的应用,在前面我们申请的应用审核完后的APP_ID 和APP_SECRET 就填写在这里:

private static final String APP_ID = "123456"; 
private static final String APP_SECRET = "123456";
private IWXAPI api;  
//向微信注册app
public void register(Context context) {   
	if(api==null){
	    api = WXAPIFactory.createWXAPI(context, APP_ID, true);  
	    api.registerApp(APP_ID);        
    }
}

这部分代码没有限制性需要在哪里执行,你可以放在Application的onCreate,也可以在Activity,笔者推荐放在你要做分享的Activity里。

接下来就是编写分享的代码了。微信分享有文字、图片、链接、音乐、视频这几种方式,分享的途径有分享到好友、分享到朋友圈。
由于不同分享方式的原理相同,这里我们就拿分享网页链接的例子来说
以下是分享网页链接的代码:

WXWebpageObject webpage = new WXWebpageObject();
        webpage.webpageUrl = "网页链接";
        final WXMediaMessage msg = new WXMediaMessage(webpage);
        msg.title = "网页标题";
        msg.description = "网页内容";
        
        Bitmap thumb = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.xxx);
        if(thumb != null) {
            Bitmap mBp = Bitmap.createScaledBitmap(thumb, 120, 120, true);
            thumb.recycle();
            msg.thumbData = bmpToByteArray(thumb,true);
        }
       SendMessageToWX.Req req = new SendMessageToWX.Req();    //创建一个请求对象
    req.message = msg; 
    //req.scene = SendMessageToWX.Req.WXSceneTimeline;    //设置发送到朋友圈
    req.scene = SendMessageToWX.Req.WXSceneSession;   //设置发送给朋友
    req.transaction = "设置一个tag";  //用于在回调中区分是哪个分享请求
    boolean successed = api.sendReq(req);   //如果调用成功微信,会返回true

好了,正常的话到这一步我们已经能够调起微信对好友分享网页链接了。
而往往事与愿违,现实和理想差距太大。有很多同学到这一部却碰到很多问题,比如:

1、调不起来,微信一点反应都没有;
2、能分享给好友、但是显示不了网页链接的图片;
3、能分享给好友,自己能看到网页链接的图片,但是朋友看不到。

问题的答案如下:
第一个问题:调不起来,微信一点反应都没有
首先你得保证填写的包名和签名是一定正确的,签名你如果不确定是否正确的话就最好用官方的签名获取apk来校验一下。
其次,你得确保有没有注册了?我们在代码的第一步写的:
WXAPIFactory.createWXAPI(context, APP_ID, true);
如果都确保是没问题的,那么就要从图标入手了,这是微信文档的一个大坑

我们在分享链接的时候填写图片,这个bitmap不能超过32kb
事实证明如果传给微信的bitmap太大的话,则微信会无任何反应,Log也看不出什么出错。
所以有了这一步:

Bitmap mBp = Bitmap.createScaledBitmap(thumb, 120, 120, true);

或者把你的图切小一点。也许就能调起来了。
第二个问题:能分享给好友、但是显示不了网页链接的图片
这个问题其实也是跟bitmap的大小有关,跟问题一差不多。所以建议两个方法,要么把图片切小一点。要么代码控制图片的大小,使之在正常的范围内。

第三个问题:能分享给好友,自己能看到网页链接的图片,但是朋友看不到
前面两个问题其实还好,至少稍微百度一下就能解决。而第三个问题着实坑爹。好友看不到你的网页图片,会让你误以为是问题二导致的,结果一顿修改都解决不了问题。
而其实,这个是跟微信的一个敏感词检测系统,如果你的网页分享内容里面包含了“红包”、“领取”等等之类的词语,极有可能造成问题三的产生,而微信目前没有公布哪些敏感词不通过,所以出现这个问题的话你一定要注意修改你的标题和内容了,只能把表达方式换一个,再试一下。

四、微信分享的结果回调


说了这么多,想必你已经能调起微信进行分享了吧。我们还没说到微信的回调,其实微信的回调说起来也是比较坑的,如果没接触过的话,这个回调也能耗了你不少时间。
微信的回调有四大坑,这里通过踩坑的方式来完成示例:

1、新建WXEntryActivity(坑一:新建的WXEntryActivity类包名路径不对)
长话短说,这里千言万语融成一句话:一定要在建立一个 包名.wxapi.WXEntryActivity
比如你的包名是:com.example.demo。那么你就得配置一个com.example.demo.wxapi.WXEntryActivity
千万要注意,不要随便乱放这个Activity,也不能改名,就叫WXEntryActivity。包名跟你申请应用的时候填写的包名一致。

2、向AndroidManifest.xml注册WXEntryActivity(坑二:没有配置android:exported=“true”)

  <activity android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            ></activity>

注意看清楚没?多配置了一个 android:exported=“true”,这个属性代表着运行被外界程序所启动这个Activity,微信对于我们的app来说就是外部程序了,要回调我们的Activity,没有这个万万不行。千万要注意

3、实现IWXAPIEventHandler接口,注册API(坑三:没有在onCreate里注册API)
这个接口有两个方法:

@Override
    public void onReq(BaseReq baseReq) {
        
    }

    @Override
    public void onResp(BaseResp baseResp) {

    }

分别是我们做出的请求和请求的结果回调。我们的业务逻辑便是从onResp方法里写的
然后一定要 千万要 万万要注册api、八成没有接收到回调的同学们就是没有这一步:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //注册API 没有这个不会执行onResp
        api = WXAPIFactory.createWXAPI(this, WXModel.APP_ID);
        api.handleIntent(getIntent(), this);
        LogUtils.i(TAG, " handleIntent:" + api.handleIntent(getIntent(), this));
    }

4、在onResp方法里编写分享后的回调处理逻辑(坑四:回调处理逻辑搞错)
其实到这一步回调就可以完成了。剩下的是我们的回调回来页面后的业务逻辑,从onResp来处理。
在这里特别注意提醒同学们,由于微信的登录和分享都是一样放在这个WXEntryActivity里面,所以在onResp方法里面我们必须做出区分,通过baseReq.getType()可以得到回调的类型,在ConstantsAPI接口里面定义了微信回调的很多类型,需要我们自己来区分
这里写图片描述

然后通过状态码:resp.errCode 来得知分享的结果(成功、失败、取消等等),正常成功的话是resp.errCode==BaseResp.ErrCode.ERR_OK,取消分享是BaseResp.ErrCode.ERR_USER_CANCEL。

好了,到这一步的时候我们就绕过这么多个坑,基本做对的话就能成功分享链接出去并且回调分享结果。

最后,由于微信的回调机制,我们没办法做出其他处理,一定只能通过在固定的包名路径下新建这个类来完成回调,如果你实在不想微信显示这个页面的话,那么也可以通过广播、或者EventBus来吧结果回调出去,然后结束页面。这样子注册了广播接收或者EventBus的Actibity就能接收到回调的结果:

 @Override
    public void onResp(BaseResp baseResp) {
        if (baseResp.getType() == ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX) {
            Intent intent = new Intent("SHARE_WX_ACTION");
            intent.putExtra("errCode", baseResp.errCode);
            sendBroadcast(intent);
            finish();
        }
    }

五、微信分享的踩坑总结


到这里,微信分享的过程就结束了,你学会了吗?
由于坑比较多,在最后我们再总结下微信分享都有哪些需要注意的地方:

1、配置签名的坑
解决:一定要MD5、小写、不要带冒号,最好用官方给的签名获取工具。
2、没有注册API
解决:API是运行重复注册的,并且也不是耗时任务,所以不妨放在Activity的onCreate下面,记得写这个。
3、分享的图标
解决:分享的图标大小不能超过32K,要是jpg格式。
3、分享图标自己能看到,好友看不到
解决:修改分享的标题和内容,不要触及微信的敏感词检测系统,多试几下。
4、没有回调
解决:一定要注意WXEntryActivity的包名路径是否正确,已经配置export=true
5、确定了问题4后还是调不起来
你确定有在WXEntryActivity的onCreate里面注册API并且调用 api.handleIntent(getIntent(), this);? 估计你没有吧?
6、回调到其他页面
解决:没办法直接回调到其他页面,但可以通过广播、EventBus等通知的实现来通知其他页面刷新,同时结束WXEntryActivity的页面。

猜你喜欢

转载自blog.csdn.net/lc_miao/article/details/79855687