umeng(源生微信SDK)分享以及登陆的一些坑(只执行onStart不执行onComplete;分享内容只有图片;只能分享朋友圈,不能分享朋友)

umeng分享以及登陆的一些坑

主要对于以下这些问题

1、只执行onStart,不执行onComplete
2、分享内容只有图片,没有url、title和contents
3、只能分享朋友圈,不能分享朋友
4、配置都正确,但是无法正确回调(执行了onError方法)

源生微信SDK分享以及登陆的一些坑

主要对于以下这些问题

1、分享成功后,再次分享时选择后退或关闭会闪退

1、只执行onStart,不执行onComplete

关于我这个问题的产生,先说明一下我在集成过程中的方法和步骤
1-1、核对最新代码调用问题,对比官方SDK的调用方法和自己的,看下是否存在自己修改后造成的问题。比如新版SDK就在所有回调监听器增加onStart()方法

new UMShareListener() { 
    @Override 
    public void onStart(SHARE_MEDIA platform) {
    }

    @Override 
    public void onResult(SHARE_MEDIA platform) {  
     } 

    @Override
    public void onError(SHARE_MEDIA platform, Throwable t) { 
    } 

    @Override 
    public void onCancel(SHARE_MEDIA platform) { 
    } 
  };

而不再是下面这个老方法了

new UMShareListener() { 
    @Override 
    public void onResult(SHARE_MEDIA platform) {  
           Toast.makeText(ShareActivity.this,platform + " 分享成功啦", Toast.LENGTH_SHORT).show();
     } 

    @Override
    public void onError(SHARE_MEDIA platform, Throwable t) { 
           Toast.makeText(ShareActivity.this,platform + " 分享失败啦", Toast.LENGTH_SHOR T).show(); 
    } 
    @Override 
    public void onCancel(SHARE_MEDIA platform) { 
            Toast.makeText(ShareActivity.this,platform + " 分享取消了", Toast.LENGTH_SHORT).show(); 
    } 
  };

1-2、核对包名和签名获取的appid和secret是否匹配,我就是这个问题,新项目的包名忘记更改,使 用了别的项目的可用appid和secret,结果造成只执行onStart方法而不执行onComplete方法,简而言之,造成这个问题的原因就是签名不匹配。
1-3、核对umeng下wxapi下的WXEntryActivity这继承的父类WXCallbackActivity所在的包是 simplify还是full,我的是简易版,完整版不行,具体原因还在探索中。
1-4、核对AndroidManifest.xml配置文件的正确性


<application>
    ......
     <activity
           android:name=".wxapi.WXEntryActivity"
           android:configChanges="keyboardHidden|orientation|screenSize"
           android:exported="true"
           android:screenOrientation="landscape"
           android:theme="@android:style/Theme.Translucent.NoTitleBar"
           >
      activity>
    .......
application>

这个配置是否正确,其实归根结底还是包名问题, 因为wxapi前面省略的就是包名,还有,项目下建立的包也一定要跟这个目录一模一样!
1-5、确认activity中的onActivityResult方法是否回调mShareAPI.onActivityResult(requestCode, resultCode, data)。
1-6、微信登陆授权是需要交钱的,貌似是300大洋,而单纯分享不用,所以你如果不能登陆,那可能 需要问下你们老板交钱了没。大概就这6点了,相信只要一一对应去排查,问题就能解决了。PS: SDK一直在更新,以前的jar并没有onStart方法,现在新增进去了,因此建议各位码友们记得好好对 比最新的SDK,适当做些更改。

2、分享内容只有图片,没有url、title和contents

在可以分享的大前提下,测试发现分享只能分享图片,不能携带url、title和contents了。这个问题解决方法其实我在第一点的第一步就已经说明了,是的,核对最新的SDK!旧版SDk分享中,可以有ShareAction .withTitle()、ShareAction .withTargetUrl()、ShareAction .withContent()等方法,但是新版已经替换为 UMWeb mWeb = new UMWeb(String url) 来添加分享url含title和contents方法了,所以,只要对应的new 出mWeb ,用mWeb 这个对象进行title和contents设置就行了。
PS:如果你仔细研究,你就会发现当ShareAction.withText().withMedia()并存时,而你又在withMedia()方法中设置withMedia(img),这时分享的内容便只有图片;当只有ShareAction.withText()时,会只分享文字!
注意:集成过程中注意param判空!

//友盟分享调用的主要方法
public void umengShare(final OnShareListener listener, ShareParam param)
{
    //友盟分享--微信平台
    SHARE_MEDIA mdia = m_UMPartyList.get(SHARE_MEDIA.WEIXIN);
    //ShareAction对象用于携带(捆绑)参数
    ShareAction sAct = newShareAction(param);
    //友盟分享调用的主要方法
    sAct.withText(param.sTargetURL).setPlatform(mdia).setCallback(newShareListener(listener)).share();
}

