微信分享功能踩坑过程

最近,做一款应用的分享功能,主要业务是分享一个网页给微信、QQ好友,然后用的是微信开发平台、腾讯开放平台的官方SDK分享。其中遇到了一些打不开、分享不了的坑,填好后,做了一下封装。总结记录一下。

废话不说,先上效果图
微信分享功能踩坑过程_第1张图片

一、微信分享
(一) 配置微信分享、集成SDK
1.先要注册一个微信开发者账号,云云,此处不累述

2.第一个坑:创建应用,并申请APP ID
微信分享功能踩坑过程_第2张图片

2.1 获取 应用签名

第一步:
配置你的应用app下的build.gradle(AS普及这么久了,我已经抛弃Eclipse了)

android {
    // ...

    signingConfigs {
        config {
            keyAlias '你的签名文件名'
            keyPassword 'key的密码(如果有)'
            storeFile file('签名文件的路径,比如我的 D:/signatrue/CHjijidao')
            storePassword 'keystore的密码(如果有)'
        }
    }

    buildTypes {
        // release版本的配置
        release {
            // 是否混淆
            minifyEnabled true
            // 是否去除重复资源
            zipAlignEnabled true
            // 混淆文件
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            // 设置release下的签名配置
            signingConfig signingConfigs.config
            // 是否可以debug模式运行
            debuggable true
        }
        // debug版本的配置
        debug {
            // 默认没有写的时候,build出来的debug版apk是使用的debug.keystore
            // 现在设置签名为配置好的签名
            signingConfig signingConfigs.config
        }
    }
 }

/* 此处的目的是为了配置指定好签名,方便生成微信开发平台中需要填写的 ——“应用签名” */

在清单配置文件的application标签下添加


<receiver
    android:name=".controller.AppRegister"
    android:permission="com.tencent.mm.plugin.permission.SEND" >
    <intent-filter>
        <action android:name="com.tencent.mm.plugin.openapi.Intent.ACTION_REFRESH_WXAPP" />
    intent-filter>
receiver>

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

附赠WXEntryActivity

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);
        IWXAPI api = WXAPIFactory.createWXAPI(this, WechatShareComponent.APP_ID, false);
        api.handleIntent(getIntent(),this);
        finish();
    }

    @Override
    public void onReq(BaseReq baseReq) {

    }

    @BindString(R.string.errcode_success)
    String mErrorCodeStr1;
    @BindString(R.string.errcode_cancel)
    String mErrorCodeStr2;
    @BindString(R.string.errcode_deny)
    String mErrorCodeStr3;
    @BindString(R.string.errcode_unsupported)
    String mErrorCodeStr4;
    @BindString(R.string.errcode_ban)
    String mErrorCodeStr5;
    @BindString(R.string.errcode_unknown)
    String mErrorCodeStr6;
    @Override
    public void onResp(BaseResp baseResp) {
        String result;
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result = mErrorCodeStr1;
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = mErrorCodeStr2;
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = mErrorCodeStr3;
                break;
            case BaseResp.ErrCode.ERR_UNSUPPORT:
                result = mErrorCodeStr4;
                break;
            case BaseResp.ErrCode.ERR_BAN:
                result = mErrorCodeStr5;
                break;
            default:
                result = mErrorCodeStr6;
                break;
        }

        ToastUtil.showLongToastCenter(result);
    }
}

第二步:
安装一个签名工具应用到手机

第三步:
运行你的工程到手机!(你要集成微信分享的app)

第四步:
打开第二步安装的工具应用,输入包名生成“应用签名”

下载这个工具!

微信分享功能踩坑过程_第3张图片

2.2 复制获取到的 ”应用签名“ 字符串填入微信开发平台

2.3 复制申请到的APP_ID.

3.依赖类库

// 分享给微信好友
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'

4.配置权限


<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.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

(二)封装WechatShareComponent

/*
Copyright [2017] [沈煜]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/**
 * date: 2017/12/21
 * description:  WechatShareComponent.java
 * author: 沈煜 
 * blog: http://blog.csdn.net/shenyu_njau
 * 版权所有,转载请注明出处。
 */

public class WechatShareComponent {
    // 你的APP_ID
    public static final String APP_ID = "你的APP_ID";
    private static final String TAG = "WechatShareComponent";
    // 微信分享封装类实例(单例模式)
    private static WechatShareComponent mInstance;
    // 微信IWXAPI对象
    private static IWXAPI wxApi;
    // 微信网页对象
    private static WXWebpageObject mWxWebpageObject;
    // 微信分享信息对象
    private static WXMediaMessage mWxMediaMessage;
    // 分享到微信对象
    private static SendMessageToWX.Req mSReq;

    /**
     * 私有的构造方法,单例模式
     * @params mContext 用于构造和注册IWAPI对象
     */
    private WechatShareComponent(Context mContext) {
        wxApi = WXAPIFactory.createWXAPI(mContext, APP_ID, true);
        wxApi.registerApp(APP_ID);
    }

