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(); } }
廣告
2016年1月7日 星期四
[android] 微信接入(登入,發動態) | weChat auth login,share
[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"
2015年12月16日 星期三
html5 data-attribute
以往JavaScript和CSS都要透過id或是class和HTML產生關聯, 造成典型的問題就是一個CSS的style用不到了, 但是怕刪除class讓JS失效. 目前最新的解法是:JavaScript少class。 改用 HTML5 data- attributes 來當JS和HTML之間的橋梁 Twitter Bootstrap: css => class="nav nav-tabs" js =>
優點:
1.可以定義一些不需要顯示在前端的資訊(ex:id)
2.分離js , html ,css
ref:
https://www.christianheilmann.com/2012/10/10/data-attributes-rock-as-both-css-and-javascript-know-them/
http://minipai.tumblr.com/post/34152230626/%E6%9C%AA%E4%BE%86%E5%8F%AF%E8%83%BD%E6%9C%83%E7%94%A8%E5%89%8D%E7%AB%AF%E5%88%86%E9%9B%A2%E8%A1%93
http://sincode.blogspot.tw/2014/09/html5-data-data.html
https://hacks.mozilla.org/2012/10/using-data-attributes-in-javascript-and-css/
2015年11月19日 星期四
[android] Use "meta-data" from AndroidManifest.xml
想說第三方的app key參數都放在<meta-data >裡
但如果value直過大時(46464646464123),
ex:
<meta-data
android :name="API_KEY"
android :value="46464646464123 " />
此時直接從程式裡引用此值會出錯.
解法:
<meta-data android:name="zoo" android:value="@string/kangaroo" />
benefits:
2015年10月24日 星期六
Open new tab without popup blocker after ajax call on user click | 用ajax開新tab時,避免瀏覽器會詢問是否可開
是這樣的,我網頁上有個按鈕,點擊時會去
用jquery的ajax http get 去跟後端取資料,
並且取得後會開啟一個新分頁.
此時有個現象,
當ajax http get裡面的參數"async"設為true,
開新分頁時,browser 會問你可不可以跳視窗.
當ajax http get裡面的參數"async"設為false,
開新分頁時,browser 就不會問,而是直接地就
開啟新分頁.
PS:開啟新分頁是用window.open(url, '_blank')
以下為網友"Kenqr"的回答:
ref:http://stackoverflow.com/questions/18885676/open-new-tab-without-popup-blocker-after-ajax-call-on-user-click
用jquery的ajax http get 去跟後端取資料,
並且取得後會開啟一個新分頁.
此時有個現象,
當ajax http get裡面的參數"async"設為true,
開新分頁時,browser 會問你可不可以跳視窗.
當ajax http get裡面的參數"async"設為false,
開新分頁時,browser 就不會問,而是直接地就
開啟新分頁.
PS:開啟新分頁是用window.open(url, '_blank')
以下為網友"Kenqr"的回答:
非由使用者的操作直接引發的開新視窗 瀏覽器會詢問,==================================
點按鈕後直接開新視窗會被視為是使用者的操作引發的,
但async true時會在另一個thread執行,就不會被當成是使用者的操作,
可以改成點擊後直接開新分頁,新分頁裡再用ajax讀資料,
或是先開新分頁,原分頁讀到資料後再傳給新分頁應該也行
ref:http://stackoverflow.com/questions/18885676/open-new-tab-without-popup-blocker-after-ajax-call-on-user-click
2015年10月23日 星期五
Change the URI (URL) for a remote Git repository | 修改git remote的網址
有兩個方法:
1. edit .git/config and change the URLs there.
2. git remote set-url origin git://new.url.here
================================
show current remote url
1. edit .git/config and change the URLs there.
2. git remote set-url origin git://new.url.here
================================
show current remote url
git config --get remote.origin.url
2015年10月15日 星期四
AdBlock plus hids elements with ids or class with the word “ad”
chrome如果有裝adBlock的話在,html中
class的命名盡量不要出現以下相關字眼.
=> *ad*,*banner*
來源(https://easylist-downloads.adblockplus.org/easylist.txt)
訂閱:
文章 (Atom)