private ShareAction newShareAction( ShareParam param )
    {
        ShareAction sAct = new ShareAction(m_Context);
        UMImage img = UMAsset.getUmImage(m_Context, param.sMedia);
        //老版本方法
//      sAct.withText(param.sContent);
//      sAct.withTitle(param.sTitle);
//      sAct.withTargetUrl(param.sTargetURL);
//      sAct.withText(param.sTargetURL);
        //新版本方法
        mWeb = new UMWeb(param.sTargetURL);
        mWeb.setTitle(param.sTitle);
        mWeb.setDescription(param.sContent);
        if (null == mWeb) {
            sAct.withMedia(img);
        } else {
            sAct.withMedia(mWeb);
        }
        return sAct;
    }

3、只能分享朋友圈,不能分享朋友

说起来也是挺尴尬的,我们都知道,微信分享只要注册账号然后依据包名生成对应签名的AppKey(或者说AppId)就能实现分享了,但是集成登陆,却是还要交300块大洋给TX。因此,在测试过程中,我们有可能只需要授权分享,但是不用登陆,所以索性就只申请了AppKey(AppId),然后就照常集成了。但是就在新的一个项目测试过程中,忽然发现分享只能分享分享朋友圈,点击分享朋友却没反应!经过研究发现,根源在于AppSecret!我们知道umeng在设置平台时,会使用

//友盟平台调用的主要方法
PlatformConfig.setQQZone(String id, String key)
PlatformConfig.setTwitter(String key, String secret)
...
...
PlatformConfig.setWeixin(String id, String secret)

问题就发生在 PlatformConfig.setWeixin(String id, String secret)这个方法,该方法中secret是不允许为空的!因此解决办法就是:将secret随便赋予一个不为空的字符就OK了

4、配置都正确,但是无法正确回调(执行了onError方法,错误码2008,错误信息提示未安装应用)

这个梗我已经不想多说了,但是有些人还是不知道,所以还是说一下吧。造成这个问题的原因就是图片大小超过32K了!所以只需要更改分享图片内容大小就行了

5、源生微信SDK分享成功后,再次分享时,选择后退或关闭(或者重复操作分享时)会闪退

这是什么原因具体不详,但是从添加的jar包看来,应该是使用httpclient请求出问题了。出现这情况,通过百度了解并尝试跟着添加 HttpMine-4.x.x.jar包 以后可以解决,如果还不行的话,请再跟小编一起讨论!

*************************2018-01-27 华丽分割线************************

一月二十七日关于源生微信SDK分享成功后,再次分享时,选择后退或关闭问题的另一个解决方法。
由于项目是比较早的项目源码直接拿过来用的,因此也没太注意。直到在最近更新过程中,这个分享可以成功,但是在分享时按后退键后会闪退的问题又再次出现了!我那个尴尬啊。。。好了,直接进入正题吧!较早之前的代码使用的是httpclient封装的请求(所以用HttpMine-4.x.x.jar包来防止闪退),但是我们知道,Google在android5.1(API22)开始,httpclient就已经被废除了,因此我想到了最直接的修改方法–干脆重写 WXEntryActivity.class 的数据请求方法,改用现在最流行的retrofit2框架,于是如我所料,分享再也不会闪退了。。。贴上代码,顺便复习一下retrofit2的使用方法(注意:需考虑多baseurl使用问题!)吧!

5.1、再次解决源生微信SDK可以分享成功,但是在分享界面打开时,按后退键后会闪退的问题

5.1.1、先通过查看微信开放平台,建立相应字段的实体类,由于请求字段的特殊性,这些字段名称不能随意更改

public class MyWXEntry {
    private String access_token;    //接口调用凭证
    private String expires_in;      //ccess_token接口调用凭证超时时间,单位(秒)
    private String refresh_token;   //用户刷新access_token
    private String openid;          //授权用户唯一标识
    private String scope;           //用户授权的作用域,使用逗号(,)分隔
    private String unionid;         //用户统一标识,当且仅当已获得该用户的userinfo授权时,才会出现该字段
    private String code;            //用户换取access_token的code,仅在ErrCode为0时有效
    private String nickname;        //用户昵称
    private String sex;             //用户性别,1为男性,2为女性
    private String headimgurl;      //用户头像
    (还有少部分比如country、city等,因为不需要,所以我也就不列入字段了)
        ......
    (getter和setter方法就不贴出来了)

5.1.2、设置retrofit的baseUrl和创建IWXUrl.class接口

/**
 * 通过code获取access_token,请求的url:
 * "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
 * + ThirdDefine.WeixinAppID + "&secret="
 * + ThirdDefine.WeixinAppSecret
 * + "&code=" + code + "&grant_type=authorization_code"
 * 
 * 检验授权凭证(access_token)是否有效,返回用户信息请求的url:
 * "https://api.weixin.qq.com/sns/userinfo?access_token=" + accesstoken + "&openid=" + openid
 */

private static final String BASEURL = "https://api.weixin.qq.com/";
public interface IWXUrl {
    @GET("sns/oauth2/access_token")
    Call getToken(@Query("appid") String appid,
                          @Query("secret") String secret,
                          @Query("code") String code,
                          @Query("grant_type") String grant_type
    );

