1. 程式人生 > >Android微信分享功能整合開發指南(這一篇就夠了)

Android微信分享功能整合開發指南(這一篇就夠了)

前言

本文介紹的只是微信開發中的一個功能,分享。看到網上很多關於微信分享的部落格、帖子,說實話,沒幾篇寫的全的,很多都是複製貼上,介紹的也不全,缺少程式碼的分析,關鍵性的程式碼總是漏一句兩句,看著就很難受。所以,在這裡我打算寫一篇關於微信分享的部落格,總結一下知識點,貼上詳細的程式碼。學微信分享,這一篇就夠了。

準備工作

1.微信開放平臺申請應用,分享需要用到appId,這裡注意了,申請時用到的是MD5值,而不是SHA1值(這裡我就弄錯過,導致分享一直都是失敗,返回的狀態碼為-6)。不知道怎麼在AS中得到簽名信息的同學也不要緊,微信開放平臺上有一個apk專門可以用來獲取簽名,這裡附上鍊接

點選前往
2.在自定義的Application中的onCreate方法中,註冊一下app,程式碼如下:

// 三個引數分別是上下文、應用的appId、是否檢查簽名(預設為false)
IWXAPI mWxApi = WXAPIFactory.createWXAPI(this, "你的appId", true);
// 註冊
mWxApi.registerApp("你的appId");

3.微信分享是肯定需要請求網路的,所以要在manifests檔案中允許網路許可權:

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

4.在app模組的build.gradle檔案中,新增如下依賴:

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

或者

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

這兩個依賴乍一看是一樣的,區別在於,第一個是with,第二個是without。其中,第一個依賴包含統計功能。說實話,我也沒用過它的統計功能,但是我一般都是依賴第一個,說不定什麼時候就需要用到了呢。依賴好後,同步一下。

開始使用

微信分享,可以是純文字型別、圖片型別、音樂型別、視訊型別、網頁型別、小程式型別。這麼多型別如何實現,微信開放平臺上有完整的程式碼實現,只是少了一個引數,看過的同學就知道啦,老樣子,還是附上鍊接點選前往。我的專案中用到的是網頁型別,所以我下面貼出的也是分享網頁型別的程式碼,如果需要用到別的型別的,去我上面的連結裡看一下就清晰了,其實程式碼本質都是一樣的,只是個別引數變了一下。我把請求的程式碼寫到了一個工具類裡,方便呼叫,下面附上程式碼:

public class WxShareUtils {
/**
     * 分享網頁型別至微信
     *
     * @param context 上下文
     * @param appId   微信的appId
     * @param webUrl  網頁的url
     * @param title   網頁標題
     * @param content 網頁描述
     * @param bitmap  點陣圖
     */
    public static void shareWeb(Context context, String appId, String webUrl, String title, String content, Bitmap bitmap) {
        // 通過appId得到IWXAPI這個物件
        IWXAPI wxapi = WXAPIFactory.createWXAPI(context, appId);
        // 檢查手機或者模擬器是否安裝了微信
        if (!wxapi.isWXAppInstalled()) {
            ToastUtil.makeText("您還沒有安裝微信");
            return;
        }

        // 初始化一個WXWebpageObject物件
        WXWebpageObject webpageObject = new WXWebpageObject();
        // 填寫網頁的url
        webpageObject.webpageUrl = webUrl;

        // 用WXWebpageObject物件初始化一個WXMediaMessage物件
        WXMediaMessage msg = new WXMediaMessage(webpageObject);
        // 填寫網頁標題、描述、點陣圖
        msg.title = title;
        msg.description = content;
        // 如果沒有點陣圖,可以傳null,會顯示預設的圖片
        msg.setThumbImage(bitmap);

        // 構造一個Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        // transaction用於唯一標識一個請求(可自定義)
        req.transaction = "webpage";
        // 上文的WXMediaMessage物件
        req.message = msg;
        // SendMessageToWX.Req.WXSceneSession是分享到好友會話
        // SendMessageToWX.Req.WXSceneTimeline是分享到朋友圈
        req.scene = SendMessageToWX.Req.WXSceneSession;

        // 向微信傳送請求
        wxapi.sendReq(req);
    }
}

工具類寫好了,最後只要在你需要的地方呼叫就行了。這裡補充一下,得到本地的bitmap很簡單,只要通過工廠類就能實現,如果是網路圖片呢?不知道的繼續往下看,我這裡使用了Glide這個控制元件。這個控制元件有多NB,不需要我在這裡展開說明了吧。Glide有個方法可以直接非同步獲取網路圖片的點陣圖(我這裡使用的是4.0.0版本,別的版本大家可以去Github檢視,看有沒有變化),老樣子,貼上程式碼:

Glide.with(this).asBitmap().load("圖片url").into(new SimpleTarget<Bitmap>() {
            /**
             * 成功的回撥
             */
            @Override
            public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) {
                // 下面這句程式碼是一個過度dialog,因為是獲取網路圖片,需要等待時間
                mDialog.dismiss();
                // 呼叫方法
                WxShareUtils.shareWeb(this, "你的appId",
                        "網頁url", "網頁標題", "網頁描述",
                         bitmap);
            }

            /**
             * 失敗的回撥
             */
            @Override
            public void onLoadFailed(@Nullable Drawable errorDrawable) {
                super.onLoadFailed(errorDrawable);
                mDialog.dismiss();

                WxShareUtils.shareWeb(this, "你的appId",
                        "網頁url", "網頁標題", "網頁描述",
                         null);
            }
});

這裡還是需要補充一下,圖片大小超過32KB(我記得沒錯應該是這個值),會導致分享介面調不起來,這裡就需要壓縮一下圖片了,壓縮圖片的程式碼大家去網上找一下吧,以前我寫過,但是暫時找不到了,怕網上隨便找的有問題,誤導大家,大家就辛苦一下自己找找吧,還是有很多的,基本沒啥大問題。

收尾工作

在app模組包的根目錄下新建一個wxapi的包,在這個包下面新建一個WXEntryActivity,這兩步缺一不可,而且名字也要一模一樣,不要問我為什麼,微信規定的。
重點用紅框標記了
這個WXEntryActivity就是個普通的Activity,先貼上佈局,其實就是一個最簡單的空佈局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

</android.support.constraint.ConstraintLayout>

下面就是這個Activity的程式碼:

public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {

    private IWXAPI wxapi;

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        wxapi.handleIntent(intent, this);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wxentry);

        wxapi = WXAPIFactory.createWXAPI(this, "你的appId");
        wxapi.handleIntent(getIntent(), this);
    }

    /**
     * 微信傳送請求到第三方應用時,會回撥到該方法
     */
    @Override
    public void onReq(BaseReq baseReq) {
        // 這裡不作深究
    }

    /**
     * 第三方應用傳送到微信的請求處理後的響應結果,會回撥到該方法
     * app傳送訊息給微信,處理返回訊息的回撥
     */
    @Override
    public void onResp(BaseResp baseResp) {
        switch (baseResp.errCode) {
            // 正確返回
            case BaseResp.ErrCode.ERR_OK:
                switch (baseResp.getType()) {
                    // ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX是微信分享,api自帶
                    case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:
                        // 只是做了簡單的finish操作
                        finish();
                        break;
                    default:
                        break;
                }
                break;
            default:
                // 錯誤返回
                switch (baseResp.getType()) {
                    // 微信分享
                    case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:
                        Log.i("WXEntryActivity" , ">>>errCode = " + baseResp.errCode);
                        finish();
                        break;
                    default:
                        break;
                }
                break;
        }
    }
}

這樣還沒完,最後需要在manifests檔案中申明這個Activity,程式碼如下(複製貼上的話,把程式碼中的註釋去掉就可以了):

<activity
    // 下面三行程式碼必須要有
    android:name=".wxapi.WXEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"
    // 下面兩行程式碼可有可無
    android:screenOrientation="portrait"
    // 指定一個主題,這裡是無標題、半透明的主題
    android:theme="@style/NoTitleTranslucent80Theme"/>

下面是指定主題的程式碼,寫在style.xml檔案裡(windowAnimationStyle可以不新增,這裡只是一個動畫):

<style name="NoTitleTranslucent80Theme" parent="BaseAppTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowBackground">#80000000</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowAnimationStyle">@style/AlphaAnim</item>
</style>

下面是動畫的style(程式碼中兩個item從上至下分別是進入動畫、退出動畫):

<style name="AlphaAnim" parent="android:Animation">
    <item name="@android:windowEnterAnimation">@anim/bottom_in</item>
    <item name="@android:windowExitAnimation">@anim/bottom_out</item>
</style>

bottom_in 的程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromXDelta="0"
        android:fromYDelta="100%"
        android:toXDelta="0"
        android:toYDelta="0" />
</set>

bottom_out 的程式碼如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="0"
        android:toYDelta="100%" />
</set>

至此,一個完整的微信分享功能就實現了。

總結

只要按照上面的步驟一步步來,基本就能實現微信分享功能了。其中,要注意一點,
分享的圖片大小不能大於32KB
分享的圖片大小不能大於32KB
分享的圖片大小不能大於32KB
最好自己寫個壓縮的方法。