廣告

2016年9月25日 星期日

上線前須做的事

公司內部某單位不知道 何謂 "測試環境是啥"
特地說明==


以軟工上線流程來說會有三個階段

1. [測試環境]的上線及測試
    .此階段的所有資料都是假的.  
    .其目的在於資料欄位的正確性

2. 測試[正式環境]
    .此階段的所有資料都是真的.
    .此階段目的在於測試各家廠商
     的正式環境是否正常運行.因為我們在#1不會知道他們的正式
     環境是否正常
    .若此步驟的環節有錯,我們就不能進入第三步驟.  

3. [正式環境]上線
    .本系統與各家廠商的系統正式環境
     都正常運行才會到這步驟
   
所以如果我們直接就從#1進入#3是無法確定
我們自己的系統與各家廠商的系統的正式環境是正常的,
此時勢必會造成更多問題需要處理(因為已經有外部的使用者在使用)

2016年9月22日 星期四

[java] dynamic key-value set from config.properties


config.properties
terminalID =abStoreA1: 11199942, abStoreWeekend: 11199943, abStoreEP: 11199944


LoadPropertyUtil.java
public class LoadPropertyUtil {

    private static Map mapTerminalID = new HashMap();

    public final static String merchantID = PropertyLoader.getInstance().getValue(Constants.MERCHANT_ID_KEY);

    public final static String authMessageType = PropertyLoader.getInstance().getValue(Constants.AUTH_MESSAGE_TYPE_KEY);
    public final static String authProcessingCode = PropertyLoader.getInstance().getValue(Constants.AUTH_PROCESSING_CODE_KEY);
    public final static String authPosEntryMode = PropertyLoader.getInstance().getValue(Constants.AUTH_POSENTRYMODE_KEY);

    public final static String inquireAuthMessageType = PropertyLoader.getInstance().getValue(Constants.INQUIRE_AUTH_MESSAGE_TYPE_KEY);
    public final static String inquireAuthProcessingCode = PropertyLoader.getInstance().getValue(Constants.INQUIRE_AUTH_PROCESSING_CODE_KEY);
    public final static String inquireAuthPosEntryMode = PropertyLoader.getInstance().getValue(Constants.INQUIRE_AUTH_POSENTRYMODE_KEY);

    static {
      /**
        * split the tid property "srcProject1:TID1,srcProject2:TID2,srcProject3:TID3"
        */
      String[] tIDs = PropertyLoader.getInstance().getValue(Constants.TERMINAlID_KEY).split(",");
      for (String string : tIDs) {
        String[] pair = string.split(":");
        if(pair.length == 2)
            mapTerminalID.put(pair[0].trim(), pair[1].trim());
      }
    }

    public static String getTerminalID(String srcProject) {
      return mapTerminalID.get(srcProject);
    }

    public static boolean containsSrcProjectName(String srcProject) {
      if (srcProject!=null && srcProject.length()>0) {
        return mapTerminalID.containsKey(srcProject);
      }
      return false;
    }
}



PropertyLoader.java
public class PropertyLoader {
  private static PropertyLoader instance = null;
  private Properties props = null;

  /* Singleton Design Pattern */
  private PropertyLoader() {
      try {
        props = new Properties();
        props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(Constants.PROPS_FILE_NAME));
      } catch (IOException e) {
        e.printStackTrace();
      }
  }

  public static synchronized PropertyLoader getInstance() {
      if (instance == null)
        instance = new PropertyLoader();
      return instance;
  }

  public String getValue(String propKey) {
      return this.props.getProperty(propKey);
  }
}



using example
LoadPropertyUtil.getTerminalID("abStoreA1")

[java] Extract digits from a string in Java


A:
str.replaceAll("[^0-9]", "")

B:
str.replaceAll("\\D+","")

C:
public static String stripNonDigits(
  final CharSequence input /* inspired by seh's comment */){
  final StringBuilder sb = new StringBuilder(
  input.length() /* also inspired by seh's comment */);
  for(int i = 0; i < input.length(); i++){
  final char c = input.charAt(i);
  if(c > 47 && c < 58){
  sb.append(c);
  }
  }
  return sb.toString();}


http://stackoverflow.com/questions/4030928/extract-digits-from-a-string-in-java

[java] ftp upload fail (enterLocalPassiveMode)


ftpClient .connect (Constants . FTP_URL) ;
ftpClient .login (Constants . FTP_ID, Constants . FTP_PWD) ;
ftpClient .enterLocalPassiveMode ();