    @GET("sns/userinfo")
    Call getUserInfo(
            @Query("access_token") String access_token,
            @Query("openid") String openid
    );
}

5.1.3、创建retrofit实例

public class RetrofitUtil {

    private static RetrofitUtil instance;
    private Retrofit mRetrofit;

    private RetrofitUtil(String base_url){
        mRetrofit = new Retrofit.Builder()
                .baseUrl(base_url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    /**
     * 单例模式
     *
     * @return
     */
    public static RetrofitUtil getInstance(String base_url) {
        if (instance == null) {
            synchronized (RetrofitUtil.class){
                if (instance==null){
                    instance = new RetrofitUtil(base_url);
                }
            }
        }
        return instance;
    }

    public  T create(final Class bean) {
        return mRetrofit.create(bean);
    }
}

5.1.4、在WXEntryActivity.class中实例化mRetrofit,请求到Access_Token和Openid后再通过它们去请求UserInfo

......
private RetrofitUtil mRetrofit = RetrofitUtil.getInstance(BASEURL);
......
@Override
    public void onResp(BaseResp resp) {
        switch (resp.getType()) {
            case ConstantsAPI.COMMAND_SENDAUTH://登录发送广播
            {
                if (resp instanceof SendAuth.Resp) {
                    SendAuth.Resp authResp = (SendAuth.Resp) resp;
                    switch (authResp.errCode) {
                        case BaseResp.ErrCode.ERR_OK://授权成功
                        {
                            getTokenAndOpenid(authResp.code);
                        }
                        break;
          .......
      }
    finish();
    }

private void getTokenAndOpenid(final String code) {
        final IWXUrl iUrlService = mRetrofit.create(IWXUrl.class);
        new Thread(new Runnable() {

            @Override
            public void run() {
                Call call = iUrlService.getToken(
                        ThirdDefine.WeixinAppID,
                        ThirdDefine.WeixinAppSecret,
                        code,                   
                        "authorization_code"   //这个是固定死的
                );
                MyWXEntry tokenAndOpenid=null;
                try {
                    Response response = call.execute();
                    tokenAndOpenid = response.body();
                    //将获取的数据通过消息发送到主线程
                    Message message_0 = Message.obtain();
                    message_0.obj = tokenAndOpenid;
                    message_0.what = 0;
                    mhandler.sendMessage(message_0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

Handler mhandler = new Handler() {
  String refreshtoken;
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    MyWXEntry myWXEntry = (MyWXEntry) msg.obj;
                    refreshtoken = myWXEntry.getRefresh_token();
                    getUserData(myWXEntry.getAccess_token(), myWXEntry.getOpenid());
                    break;
                case 1:
                    MyWXEntry userInfo = (MyWXEntry) msg.obj;
                    //将你想要的数据进行封装或者直接拿出来使用,比如userInfo.getNickname就是用户昵称
                    JSONObject data = new JSONObject();
                    try {
                        data.put("image_url", userInfo.getHeadimgurl());
                        data.put("gender", userInfo.getSex());
                        data.put("name", userInfo.getNickname());
                        data.put("unionid", userInfo.getUnionid());
                        data.put("refresh_token",  refreshtoken);
                        data.put("openid", userInfo.getOpenid());
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    if (data != null) {
                        //若需要回调json数据,则封装好的infoData 就是最终需要的数据
                        String infoData = data.toString();
                    }
                    finish();
                    break;
            }
        }
    };

private void getUserData(final String token, final String openid) {
        final IWXUrl iUrlService = mRetrofit.create(IWXUrl.class);
        new Thread(new Runnable() {

            @Override
            public void run() {
                Call call = iUrlService.getUserInfo(
                        token,
                        openid
                );
                MyWXEntry userInfo;
                try {
                    Response response = call.execute();
                    userInfo = response.body();
                    //将获取的数据通过消息发送到主线程
                    Message message_0 = Message.obtain();
                    message_0.obj = userInfo;
                    message_0.what = 1;
                    mhandler.sendMessage(message_0);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

OK,至此就全部搞定了!怀着忐忑的心,测试了一下,登陆成功!又测试了分享功能,不断点击分享–后退–分享–后退。。。终于不会闪退了。。。万恶的httpclient啊。。。

你可能感兴趣的:(Android)