廣告

2016年1月11日 星期一

bootstrap disable navbar collapse

html


  

css

.disable-collapse {
    .navbar-collapse.collapse {
        display: block!important;
    }
    .navbar-nav>li,
    .navbar-nav {
        float: left !important;
    }
    .navbar-nav.navbar-right:last-child {
        margin-right: -15px !important;
    }
    .navbar-right {
        float: right!important;
    }
}


參考
 http://jsfiddle.net/t4ym3/

2016年1月7日 星期四

[android] 微信接入(登入,發動態) | weChat auth login,share



sample code
https://github.com/cihm/WeChatDemo

註冊
https://open.weixin.qq.com/cgi-bin/userinfo?lang=zh_CN&token=7a348e868afe006e18453eb53e825c65c231e870
教學
http://mobile.51cto.com/others-388965.htm
http://www.eoeandroid.com/thread-547012-1-1.html?_dsign=491583a0
============================
.程式裡的APP key 要使用開發者後台所提供的.
.要使用app_signatures.apk將包名編譯成md5並且填入開發者後台當中.
.或是直接cmd line跑出來,在自己轉小寫
willy key:7ae51e2d4ca6bb6c5df769148071bed6

登入功能需要開通

前提:
 要得到回傳訊息(不管發動態或是登入)
 一定要在自己於微信後台註冊的package(自己的專案)下面
 新增一個package 叫"wxapi"
 然後在此package下面新增
 "WXEntryActivity.java"並實作IWXAPIEventHandler則就可在onResp拿到回傳

 注意:
 package名稱(wxapi )跟java檔名稱(WXEntryActivity )一要要這樣叫

 androidmenifest:

    
        
        
        
    


===========
分享動態功能
WXEntryActivity => SendToWXActivity
 發送文字
 .將app註冊到APP
 .自訂TextView(EditText )
 .自訂dialog(MMAlert)
 .初始化一个 WXTextObject 对象(將要分享的文字放進去)
 .初始化WXMediaMessage(WXTextObject放進去 )
 .构造一个 Req(SendMessageToWX.Req)
 .调用api接口发送数据到微信(api .sendReq(req) )
 .WXEntryActivity 的onResp會顯示成功與否
其他發送訊息如程式sample所演示.

圖文同時的話目前找到用WXWebpageObject代替


package com.example.wechatsdk.party3control;

import android.app.Activity;
import android.app.Dialog;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;


import com.tencent.mm.sdk.openapi.BaseReq;
import com.tencent.mm.sdk.openapi.BaseResp;
import com.tencent.mm.sdk.openapi.ConstantsAPI;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.SendAuth;
import com.tencent.mm.sdk.openapi.SendMessageToWX;
import com.tencent.mm.sdk.openapi.ShowMessageFromWX;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.mm.sdk.openapi.WXAppExtendObject;
import com.tencent.mm.sdk.openapi.WXMediaMessage;
import com.tencent.mm.sdk.openapi.WXWebpageObject;

/**
* Created by 1409035  lewisli on 2015/11/17.
*/
public class WeChatControl {

    private static WeChatControl instance = new WeChatControl();

    private WeChatControl() {

    }

    public static WeChatControl getInstance() {
        return instance ;
    }

    private static final int THUMB_SIZE = 150 ;
    private IWXAPI iwaxaApi;
    private ApplicationInfo applicationInfo;
    private String appKey;
    private String TAG = "com.wechat.api.wechat_API_KEY";



    public void shareMessage(Activity activity, String text, Bitmap bitmap) {
        //ref:http://mobile.9sssd.com/android/art/1059
        // custom dialog


        String url = "http://test";// 收到分享的好友点击信息会跳转到这个地址去
        WXWebpageObject localWXWebpageObject = new WXWebpageObject();
        localWXWebpageObject.webpageUrl = url;

        WXMediaMessage msg = new WXMediaMessage(localWXWebpageObject);

        //msg.setThumbImage(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
        //Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.send_img);

        Bitmap thumbBmp = Bitmap. createScaledBitmap(bitmap, THUMB_SIZE, THUMB_SIZE, true );

        msg.thumbData = Util.bmpToByteArrayFix(thumbBmp, true);  // 设置缩略图
        bitmap.recycle();

        msg.title = text;
        msg.description = text;

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = System.currentTimeMillis() + "";
        req.message = msg;

        //send global or friend only
        //req.scene = isTimelineCb.isChecked() ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
        req. scene = SendMessageToWX.Req.WXSceneTimeline;
        getiIWXAPI(activity).sendReq(req);

        //finish();
    }