[java] multipart/form-data POST request using Java  | mailgun with attachment


        CredentialsProvider credsProvider = new BasicCredentialsProvider();

        credsProvider.setCredentials(

                new AuthScope(HOST_NAME, PORT),

                new UsernamePasswordCredentials(USER_NAME, TOKEN));

        CloseableHttpClient httpclient = HttpClients.custom()

                .setDefaultCredentialsProvider(credsProvider)

                .build();

        try {

            HttpPost httpPost = new HttpPost(BASE_URL + EMAIL_API_NAME);


            MultipartEntityBuilder builder = MultipartEntityBuilder.create();


            builder.addBinaryBody("attachment", new File("D:/opt/test.pdf"), ContentType.APPLICATION_OCTET_STREAM, "file.ext");

            builder.addTextBody("from", FROM_ADDRESS, ContentType.APPLICATION_JSON);

            builder.addTextBody("to", toEmail, ContentType.APPLICATION_JSON);

            builder.addTextBody("bcc", bcc, ContentType.APPLICATION_JSON);

            builder.addTextBody("subject", subject, ContentType.APPLICATION_JSON);

            builder.addTextBody("html", this.loadTemplate(template, values), ContentType.APPLICATION_JSON);

            HttpEntity multipart = builder.build();

            httpPost.setEntity(multipart);

            CloseableHttpResponse response2 = httpclient.execute(httpPost);

            log.info(response2.toString());


            try {

                System.out.println(response2.getStatusLine());

                HttpEntity entity2 = response2.getEntity();

                // do something useful with the response body

                // and ensure it is fully consumed

                EntityUtils.consume(entity2);

            } finally {

                response2.close();

            }

        } finally {

            httpclient.close();

        }


ref:http://stackoverflow.com/questions/1378920/how-can-i-make-a-multipart-form-data-post-request-using-java

[java] isKeysExistInMap (keys ,map )



package test;

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

public class testMapContainMultiKey {

       public static void main( String[] args ) {
             // TODO Auto-generated method stub

             ArrayList< String> keys = new ArrayList< String> ();
            keys .add ("a" );
            keys .add ("b" );

             HashMap< String, String > map = new HashMap<> ();
            map .put ("a" , "a" );
            map .put ("c" , "b" );

             System. out .println ( isKeysExistInMap (keys ,map ) );


       }

       public static boolean  isKeysExistInMap( ArrayList< String> keys , HashMap  map ) {
             boolean result = true;
             for (String key : keys) {
                 result = map. containsKey (key );
                 if (result == false ) {
                     return result;
                 }
             }
             return result;
       }

}


2016年8月10日 星期三

a bug in Chrome's live-edit CSS/JS. Notice how the number changes on each request.

