1. 程式人生 > >cocos2dx接入微信sdk,分享文字和截圖

cocos2dx接入微信sdk,分享文字和截圖

首先,你得擁有一個微信開放平臺,需要一個AppID。

然後在微信平臺下,下載開發工具包,放在android下的libs檔案裡面。比如:libammsdk.jar

然後在AndroidManifest.xml中新增許可權。

    <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"/>

下面開始寫java程式碼。
首先在android下的src建立資料夾,比如:src\com\share\game。
建立一個WXapi.java

引入一些要用的包。

import com
.tencent.mm.opensdk.modelmsg.SendMessageToWX; import com.tencent.mm.opensdk.modelmsg.WXImageObject; import com.tencent.mm.opensdk.modelmsg.WXMediaMessage; import com.tencent.mm.opensdk.modelmsg.WXTextObject; import com.tencent.mm.opensdk.modelmsg.WXWebpageObject; import com.tencent.mm.opensdk.openapi
.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory;

在一個WXapi的class裡面,定義一些必要的屬性,比如wx_api和app_id。還有sContext。
然後在這兩行程式碼中開始註冊。
這裡的app_id就是你開放平臺的id。

private static IWXAPI wx_api;
    private static Cocos2dxActivity sContext = (Cocos2dxActivity) Cocos2dxActivity.getContext();
    public static final String APP_ID = "wx3d4e39axxxxxxxx";

wx_api = WXAPIFactory.createWXAPI(sContext, APP_ID, true);
wx_api.registerApp(APP_ID);

下面則是寫的微信分享文字,其中分享或收藏的目標場景,通過修改scene場景值實現。
傳送到聊天介面——WXSceneSession
傳送到朋友圈——WXSceneTimeline
新增到微信收藏——WXSceneFavorite

    public static void shareToWX(){

        String strText = "this is my WX share";

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

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

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

        wx_api.sendReq(req);
    }

然後這是微信分享圖片到朋友圈。

public static void shareToImg(String path){

        Bitmap bmp = BitmapFactory.decodeFile(path);

        WXImageObject imgObj = new WXImageObject(bmp);
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = imgObj;

        //設定縮圖

        Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 150, bmp.getHeight() * 150 / bmp.getWidth(), true);
        bmp.recycle();
        msg.thumbData = Util.bmpToByteArray(thumbBmp, true);

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("img");
        req.message = msg;
        req.scene = SendMessageToWX.Req.WXSceneTimeline;

        wx_api.sendReq(req);

    }

這裡面的buildTransaction()函式文件裡面沒有,需要自己重寫。

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

還有在分享圖片的Util.bmpToByteArray(),這個東西也沒有,也需要自己在同目錄下寫一個util的類。

public class Util {

    public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        bmp.compress(CompressFormat.PNG, 100, output);
        if (needRecycle) {
            bmp.recycle();
        }

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

        return result;
    }
}

好了,以上就是分享到微信的java程式碼,然後我自己也寫了一個主要測試在android中訪問圖片的一個函式。我從外面獲取到路徑path,然後我在android上去顯示出來。由於是因為android渲染,所以要在UI執行緒裡面跑。
當然,我這裡是修改了Cocos2dxActivity.java的程式碼,把mFrameLayout的屬性變成了public。以便於這裡的訪問。

或許有其他更好的方法,請指教。

    public static String _path = null;

    public static void showToImg(String path){
        _path = path;

        sContext.runOnUiThread(new Runnable(){
            @Override
            public void run(){

                Bitmap bmp = BitmapFactory.decodeFile(_path);

                ImageView image = new ImageView(sContext);
                image.setImageBitmap(bmp);

                ViewGroup.LayoutParams lypt=new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                image.setLayoutParams(lypt); 
                sContext.mFrameLayout.addView(image);


            }
        }); 
    }

還有一個被忽視的重要java程式碼。那就是微信的回撥。
還是在src目錄下新建一個檔案,比如:src\wxapi 目錄裡面。
新建立一個WXEntryActivity.java。
然後引入WXapi。

import com.share.game.WXapi

具體程式碼如下:

public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        WXapi.getWx().handleIntent(getIntent(), this);
    }

    @Override
    public void onReq(BaseReq arg0) {
        Log.d("Mohjong onReq", "11111111111111111111111111msg from wx");

        this.finish();
    }

    @Override
    public void onResp(BaseResp resq) {
        Log.d("Mohjong onResp", "2222222222222222222222222msg from wx");
    }

}

在androidManifest.xml裡面新增

<activity android:name="wxapi.WXEntryActivity1111"
                  android:label="@string/app_name"
                  android:exported="true" />

其中WXapi.getWX();是在WXapi.java中的一個靜態函式,主要是為了返回wx_api。

好了,接下來就是jni互動時間。
首先,呼叫分享文字,無引數呼叫。

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

        //shareToWX

        JniMethodInfo t;
        bool ishave = JniHelper::getStaticMethodInfo(t, "com/share/game/WXapi", "shareToWX", "()V");
        if (ishave) {
            t.env->CallStaticVoidMethod(t.classID, t.methodID);
        }
#endif

可以寫在按鈕響應事件裡面。
接下來是,截圖,然後獲取路徑,傳入到java裡面。

Size winSize = Director::getInstance()->getWinSize();
        RenderTexture* render = RenderTexture::create(winSize.width, winSize.height);

        render->begin();
        this->getParent()->visit();
        render->end();

        render->saveToFile("share.png", Image::Format::PNG);
        std::string str = FileUtils::sharedFileUtils()->getWritablePath() + "share.png";

上面是截圖程式碼,str是路徑。其中傳入java中string要變為char*,並且還要經過轉換為jstring才能開始傳入。

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

            std::string str = FileUtils::sharedFileUtils()->getWritablePath() + "share.png";

            JniMethodInfo t;
            bool ishave = JniHelper::getStaticMethodInfo(t, "com/share/game/WXapi", "shareToImg", "(Ljava/lang/String;)V");

            jstring _path = t.env->NewStringUTF(str.c_str());

            if (ishave) {
                t.env->CallStaticVoidMethod(t.classID, t.methodID, _path);
    }
#endif

還有一個jni的互動的問題,在getStaticMethodInfo()的引數裡面後面那個v表示無返回,但是,你會傳入一個string型別的引數,所以在前面的括號裡面要填寫string的型別。叫做簽名好像。

有一個注意點,截圖後,不要馬上分享,或者讀取,因為有可能沒有儲存完畢,你就訪問了後,就會報錯,所以,等一下再訪問就沒有問題了。

下面我會把我的這一份測試程式碼上傳。