    public IWXAPI getiIWXAPI(Activity activity) {
        if (iwaxaApi == null) {
            setiIWXAPI(WXAPIFactory.createWXAPI (activity, getAppKey(activity), true));


            Log.e( "!!!!", "getiIWXAPI" );
            iwaxaApi.registerApp(getAppKey(activity));
            //iwaxaApi.handleIntent(activity.getIntent(), this);

        }
        return iwaxaApi ;
    }

    public void setiIWXAPI(IWXAPI iwaxAPI) {
        this.iwaxaApi = iwaxAPI;
    }


    private ApplicationInfo getApplicationInfo(Activity activity) {
        if (applicationInfo == null) {
            try {
                setApplicationInfo(activity.getPackageManager().getApplicationInfo(activity.getPackageName(), PackageManager.GET_META_DATA));
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return applicationInfo ;
    }

    private void setApplicationInfo(ApplicationInfo applicationInfo) {
        this.applicationInfo = applicationInfo;
    }

    public String getAppKey(Activity activity) {
        if (appKey == null) {
            setAppKey(getApplicationInfo(activity).metaData.getString( TAG));
        }
        return appKey ;
    }

    public void setAppKey(String appKey) {
        this.appKey = appKey;
    }


    public void login(Activity activity){
        final SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat2chongba";
        getiIWXAPI(activity).sendReq(req);
    }



}
=============
登入功能:

文件
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=88a73255c4a18aa152113ef684fce5dfd2347719&lang=zh_CN

https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317853&lang=zh_CN

  在onResp回傳 =>BaseResp resp
  做轉型
  SendAuth.Resp sendResp = (SendAuth.Resp) resp;
  取token
  sendResp.token
 // 官方文件寫錯(他寫code),但實際上是 token



STEP1:user token to get access_token and openid

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxbff6de7ebe6c9498&secret=a50b0b62ae77557b289c487308aa9faa&code=0112342663e805e50dd7fbe001075d0L&grant_type=authorization_code


STEP2: use refresh_token
=>第一次可跳過,又或者你只需要取得一次用戶資訊,那也可跳過此步驟

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=wxbff6de7ebe6c9498&grant_type=refresh_token&refresh_token=OezXcEiiBSKSxW0eoylIeILPYvLIWkzXq-H0gG9o7k8Dt9ilr91flHHcPwl78kdLCCcgvEVqvNaksf3wpgyqlaIvgSqQwbgV9LnBvgafjJpdJa7R-XExsaMWDy_o7LpKMPkIGvnQsHpKY2_LP5z12g


STEP3: use access_token and openid get user info
https://api.weixin.qq.com/sns/userinfo?access_token=OezXcEiiBSKSxW0eoylIeILPYvLIWkzXq-H0gG9o7k8Dt9ilr91flHHcPwl78kdLXZNZvaTI5NyTOMl1klSSoTbRuXuzd52ZqVe5X9O6QGvd7wFUYOVubwRWhDGLcHzbKzPoZ_ukdukfBBgW1sL7tQ, unionid=oS9mHwNTZYvYeerdgwiGaEzqMBHc&openid=oibTCuAkkFgeUkJeV8bdp6wSgYJI




WXEntryActivity  code


package com.acer.wxapi;


import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.util.task.json.JsonGetTask;


import com.acer.R;
import com.acer.pet.util.ViewUtils;
import com.example.wechatsdk.party3control.WeChatControl;
import com.tencent.mm.sdk.openapi.BaseReq;
import com.tencent.mm.sdk.openapi.BaseResp;
import com.tencent.mm.sdk.openapi.ConstantsAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.SendAuth;

import java.util.ArrayList;
import java.util.HashMap;

import static android.util.Constants.NETWORK_ERROR;
import static com.acer.pet.util.ViewUtils.loadingFinish;
import static com.acer.pet.util.ViewUtils.loadingStart;


public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    private static final int TIMELINE_SUPPORTED_VERSION = 0x21020001 ;
    private static final int RETURN_MSG_TYPE_LOGIN = 1 ;
    private static final int RETURN_MSG_TYPE_SHARE = 2 ;
    private String appId;
    private String secret;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        WeChatControl.getInstance().getiIWXAPI( this).handleIntent(getIntent(), this);


    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.e( "onNewIntent", "!!!" + intent);
        setIntent(intent);
        WeChatControl.getInstance().getiIWXAPI( this).handleIntent(getIntent(), this);
    }

    // 微信发送请求到第三方应用时,会回调到该方法
    @Override
    public void onReq(BaseReq req) {
        Log.e( "onReq", "!!!" + req);
        switch (req.getType()) {
            case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
                //goToGetMsg();
                break;
            case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
                //goToShowMsg((ShowMessageFromWX.Req) req);
                break;
            default:
                break;
        }
    }