Error msg:
Error shows “Failed to get text for stylesheet (#): No style sheet with given id found”

Ans:

closed all the files in the 'source' tab.


2016年8月7日 星期日

[git]Untrack files from git

This will tell git you want to start ignoring the changes to the file
git update-index --assume-unchanged path/to/file

When you want to start keeping track again
git update-index --no-assume-unchanged path/to/file

usage occasion : put some file in remote once and not track it anymore

                 ex:local config

2016年7月13日 星期三

2016年6月23日 星期四

Hibernate Eager vs Lazy Fetch Type


  @OneToOne(fetch=FetchType.EAGER) //LAZY
  @JoinColumn(name="user_profile_id")
  private Profile getUserProfile()
  {
   return userProfile;
  }

 FetchType.LAZY = Doesn’t load the relationships 
 unless explicitly “asked for” via getter
 FetchType.EAGER = Loads ALL relationships

ref:
https://m.oschina.net/blog/327056
https://howtoprogramwithjava.com/hibernate-eager-vs-lazy-fetch-type/

2016年6月8日 星期三

Hibernate paging get error result if row have same value


Query queryHot = session.createQuery(
   "from HotPost ORDER BY popularity DESC");

queryHot.setFirstResult((page - 1) * pageSize);
queryHot.setMaxResults(pageSize);

solve:
Query queryHot = session.createQuery(
   "from HotPost ORDER BY popularity DESC,id");
==================================
Before:
id   popularity 
1     9   |
2     8   |  page 1
3     8   |

5     8   |
6     7   |  page 2
7     5   |

AFTER:
id   popularity 
1     9  |
2     8  |  page 1
3     8  |

4     8  |
5     7  |  page 2
6     5  |


2016年5月19日 星期四

Hibernate  one-to-one mapping cautions


正確用法
@OneToOne(mappedBy = "post")
@JsonView(View.Detail.class)
private HotPost hotPost;

一開始犯傻
@OneToOne(mappedBy = "post")
@JsonView(View.Detail.class)
Set hotpost = new HashSet<>(0);
CautionsCautionsCautions
log只會說:Unknown mappedBy in: com.ws.pojo.Post.hotPost, referenced property unknown: java.util.Set.post


but @OneToMany
remember to use Set


ref:




Hibernate batch process


 //in pojo (java bean)
      @BatchSize(size=5)
------------------------------------------------
      public void insertOldPost2HotPost() throws Exception{
       
       Session session = sessionFactory.getCurrentSession();

        @SuppressWarnings("unchecked")
        List posts = session.createQuery("from Post ").list();
        int itCount=0;
        for(Iterator it = posts.iterator(); it.hasNext(); ) {

            itCount++;

            Post post = (Post) it.next();

            HotPost hotPost = new HotPost(post);
            session.saveOrUpdate(hotPost);

            if (itCount % 5 == 0) {
            
                session.flush();
                session.clear();
            }
        }
    }


ref:


2016年5月10日 星期二

Spring MVC @JsonView使用详解


     public class View {
      interface Summary {}
      interface SummaryWithDetail extends Summary{}
    }
    -----------------------------------
    public class User {
      @JsonView(View.Summary.class)
      private Long id;
      @JsonView(View.SummaryWithDetail.class)
      private String firstname;
    }
    -----------------------------------
    @RequestMapping("/user")[
    @JsonView(View.Summary.class)
    //or @JsonView(View.SummaryWithDetail.class)
    public List getUsers(){
     return userService.listUsers();
    }
    -----------------------------------
    result of @JsonView(View.Summary.class)
    [
     {
        "id": 70,
     }
    ]

    result of @JsonView(View.SummaryWithDetail.class)
    [
     {
        "id": 70,
        "firstname": 222
     }
    ]


2016年3月28日 星期一

Hibernate openSession() vs getCurrentSession()


      SessionFactory.openSession():
      always opens a new session that you have to
      close once you are done with the operations.
     
      SessionFactory.getCurrentSession():
      returns a session bound to a context - you don't need to close this. 
     
      should always use "one session per request" or "one session per transaction"
      In one application, if the DAO layer, using Spring hibernate,
      control the life cycle via Spring session to ,

      First choice  getCurrentSession ().

2016年3月17日 星期四

Usage of @JsonView (annotation of spring)


    public class View {
      interface Summary {}
      interface SummaryWithDetail extends Summary{}
    }
    -----------------------------------
    public class User { 
      @JsonView(View.Summary.class) 
      private Long id; 
      @JsonView(View.SummaryWithDetail.class) 
      private String firstname; 
    }
    -----------------------------------
    @RequestMapping("/user")
    @JsonView(View.Summary.class) 
    //or @JsonView(View.SummaryWithDetail.class) 
    public List getUsers(){
     return userService.listUsers();
    }
    -----------------------------------
    result of @JsonView(View.Summary.class)
    [
     {
        "id": 70,
     }
    ]
    
    result of @JsonView(View.SummaryWithDetail.class)
    [
     {
        "id": 70,
        "firstname": 222
     }
    ]

ref:
http://www.jianshu.com/p/633d83dd303b#

2016年3月10日 星期四

Apache_httpd_to_Tomcat-Mod_Proxy_Setup.txt | 轉址


sudo vi /opt/lampp/etc/httpd.conf

Make sure the following are uncommented:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Add these:
ProxyPass         /eInvoiceLocate http://localhost:8080/eInvoiceLocate
ProxyPassReverse  /eInvoiceLocate http://localhost:8080/eInvoiceLocate

Reload Apache conf
# cd /opt/lampp/bin
# sudo ./apachectl -k graceful


2016年2月25日 星期四

apache xmlhttprequest cannot load origin is not allowed by access-control-allow-origin |ajax 跨網頁存取圖片遇到cors

修改這個檔:
/opt/lampp/etc/httpd.conf

在 <Directory "/opt/lampp/htdocs"> 區段加入:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "x-requested-with"
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"

重起
sudo /opt/lampp/bin/apachectl -k graceful

關於cors

Android Receive SMS Tutorial | android 取得sms內容


testReadSms.java
public class testReadSms extends BodyFragment{

    private SmsBroadcastReceiver receiver = new SmsBroadcastReceiver(new SmsBroadcastReceiver.UpdateSmsEvent() {
        @Override
        public void updateSms(String sms) {
            newMsg.setText(sms);
        }
    });

    private ArrayList smsMessagesList = new ArrayList();
    private ListView smsListView;
    private ArrayAdapter arrayAdapter;
    private TextView newMsg;

    @Override
    public void onStart() {
        super.onStart();

        //regist sms receiver
        Log. e("registerReceiver", "registerReceiver");
        receiver.registerSmsReceiver(activity);
    }

    @Override
    protected View fragmentLayout(LayoutInflater inflater, ViewGroup container) {
        return inflater.inflate(R.layout.test_body_sms, container, false);
    }

    @Override
    protected void setupComponents(View fragmentView) {
        newMsg = (TextView) fragmentView.findViewById(R.id. new_msg);
        smsListView = (ListView) fragmentView.findViewById(R.id. SMSList);
        arrayAdapter = new ArrayAdapter( activity, android.R.layout.simple_list_item_1 , smsMessagesList);
        smsListView.setAdapter(arrayAdapter);
        smsListView.setOnItemClickListener( this);

        refreshSmsInbox();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //activity.unregisterReceiver(receiver);
    }

    public void refreshSmsInbox() {
        ContentResolver contentResolver = activity.getContentResolver();
        Cursor smsInboxCursor = contentResolver.query(Uri.parse("content://sms/inbox"), null, null , null, null);
        int indexBody = smsInboxCursor.getColumnIndex( "body");
        int indexAddress = smsInboxCursor.getColumnIndex( "address");
        if (indexBody < 0 || !smsInboxCursor.moveToFirst()) return;
        arrayAdapter.clear();
        do {
            String str = "SMS From: " + smsInboxCursor.getString(indexAddress) +
                    "\n" + smsInboxCursor.getString(indexBody) + "\n";
            arrayAdapter.add(str);
        } while (smsInboxCursor.moveToNext());
    }

    public void updateList(final String smsMessage) {
        arrayAdapter.insert(smsMessage, 0);
        arrayAdapter.notifyDataSetChanged();
    }

    public void updateNewMsg(final String msg) {
        newMsg.setText(msg);
    }

}


SmsBroadcastReceiver.java
public class SmsBroadcastReceiver extends BroadcastReceiver {

    public static final String SMS_BUNDLE = "pdus";
    public Activity activity;
    public UpdateSmsEvent updateSmsEvent;


    public interface UpdateSmsEvent{
        void updateSms(String sms);
    }

    public SmsBroadcastReceiver(UpdateSmsEvent inte){
        updateSmsEvent = inte;
    }


    public void onReceive(Context context, Intent intent) {
        Bundle intentExtras = intent.getExtras();
        if (intentExtras != null) {
            Object[] sms = (Object[]) intentExtras.get(SMS_BUNDLE);
            String smsMessageStr = "";
            String smsMessageBody= "";
            for (int i = 0; i < sms. length; ++i) {
                SmsMessage smsMessage = SmsMessage. createFromPdu((byte[]) sms[i]);

                String smsBody = smsMessage.getMessageBody().toString();
                String address = smsMessage.getOriginatingAddress();

                //smsMessage.getTimestampMillis() is current time
                smsMessageStr += "SMS From: " + address + "\n" ;
                smsMessageStr += smsBody + "\n" ;
                smsMessageBody = smsMessage.getMessageBody().toString();
            }
            Toast.makeText (context, smsMessageBody, Toast.LENGTH_SHORT).show();
            smsMessageBody = smsMessageBody.replaceAll("\\D+","" );
            //this will update the UI with message
            updateSmsEvent.updateSms(smsMessageBody);
            activity.unregisterReceiver(this);
        }
    }

    public void registerSmsReceiver(Activity activity){
        this.activity = activity;
        IntentFilter filter = new IntentFilter();
        filter.setPriority(999 );
        filter.addAction("android.provider.Telephony.SMS_RECEIVED");
        activity.registerReceiver(this, filter);
    }
}



main ref:

ref:

[android] sms emulator control in Android Studio | android模擬器 模擬簡訊寄送

Tools->Android->Android Device Monitor-> Click on the emulator name in devicess-> Emulator Controls

[android] phone call using intent in android


String phone = location.getPhoneNumber();
//Intent intent = new Intent(Intent.ACTION_DIAL, Uri.fromParts("tel", phone, null));
//need click call
Intent intent = new Intent(Intent. ACTION_CALL, Uri.fromParts( "tel", phone, null ));
//call directly
activity.startActivity(intent);


add permission in AndroidManifest.xml


[android] Send Email Intent

http://stackoverflow.com/questions/8701634/send-email-intent
Intent emailIntent = new Intent(Intent. ACTION_SENDTO, Uri.fromParts(
        "mailto", "lewisli.acer@gmail.com", null));
emailIntent.putExtra(Intent.EXTRA_EMAIL , "lewisli.acer@gmail.com");
emailIntent.putExtra(Intent.EXTRA_SUBJECT , "Pet");
emailIntent.putExtra(Intent.EXTRA_TEXT , "this is error page");
startActivity(Intent.createChooser(emailIntent, "Report error"));





but can't get result event
http://stackoverflow.com/questions/3778048/how-can-we-use-startactivityforresult-for-email-intent

You can't, this is not part of the API. It returns once you have pressed send button even if it is not sent

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"