安卓开发之集成微信登录以及分享群聊,朋友圈功能。

准备工作

先申请应用的各种ID,官网地址:https://open.weixin.qq.com

集成

  • 添加依赖。
 implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
 implementation 'com.squareup.okhttp3:okhttp:3.4.1'
  • 登录调用代码
 WechatUtils.getInstance().login()
  • 微信登录分享的工具类  WechatUtils
**
 * @author wangheru
 * @date 2019/11/18
 */
public class WechatUtils {
    private static WechatUtils instance;
    private IWXAPI wxAPI;
    private Context context;
    private final String appId;

    public WechatUtils() {
        context = HealtyApplication.getInstance().getApplicationContext();
        appId = context.getResources().getString(R.string.wechat_app_id);
        wxAPI = WXAPIFactory.createWXAPI(context, appId, true);
        wxAPI.registerApp(appId);
    }

    /**
     * 微信登陆(三个步骤)
     * 1.微信授权登陆
     * 2.根据授权登陆code 获取该用户token
     * 3.根据token获取用户资料
     */
    public void login() {
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = String.valueOf(System.currentTimeMillis());
        wxAPI.sendReq(req);
    }

    /**
     * 微信分享--分享链接
     *
     * @param friendsCircle 是否分享到朋友圈
     * @param title         分享的标题
     * @param desc          分享的描述
     */
    public void shareUrl(boolean friendsCircle, String title, String desc) {
        //判断是否支持分享到微信朋友圈
        if (wxAPI.getWXAppSupportAPI() >= Build.TIMELINE_SUPPORTED_SDK_INT) {
            WXWebpageObject wxWebpageObject = new WXWebpageObject();
            wxWebpageObject.webpageUrl = "www.baidu.com";
            WXMediaMessage msg = new WXMediaMessage(wxWebpageObject);
            msg.title = title;
            msg.description = desc;
            //缩略图
            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg_user_message_card);
            msg.thumbData = bmpToByteArray(bitmap);
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = String.valueOf(System.currentTimeMillis());
            req.message = msg;
            req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
            wxAPI.sendReq(req);
        }
    }

    /**
     * 微信分享---分享图片
     *
     * @param friendsCircle 是否分享到朋友圈
     */
    public void shareImage(boolean friendsCircle, Bitmap bitmap) {
        if (wxAPI.getWXAppSupportAPI() >= Build.TIMELINE_SUPPORTED_SDK_INT) {
            if (bitmap == null) {
                ToastUtils.showImageToast(context, "分享异常");
                return;
            }
            WXMediaMessage msg = new WXMediaMessage();
            //分享图片
//            Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg_user_message_card);
            WXImageObject wxImageObject = new WXImageObject(bitmap);
            msg.mediaObject = wxImageObject;
            SendMessageToWX.Req req = new SendMessageToWX.Req();
            req.transaction = String.valueOf(System.currentTimeMillis());
            req.message = msg;
            req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
            wxAPI.sendReq(req);
        }
    }

    /**
     * Bitmap转换成byte[]并且进行压缩,压缩到不大于32K,缩略图最大32K
     *
     * @param bitmap
     * @return
     */
    public static byte[] bmpToByteArray(Bitmap bitmap) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, output);
        int options = 100;
        int IMAGEMAXSIZE = 32;
        while (output.toByteArray().length > IMAGEMAXSIZE && options != 10) {
            output.reset(); //清空output
            bitmap.compress(Bitmap.CompressFormat.JPEG, options, output);//这里压缩options%,把压缩后的数据存放到output中
            options -= 10;
        }
        if (bitmap != null) {
            bitmap.recycle();
        }

        byte[] result = output.toByteArray();
        try {
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

//    /**
//     * 发起支付
//     *
//     * @param wxPayBean
//     */
//    public void pay(WXPayBean wxPayBean) {
//        PayReq req = new PayReq();
//        req.appId = appId;//appid
//        req.partnerId = wxPayBean.getPartnerid();//微信支付分配的商户号
//        req.prepayId = wxPayBean.getPrepayid();//微信返回的支付交易会话ID
//        req.packageValue = wxPayBean.getPackage_value();//暂填写固定值Sign=WXPay
//        req.nonceStr = wxPayBean.getNoncestr();//随机字符串,不长于32位。推荐随机数生成算法
//        req.timeStamp = wxPayBean.getTimestamp();//时间戳
//        req.sign = wxPayBean.getSign();//签名
//        Log.e("whr", "微信支付:" + req.toString());
//        wxAPI.sendReq(req);
//    }

    public static WechatUtils getInstance() {
        if (instance == null) {
            synchronized (WechatUtils.class) {
                if (instance == null) {
                    instance = new WechatUtils();
                }
            }

        }
        return instance;
    }
}
  • 包下新建文件夹wxapi,处理微信登录逻辑界面  WXEntryActivity。