    /**
     * 私有的WechatShareComponent 构造方法,单例模式
     * @params mContext 用于构造WechatShareComponent 对象
     */
    private static WechatShareComponent createWechatShareInstance(Context mContext) {
        if (mInstance == null) {
            mInstance = new WechatShareComponent(mContext);
        }
        return mInstance;
    }

    /**
     * 构造器模式,WechatShareComponent.Builder对象
     */
    public static class Builder {
        private Context mContext;

        /**
         * WechatShareComponent.Builder的构造方法
         * @params mContext 上下文对象
         */
        public Builder(Context mContext) {
            this.mContext = mContext;
        }

        /**
         * 设置分享内容的url
         * @params url 分享内容的url
         */
        public Builder setShareContentUrl(String url) {
            initWXWebpageObject();
            mWxWebpageObject.webpageUrl = url;
            return this;
        }

        /**
         * 设置分享内容的标题
         * @params title 分享内容的标题
         */
        public Builder setShareContentTitle(String title) {
            initWXMediaMessage();
            mWxMediaMessage.title = title;
            return this;
        }

        /**
         * 设置分享内容的摘要
         * @params summary 分享内容的摘要
         */
        public Builder setShareContentSummary(String summary) {
            initWXMediaMessage();
            mWxMediaMessage.description = summary;
            return this;
        }

        /**
         * 设置分享内容的缩略图
         * @params thumb 分享内容的缩略图bitmap对象
         * 要求图片不能大于32kb
         * 否则会throw checkArgs fail, thumbData is invalid 错误
         */
        public Builder setShareContentImage(Bitmap thumb) {
            try {
                initWXMediaMessage();
                mWxMediaMessage.thumbData = BitmapUtil.compressAndGenImage(thumb, 32);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return this;
        }


        /**
         * 设置分享内容的缩略图
         * @params type 分享内容的缩略图bitmap对象
         */
        public Builder setShareTransaction(String type) {
            initSendMessageToWXRequest();
            mSReq.transaction = buildTransaction(type);
            mSReq.message = mWxMediaMessage;
            mSReq.scene = SendMessageToWX.Req.WXSceneSession;
            return this;
        }

        /**
         * 创建WechatShareComponent对象,调用
         * @see #createWechatShareInstance(Context)
         * @return WechatShareComponent对象
         */
        public WechatShareComponent build() {
            return WechatShareComponent.createWechatShareInstance(mContext);
        }

        /**
         * 初始化WXWebpageObject对象
         */
        private void initWXWebpageObject() {
            if (mWxWebpageObject == null) {
                mWxWebpageObject = new WXWebpageObject();
            }
            LogUtil.d("mWxWebpageObject=" + mWxWebpageObject);
        }


        /**
         * 初始化WXMediaMessage对象
         */
        private void initWXMediaMessage() {
            if (mWxMediaMessage == null) {
                initWXWebpageObject();
                mWxMediaMessage = new WXMediaMessage(mWxWebpageObject);
            }
            LogUtil.d("mWxMediaMessage=" + mWxMediaMessage);
        }

        /**
         * 使用当前时间创建发送分享消息的 transaction
         * @params type 分享内容的类型
         * 主要有文字text、图片pictrue、网页webpage等
         */
        private String buildTransaction(final String type) {
            return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
        }

        /**
         * 初始化SendMessageToWX.Req对象
         */
        private void initSendMessageToWXRequest() {
            if (mSReq == null) {
                mSReq = new SendMessageToWX.Req();
            }
            LogUtil.d("mSReq=" + mSReq);
        }

    }

    /**
     * 发起发送到微信请求,实现分享功能。
     */
    public void share() {
        LogUtil.d("wxApi=" + wxApi);
        wxApi.sendReq(mSReq);
    }
}

封装说明:
1.使用了单例模式,因为一个app要实现微信分享给朋友、朋友圈等功能只需要一个IWXApi对象

2.使用构造器模式,方便设置微信分享所需要设置的参数 : 主要包括类型、标题、摘要、图片、网址链接等。

3.其中使用缩略图时,需要注意图片大小,并使用压缩工具。

/**
 * Compress by quality,  and generate image to the path specified
 *
 * @param image origin image bitmap
 * @param maxSize target will be compressed to be smaller than this size.(kb)
 * @throws Exception
 */
public static byte[] compressAndGenImage(Bitmap image, int maxSize) throws Exception {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    // scale
    int options = 100;
    // Store the bitmap into output stream(no compress)
    image.compress(Bitmap.CompressFormat.JPEG, options, os);
    // Compress by loop
    while ( os.toByteArray().length / 1024 > maxSize) {
        // Clean up os
        os.reset();
        // interval 10
        options -= 10;
        image.compress(Bitmap.CompressFormat.JPEG, options, os);
    }

    // Generate compressed image bitmap
    return os.toByteArray();
}

注意如果图片太大,最好做一个小图,否则压缩了也可能出现:

checkArgs fail, thumbData is invalid

不怎么华丽的分割线


下一篇:QQ分享踩坑

你可能感兴趣的:(Android)