    // 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
    @Override
    public void onResp(BaseResp resp) {
        int result = 0;
        Log.e( "onResp", "!!!" + resp.getType());
        switch (resp.errCode) {
            case BaseResp.ErrCode.ERR_OK:

                switch (resp.getType()) {
                    case RETURN_MSG_TYPE_LOGIN:

                        SendAuth.Resp sendResp = (SendAuth.Resp) resp;
                        Log. e("resp.errCode", "!!!" + sendResp.errCode);
                        Log. e("resp.state", "!!!" + sendResp.state);
                        Log. e("resp.token", "!!!" + sendResp.token);

                        //loadingStart(this);
                        secret = getResources().getString(R.string.com_wechat_api_wechat_API_SECRET );
                        appId = WeChatControl.getInstance().getAppKey( this);
                        getAccessToken(sendResp. token);

                        //官方文件寫錯,是token,不是 code
                        // 拿到了微信返回的 code,立马再去请求access_token
                        //String code = ((SendAuth.Resp) resp).code;

                        // 就在这个地方,用网络库什么的或者自己封的网络 api,发请求去咯,注意是 get请求

                        break;

                    case RETURN_MSG_TYPE_SHARE:
                        //"微信分享成功";
                        finish();
                        break;
                }

                break;
            case BaseResp.ErrCode.ERR_USER_CANCEL:
                result = com.example.wechatsdk.party3control.R.string.errcode_cancel;
                break;
            case BaseResp.ErrCode.ERR_AUTH_DENIED:
                result = com.example.wechatsdk.party3control.R.string.errcode_deny;
                break;
            default:
                result = com.example.wechatsdk.party3control.R.string.errcode_unknown;
                break;
        }

    }

    //stpe1
    public void getAccessToken(String toekn) {

        String apiUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appId + "&secret=" + secret + "&code=" + toekn + "&grant_type=authorization_code" ;

        (new JsonGetTask(apiUrl) {
            @Override
            protected void onPostExecute(ArrayList> arrayList) {
                if ((arrayList.size() == 1 && null != arrayList.get(0).get(NETWORK_ERROR ))) {

                    Log.e("getAccessToken", "NETWORK_ERROR");

                } else {

                    //我要做的事情
                    Log.e( "getAccessToken", arrayList.toString());

                    if (!arrayList.get( 0).containsKey( "errcode")) {

                        String refreshToken = (String) arrayList.get(0).get("refresh_token" );
                        String accessToken = (String) arrayList.get(0).get("access_token" );
                        String openid = (String) arrayList.get( 0).get( "openid");
                        getUserInfo(refreshToken, accessToken, openid);

                    } else {
                        Log. e("error", arrayList.toString());
                    }

                }

                //loadingFinish();

            }
        }).execute();
    }


    //stpe2
    public void getUserInfo(String refreshToken, String accessToken, String openid) {

        String apiUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid;

        (new JsonGetTask(apiUrl) {
            @Override
            protected void onPostExecute(ArrayList> arrayList) {
                if ((arrayList.size() == 1 && null != arrayList.get(0).get(NETWORK_ERROR ))) {
                    Log.e("getUserInfo", "NETWORK_ERROR");
                } else {

                    Log.e("getAccessToken", arrayList.toString());

                    if (!arrayList.get( 0).containsKey( "errcode")) {

                        String nickname = (String) arrayList.get(0).get("nickname" );
                        String unionid = (String) arrayList.get( 0).get( "unionid");
                        String headimgurl = (String) arrayList.get(0).get("headimgurl" );

                        Log.e("userinfo", "nickname:"+nickname+"===unionid:"+unionid+"===headimgurl"+headimgurl);

                    } else {
                        Log. e("error", arrayList.toString());
                    }


                }

                //loadingFinish();
                finish();
            }
        }).execute();
    }


}


[android] 解決list item事件,與該list item裡面的"元件" 造成的事件衝突


1.將事件寫在BaseAdapter的 getView裡面
ref:https://tausiq.wordpress.com/2012/08/22/android-listview-example-with-custom-adapter/
    public View getView(int index, View view, final ViewGroup parent) {
     
     view.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //do things here
            }
        });
     
     button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              //do things here
            }
        });
  }

2.設定list item裡面的"元件"
ref:http://stackoverflow.com/questions/6703390/listview-setonitemclicklistener-not-working-by-adding-button

Try seting your buttons(or any other views you want to handle click inside a list item) like this:

android:focusable="false"
android:focusableInTouchMode="false"