/**
 * 微信登陆分享回调Activity
 *
 * @author wangheru
 * @create 2019/11/18
 */
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI wxAPI;
    private String appId;
    private String appSecret;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        appId = getResources().getString(R.string.wechat_app_id);
        appSecret = getResources().getString(R.string.wechat_app_secret);
        wxAPI = WXAPIFactory.createWXAPI(this, appId, true);
        // 将该app注册到微信
        wxAPI.registerApp(appId);
        wxAPI.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        wxAPI.handleIntent(getIntent(), this);
        LogUtil.i("whr", "WXEntryActivity onNewIntent");
    }

    @Override
    public void onReq(BaseReq arg0) {
        LogUtil.i("whr", "WXEntryActivity onReq:" + arg0);
    }

    @Override
    public void onResp(BaseResp resp) {
        switch (resp.getType()) {
            case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:
                sendShare(resp.errCode);
                break;
            case ConstantsAPI.COMMAND_SENDAUTH:
                if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
                    SendAuth.Resp authResp = (SendAuth.Resp) resp;
                    getAccessToken(authResp.code);
                } else {
                    sendLoginFail(resp.errCode);
                }
                break;
            default:
                break;
        }
        finish();
    }

    public void getAccessToken(String code) {
        String loginUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=" + appId + "&secret=" + appSecret +
                "&code=" + code + "&grant_type=authorization_code";

        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(loginUrl)
                .get()//默认就是GET请求,可以不写
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.d("whr", "onFailure: " + e.toString());
                sendLoginFail(-1);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();
                LogUtil.d("whr", "getAccessToken--->responseInfo : " + responseInfo);

                if (!TextUtils.isEmpty(responseInfo)) {
                    getWXUserInfo(new Gson().fromJson(responseInfo, WXTokenBean.class));
                } else {
                    sendLoginFail(response.code());
                }
            }
        });
    }

    /**
     * 获取微信信息
     * @param wxTokenBean
     */
    public void getWXUserInfo(WXTokenBean wxTokenBean) {
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" +
                wxTokenBean.getAccess_token() + "&openid=" + wxTokenBean.getOpenid();

        OkHttpClient okHttpClient = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()//默认就是GET请求,可以不写
                .build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.d("whr", "onFailure: " + e);
                sendLoginFail(-1);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String responseInfo = response.body().string();

                if (!TextUtils.isEmpty(responseInfo) && response.code() == 200) {
                    EventBus.getDefault().post(new WXTypeBean(1, BaseResp.ErrCode.ERR_OK, new Gson().fromJson(responseInfo, WXInfoBean.class)));
                } else {
                    sendLoginFail(response.code());
                }
            }
        });
    }

    /**
     * 微信登录失败
     *
     * @param errorCode 失败码
     */
    private void sendLoginFail(int errorCode) {
        LogUtil.i("whr", "微信登录操作....." + errorCode);
        EventBus.getDefault().post(new WXTypeBean(1, errorCode, ""));
    }

    /**
     * 微信分享
     *
     * @param errorCode 失败码
     */
    private void sendShare(int errorCode) {
        LogUtil.i("whr", "微信分享操作....." + errorCode);
        EventBus.getDefault().post(new WXTypeBean(2, errorCode, ""));
    }
}
  • 主页面我是通过eventbus获取的回调信息。
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(WXTypeBean wxTypeBean) {
        Log.i("whr", "收到eventbus请求 type:" + wxTypeBean.getType());
        String msgTitle;
        if (wxTypeBean.getType() == 1) {//登录
            Log.i("whr", "wxTypeBean:" + wxTypeBean.toString());
            msgTitle = "登录";
            if (wxTypeBean.getData() != null) {
                final WXInfoBean wxInfoBean = (WXInfoBean) wxTypeBean.getData();
                tvAge.post(new Runnable() {
                    @Override
                    public void run() {
                        tvAge.setText(wxInfoBean.getAge() + "");
                        tvNickname.setText(wxInfoBean.getNickname() + "");
                    }
                });

                Log.e("whr", "登陆成功,获取到的信息为:" + wxInfoBean.toString());
            }
        } else if (wxTypeBean.getType() == 2) {//分享
            msgTitle = "分享";
        } else if (wxTypeBean.getType() == 3) {//微信支付
            msgTitle = "支付";
        } else {
            msgTitle = "其他";
        }

        switch (wxTypeBean.getErrCode()) {
            case BaseResp.ErrCode.ERR_OK:
                Log.i("whr", "微信" + msgTitle + "成功.....");
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL://分享取消
                Log.i("whr", "微信" + msgTitle + "取消.....");
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED://分享被拒绝
                Log.i("whr", "微信" + msgTitle + "被拒绝.....");
                break;
            default:
                break;
        }
    }
  • AndroidManifest.xml
    //权限
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>


  <application>
        ...
        <activity android:name=".wxapi.WXEntryActivity" android:exported="true"> 
  </application>
  • 最后,添加混淆。
#====微信====
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}
-dontwarn com.tencent.mm.**
-keep class com.tencent.mm.**{*;}

注意事项:

  1. 一直提示我签名与平台签名不对应,错误码 -6。我核对了N多次包名与签名,发现都没错了。后来发现把APP微信卸载了重新安装就能调起了。也是头疼啊。。。
  2. 提示签名和平台签名不对应,除了卸载微信,还可以下载个apk,检查一下你安装在手机上的APP的应用签名,看是否一致!
  3. 遇到debug版本可以调试,打包之后不能分享的情况,就是你的混淆忘记加了,或者没有加全。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值