Android分享集成系列之微信分享

項目中單獨集成微信分享,集成起來還算順利,但是還是有一些坑需要注意。下面我來說說這個具體的過程:

集成流程

1.申請你的AppID
2.下載SDK及API文檔
3.搭建開發(fā)環(huán)境
4.在代碼中使用開發(fā)工具包
總之,具體參考微信開放平臺的接入流程,嚴格按照流程進行集成。點擊查看集成地址

代碼實現

在具體講解代碼實現前,保證你已經做到以下幾點,測試才能通過:

  • 應用已經通過審核
  • 創(chuàng)建的應用包名與項目包名一致

開始實現

(1)添加依賴:
dependencies {
    compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}

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

(其中,前者包含統(tǒng)計功能)

(2)清單文件權限申明:
<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.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(3)將應用注冊到微信:

要使你的程序啟動后微信終端能響應你的程序,必須在代碼中向微信終端注冊你的APP_ID。(可以在程序入口Activity的onCreate回調函數處,或其他合適的地方將你的應用id注冊到微信)

public void regToWeiXin() {
        wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID, true);
        wxapi.registerApp(appID);
    }
(4)分享到微信:
  1. 判斷當前設備是否安裝微信:
/**
     * 判斷是否安裝微信
     */
    public boolean isWeiXinAppInstall() {
        if (wxapi == null)
            wxapi = WXAPIFactory.createWXAPI(WRKApplication.getContext(), appID);
        if (wxapi.isWXAppInstalled()) {
            return true;
        } else {
            Toast.makeText(WRKApplication.getContext(), R.string.no_install_wx, Toast.LENGTH_SHORT).show();
            return false;
        }
    }
  1. 如果已安裝,判斷當前版本號對分享的支持情況:
不同微信版本對開放平臺接口的支持(New)

發(fā)送信息:4.0及以上版本微信iPhone、Android客戶端;
接收/查看信息:4.0及以上版本微信iPhone、Android、Sybiam客戶端;
發(fā)送到朋友圈:4.2及以上版本微信iPhone、Android客戶端;
收藏到我的收藏:5.0及以上版本微信iPhone、Android客戶端。

判斷版本:(這個方法只判斷是否支持分享到朋友圈,其他判斷類似)

/**
     * 是否支持分享到朋友圈
     */
    public boolean isWXAppSupportAPI() {
        if (isWeiXinAppInstall()) {
            int wxSdkVersion = wxapi.getWXAppSupportAPI();
            if (wxSdkVersion >= TIMELINE_SUPPORTED_VERSION) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
  1. 分享數據:(支持文本、圖片、表情、音頻、視頻、url鏈接、小程序)
  • 分享文本:
/**
     * 分享文本類型
     *
     * @param text 文本內容
     * @param type 微信會話或者朋友圈等
     */
    public void shareTextToWx(String text, int type) {
        if (text == null || text.length() == 0) {
            return;
        }

        WXTextObject textObj = new WXTextObject();
        textObj.text = text;

        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = textObj;
        msg.description = text;

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("text");
        req.message = msg;
        req.scene = type;

        getWxApi().sendReq(req);
    }
  • 分享圖片(代碼中開啟一個線程用來加載網絡圖片,顯示縮略圖)
/**
     * 分享圖片到微信
     */

    public void shareImageToWx(final String imgUrl, String title, String desc, final int wxSceneSession) {
        Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
        WXImageObject imgObj = new WXImageObject(bmp);

        final WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = imgObj;
        msg.title = title;
        msg.description = desc;
        final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
        bmp.recycle();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InputStream imageStream = getImageStream(imgUrl);
                    Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                    msg.mediaObject = new WXImageObject(bitmap);
                    thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                    bitmap.recycle();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);

                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("img");
                req.message = msg;
                req.scene = wxSceneSession;
                getWxApi().sendReq(req);
            }
        }).start();
    }
  • 分享音頻:
/**
     * 分享音樂
     *
     * @param musicUrl       音樂資源地址
     * @param title          標題
     * @param desc           描述
     * @param wxSceneSession
     */
    public void shareMusicToWx(final String musicUrl, final String title, final String desc, final String iconUrl, final int wxSceneSession) {
        WXMusicObject music = new WXMusicObject();
        music.musicUrl = musicUrl;

        final WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = music;
        msg.title = title;
        msg.description = desc;

        Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
        final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
        bmp.recycle();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InputStream imageStream = getImageStream(iconUrl);
                    Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                    thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                    bitmap.recycle();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("music");
                req.message = msg;
                req.scene = wxSceneSession;
                getWxApi().sendReq(req);
            }
        }).start();
    }
  • 分享視頻:
/**
     * 分享視頻
     *
     * @param videoUrl       視頻地址
     * @param title          標題
     * @param desc           描述
     * @param wxSceneSession
     */

    public void shareVideoToWx(String videoUrl, String title, String desc, final String iconUrl, final int wxSceneSession) {
        WXVideoObject video = new WXVideoObject();
        video.videoUrl = videoUrl;

        final WXMediaMessage msg = new WXMediaMessage(video);
        msg.title = title;
        msg.description = desc;
        Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
        final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
        bmp.recycle();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InputStream imageStream = getImageStream(iconUrl);
                    Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                    thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                    bitmap.recycle();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);

                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("video");
                req.message = msg;
                req.scene = wxSceneSession;
                getWxApi().sendReq(req);
            }
        }).start();
    }
  • 分享鏈接:
/**
     * 分享url地址
     *
     * @param url            地址
     * @param title          標題
     * @param desc           描述
     * @param wxSceneSession 類型
     */
    public void shareUrlToWx(String url, String title, String desc, final String iconUrl, final int wxSceneSession) {

        WXWebpageObject webpage = new WXWebpageObject();
        webpage.webpageUrl = url;
        final WXMediaMessage msg = new WXMediaMessage(webpage);
        msg.title = title;

        msg.description = desc;
        Bitmap bmp = BitmapFactory.decodeResource(WRKApplication.getContext().getResources(), R.mipmap.ic_launcher);
        final Bitmap[] thumbBmp = {Bitmap.createScaledBitmap(bmp, THUMB_SIZE, THUMB_SIZE, true)};
        bmp.recycle();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    InputStream imageStream = getImageStream(iconUrl);
                    Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
                    thumbBmp[0] = Bitmap.createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true);
                    bitmap.recycle();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                msg.thumbData = WRKFileUtil.bmpToByteArray(thumbBmp[0], true);
                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = buildTransaction("webpage");
                req.message = msg;
                req.scene = wxSceneSession;
                getWxApi().sendReq(req);
            }
        }).start();
    }

這幾種分享已經滿足項目需求,所以沒有做小程序分享。如果有需要直接參看開發(fā)平臺Demo即可。

(5)分享后接受微信的回調:WXEntryActivity類實現
  • 在你的包名相應目錄下新建一個wxapi目錄,并在該wxapi目錄下新增一個WXEntryActivity類,該類繼承自Activity(必須確保申請時的包名下,否則接收不到信息)
  • 在manifest文件里面加上exported屬性,設置為true
<activity
            android:name=".wxapi.WXEntryActivity"
            android:exported="true"
            android:theme="@style/AppTheme.Fullscreen.Translucent" />

回調接受處理:

public class WRKWxEntryActivity extends Activity implements IWXAPIEventHandler {
    private IWXAPI api;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 通過WXAPIFactory工廠,獲取IWXAPI的實例
        api = WRKShareUtil.getInstance().getWxApi();
        //注意:
        //第三方開發(fā)者如果使用透明界面來實現WXEntryActivity,需要判斷handleIntent的返回值,如果返回值為false,則說明入參不合法未被SDK處理,應finish當前透明界面,避免外部通過傳遞非法參數的Intent導致停留在透明界面,引起用戶的疑惑
        try {
            api.handleIntent(getIntent(), this);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {
//        System.out.println(baseReq);
    }

    @Override
    public void onResp(BaseResp baseResp) {
        int result;
        switch (baseResp.errCode) {
            case BaseResp.ErrCode.ERR_OK:
                result = R.string.errcode_success;
                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = R.string.errcode_cancel;
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = R.string.errcode_deny;
                break;
            case BaseResp.ErrCode.ERR_UNSUPPORT:
                result = R.string.errcode_unsupported;
                break;
            default:
                result = R.string.errcode_unknown;
                break;
        }
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
        finish();
    }
}

到這基本上就實現分享功能了,如果這樣,那你就厲害了。這里我再說一下在集成時遇到的問題:

集成問題與解決:

  1. 點擊分享后,出現 “ 不合法的參數,無法分享到微信。返回到沒有審核的應用 ” ,出現這個問題是因為我把APP_ID寫錯了。APP_ID一般為一個以wx開頭的18個字符的字符串。
  2. 分享了多條數據,發(fā)現有幾條數據點擊分享,不能把微信調起來。這個時候你就需要查看你分享的數據是否符合微信規(guī)定的限制條件。要對應限制條件,進行處理。來看一下源碼:(檢查發(fā)送時的縮略圖大小是否超過32k)
final boolean checkArgs() {
        if(this.getType() == 8 && (this.thumbData == null || this.thumbData.length == 0)) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData should not be null when send emoji");
            return false;
        } else if(this.thumbData != null && this.thumbData.length > '耀') {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, thumbData is invalid");
            return false;
        } else if(this.title != null && this.title.length() > 512) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, title is invalid");
            return false;
        } else if(this.description != null && this.description.length() > 1024) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, description is invalid");
            return false;
        } else if(this.mediaObject == null) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaObject is null");
            return false;
        } else if(this.mediaTagName != null && this.mediaTagName.length() > 64) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, mediaTagName is too long");
            return false;
        } else if(this.messageAction != null && this.messageAction.length() > 2048) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageAction is too long");
            return false;
        } else if(this.messageExt != null && this.messageExt.length() > 2048) {
            Log.e("MicroMsg.SDK.WXMediaMessage", "checkArgs fail, messageExt is too long");
            return false;
        } else {
            return this.mediaObject.checkArgs();
        }
    }

看看你沒有分享成功的原因有沒有這些,要是仔細看日志的伙伴應該也能發(fā)現這個問題。所以我在代碼中做出了處理:

 String title = mShareData.getTitle();
 if (title != null && title.length() > 512)
        title = title.substring(0, 511);
 String desc = mShareData.getDesc();
 if (desc != null && desc.length() > 1024)
       desc = desc.substring(0, 1023);

總結:

最終集成成功了,遇到的問題也基本解決了。微信的集成與其他的集成大致看一下,套路都是一樣的。想一想要是集成其他的,遇到的這些坑,其他分享應該也會有。比如說限制條件。

由于項目有多個端(APP_ID有多個),都需要分享功能。所以把分享功能放到了公共庫,但是這樣公共庫不能訪問到各個端的APP_ID,所以我將APP_ID放到各個端的清單文件中,以mete_data的形式在運行時動態(tài)獲取。如果不懂這一流程,可以看我的一篇文章:運行時動態(tài)獲取清單數據

微信分享工具類,下載地址

希望這個分享能對你有幫助,收尾!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,310評論 25 708
  • 發(fā)現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,241評論 4 61
  • 在mybatis 3.4.0版本中新增了一個功能,查詢可以返回Cusror<T>類型的數據,類似于JDBC里的Re...
    Draft灬h閱讀 34,440評論 1 4
  • 去年四月經不住同事的“忽悠”,學校的流浪小奶貓?zhí)^可憐,故而收留。也開始了自己成家后的第一次在城市養(yǎng)貓。從不足一個...
    艾冰臺閱讀 517評論 3 1
  • by橘生淮北 烏蒙小鎮(zhèn)的天永遠是灰蒙蒙的,時時刻刻都醞釀著大暴雨。奇怪的是下雨的時候從來只...
    年更搖閱讀 403評論 0 1