1. 程式人生 > >Android開發丶整合微信原生分享並於分享網頁時載入網路縮圖

Android開發丶整合微信原生分享並於分享網頁時載入網路縮圖

微信分享也是一項很常用的功能了,以往都是用友盟或者mobShareSDK框架來實現的,這兩者在微信官方的sdk基礎上封裝的很好,並且加入了一些很實用性的功能,不過這次因為只有微信平臺的分享,而且微信登入也是基於微信官方的原生SDK的,所以我們就不用再去大費周章地使用友盟和mobsharesdk了,而且也可以學習些新的東西,經過一番折騰除錯,成功地把分享整合成功了,期間也遇到了一些坑,而且微信官方的文件確實不太友好,因此這裡對其進行下總結歸納。

有關微信原生登入的請看我另一篇博文

還是效果圖走起來:

怎麼樣,不錯吧,下來詳述實現流程。

1.首先當然是去微信開放平臺申請應用的appid和appkey了,這裡我不再詳述了。

2.新建wxapi包和WXEntryActivity及相關繼承重寫我在釋出的《Android開發丶整合微信原生登入》這篇博文裡已經有了說明,不再複述。

3.首先開啟WXEntryActivity寫微信分享的回撥

這裡比較重要的一點是(敲黑板!!!)

微信分享和微信登入的回撥都走的onResp()方法,所以我們要加以辨別,否則會混淆一團,好在官方已經返回了相應的type值供我們判斷

//請求回撥結果處理
@Override
public void onResp(BaseResp baseResp) {
    switch (baseResp.errCode) {
        case BaseResp.ErrCode.ERR_OK:
            switch (baseResp.getType()){
                case ConstantsAPI.COMMAND_SENDAUTH:
                    String code = ((SendAuth.Resp) baseResp).code;
                    getAccessToken(code);
                    Log.d("fantasychongwxlogin", code.toString()+ "");
                    break;
                case ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX:
                    Log.d("Fan22", "分享成功");
                    Toast.makeText(getApplicationContext(), "分享成功", Toast.LENGTH_SHORT).show();
                    finish();
                    break;
                default:
                    break;
            }
            break;
        case BaseResp.ErrCode.ERR_AUTH_DENIED://使用者拒絕授權
            finish();
            break;
        case BaseResp.ErrCode.ERR_USER_CANCEL://使用者取消
            finish();
            break;
        default:
            finish();
            break;
    }
}

4.回到啟動分享的入口

這裡以最常見的分享web網頁為例

首先肯定是判斷裝置是否安裝微信了

if (!api.isWXAppInstalled()) {
    Toast.makeText(WebViewActivity.this, "您的裝置未安裝微信客戶端", Toast.LENGTH_SHORT).show();
}

當檢測到有安裝微信客戶端,開始後續的方法。

當分享網頁時,一般會由這三種控制元件構成,標題,描述,縮圖

那麼問題來了,標題和描述官方都給了相應的引數設定,沒什麼問題,但是縮圖官方僅支援載入本地的bitmap

如果我們實際需求中是個圖片url怎麼辦?

辦法當然是有的,考慮後我們決定把這個網路圖片下載到本地儲存成bitmap不就可以了。(我太特麼機智了)

5.這裡就涉及到下載圖片了,該方法呼叫時要放在子執行緒中,之後再通過runOnUiThread()方法操作UI執行緒即可,相關程式碼附上

/**
 * 把網路資源圖片轉化成bitmap
 * @param url 網路資源圖片
 * @return Bitmap
 */
public static Bitmap GetLocalOrNetBitmap(String url) {
    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;
    try {
        in = new BufferedInputStream(new URL(url).openStream(), 1024);
        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        out = new BufferedOutputStream(dataStream, 1024);
        copy(in, out);
        out.flush();
        byte[] data = dataStream.toByteArray();
        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        data = null;
        return bitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}
private static void copy(InputStream in, OutputStream out)
        throws IOException {
    byte[] b = new byte[1024];
    int read;
    while ((read = in.read(b)) != -1) {
        out.write(b, 0, read);
    }
}

private String buildTransaction(final String type) {
    return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
}

6.我們先檢測下該網路圖片是否儲存成本地bitmap了,先用個imageview檢測下

iv.setImageBitmap(bitmap);

有了,有了,紅框的就是!

7.接下來設定相關分享引數

那麼問題又來了,如果因為網路或者某些不可描述的問題導致圖片沒下下來咋整?

完全不慌,檢測是否為空,如果空的話,載入本地的就可以了。

if (bitmap== null){
    bitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_round);
}

接下來設定標題,網頁等引數

WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = "http://www.baidu.com";
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = "這是網頁標題";
msg.description = "這是網頁描述";

將bitmap進行裁剪,賦值

thumbBmp = Bitmap.createScaledBitmap(bitmap, 150, 150, true);
if (bitmap != null && !bitmap.isRecycled()) {
    bitmap = null;
}
msg.thumbData = Util.getBitmapBytes(thumbBmp, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = buildTransaction("webpage");
req.message = msg;
//根據type設定分享情景
switch (type) {
    case TYPE_WECHAT:
        //分享到微信好友
        req.scene = SendMessageToWX.Req.WXSceneSession;
        break;
    case TYPE_WECHAT_MOMENT:
        //分享到微信朋友圈
        req.scene = SendMessageToWX.Req.WXSceneTimeline;
        break;
}
api.sendReq(req);

以上程式碼中,req.scene是設定分享物件的,決定微信好友還是朋友圈,因此我們可以通過在不同的入口傳遞不同的引數進行判斷,決定分享的物件。

showShare(TYPE_WECHAT); 
showShare(TYPE_WECHAT_MOMENT);

這裡說明一下遇到的一些現象和問題:

1.如果不配置APPID和APPSECRET,微信客戶端無法調起

private static final String APP_ID = "";//空值

解決辦法:在申請到正式的APPID,可以先使用其餘通過稽核的應用的APPID值,新建一個測試專案與那個通過稽核的應用的包名一致,簽名檔案一致,保證微信能正常調起以及流程正常跑通,之後把相關程式碼移植到正式專案中,最後在正式專案中更換正式APPID即可。

2.當微信未登陸時,點選分享可以調起客戶端到登陸介面,登陸完成後一閃而過回到應用介面,無法分享到好友或者朋友圈。

解決辦法:當前的配置的APPID值與包名不匹配。更換正式APPID值即可。

3.下載bitmap的方法GetLocalOrNetBitmap()必須在子執行緒中執行。

至此全部完成,demo附上!(因為某些不可描述的原因,本DEMO沒有APPID和APPSECRET值,無法調起微信客戶端,主要看流程即可)

資源下載