1. 程式人生 > >Android呼叫微信登陸、分享、支付(第一版)

Android呼叫微信登陸、分享、支付(第一版)

建議大家看第二版本(最新版):http://blog.csdn.net/lowprofile_coding/article/details/78004224

轉載請註明出處:http://blog.csdn.net/lowprofile_coding/article/details/48086381

前言:用了微信的sdk各種痛苦,感覺比QQ sdk呼叫麻煩多了,回撥過於麻煩,還必須要在指定包名下的actvity進行回撥,所以我在這裡寫一篇部落格,有這個需求的朋友可以借鑑一下,以後自己別的專案有用到也有個找資料的地方.

一微信登陸分三個步驟:

  1)微信授權登陸
  2)。根據授權登陸程式碼獲取該使用者令牌
  3)。根據令牌獲取使用者資料
  4)接收微信的請求及返回值如果你的程式需要接收微信傳送的請求,或者接收發送到微信請求的響應結果,需要下面3步操作:

  一個。在你的包名相應目錄下新建一個wxapi目錄,並在該wxapi目錄下新增一個WXEntryActivity類,該類繼承自Activity(例如應用程式的包名為net.sourceforge.simcpux,

        則新新增的類如下圖所示)

       

        並在清單檔案裡面加上出口屬性,設定為真,例如:

      

      灣實現IWXAPIEventHandler介面,微信傳送的請求將回調到onReq方法,傳送到微信請求的響應結果將回調到onResp方法
      c.在WXEntryActivity中將接收到的intent及實現了IWXAPIEventHandler介面的物件傳遞給IWXAPI介面的handleIntent方法,示例如下圖:

         

    微信官網登陸教程:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=&lang=zh_CN

    微信官網接入指南:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN

二.微信分享直接呼叫sdk就行,回撥跟登陸回撥的類是一樣的,根據BaseResp的型別來區分是登陸還是分享。

三,微信支付

    1)。傳送一個支付請求

    2).接收微信支付的返回值(跟接收微信登陸.分享的返回值類似,我就不寫詳細操作步驟了) 

        官網參考地址如下:https://pay.weixin.qq.com/wiki/doc/api/app.php章= 8_5 

四,貼上程式碼進行講解

    我把微信登陸,分享,支付都封裝到了一個類裡面了,你們可以參考這個類.封裝了6個方法,我對幾個需要的方法介紹一下

    1)構造方法:初始化物件的時候,順便初始化微信物件,把APP_ID註冊到微信

    2)的.login()發起一個登陸的請求在微信登陸監聽Actviity中獲取程式碼

    3).getAccessToken(字串程式碼)當你從監聽活動中獲取了密碼之後就可以通過這個方法獲取微信訪問令牌了

    4).getWeiXinUserInfo(最終WeiXinToken OBJ)獲取微信使用者資訊傳入一個WeiXinToken物件,這個物件是第三步的返回值

    5).share(最終布林friendsCircle,最終VideoB videoB)分享給朋友或者朋友圈如果你有分享圖片,圖片過大的時候一定要經過壓縮,微信官網說明圖片不能大

         於32KB

    6).isWXAppInstalled()檢查微信是否安裝

    7).wxPay(最終BaseActivity活動,字串ORDER_ID,字串payType)微信支付我們專案微信支付的一些引數儲存在伺服器上,所以我這邊還請求了自己的

        伺服器,如果你們是放在本地,直接copy回撥函式裡面的程式碼即可.在微信支付監聽Actviity中獲取支付的狀態碼

        PayReq類屬性對應含義請參考微信官方文件:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_12

public class WeiXinPresenter extends Presenter{
	private static final int THUMB_SIZE = 150;
	public static final int IMAGE_SIZE=32768;//微信分享圖片大小限制
	public static final String APP_ID = "";
	public static final String SECRET="";
	
	private  IWXAPI wxAPI;
	private  IView iView;
	private  IUserController userController;
	
	@Override
	public IView getIView() {
		return iView;
	}
	
	public WeiXinPresenter(Context context){
		if(context!=null && context instanceof  IView)
			iView =(IView) context;
		if(wxAPI==null){
			wxAPI = WXAPIFactory.createWXAPI(context,APP_ID,true);
			wxAPI.registerApp(APP_ID);
		}
		if(null==userController)
			userController=ControllerFactory.getUserController();
	}
	
	/**
	 * 微信登陸(三個步驟)
	 * 1.微信授權登陸
	 * 2.根據授權登陸code 獲取該使用者token
	 * 3.根據token獲取使用者資料
	 * @param activity
	 */
	public void login(){
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = String.valueOf(System.currentTimeMillis());
        wxAPI.sendReq(req);
	}
	
	/**
	 * 獲取微信訪問token
	 */
	public void getAccessToken(String code){
		if(!userController.isLogin()){//沒有登陸的情況用第三方登陸
			userController.getWeiXinAccessToken(APP_ID,SECRET,code,new RequestDataCallback<WeiXinToken>(){
				@Override
				public void dataCallback(WeiXinToken obj){
					if(obj!=null){
						if(obj.getErrcode()==0){
//							if(MLog.debug){
//								iView.showToast("授權使用者唯一標識:"+obj.getOpenid());
//							}
							getWeiXinUserInfo(obj);
						}else{
							iView.showToast(obj.getErrmsg());
						}
					}else{
						
					}
				}
			});
		}else{//使用者已登陸
			
		}
	}
	
	/**
	 * 獲取微信使用者資訊
	 */
	private void getWeiXinUserInfo(final WeiXinToken obj){
		userController.getWeiXinUserInfo(obj.getAccess_token(), obj.getOpenid(), new RequestDataCallback<RegisterB>() {
			@Override
			public void dataCallback(RegisterB registerB){
				if(registerB!=null&&obj!=null){
					registerB.setAccess_token(obj.getAccess_token());
					registerB.setToken_expire_at(obj.getExpires_in());
					if(registerB.getErrcode()==0){
						registerB.setThird_type_name(Constants.WEI_XIN);
						thirdLogin(registerB);
					}else{
						iView.showToast(registerB.getErrmsg());
					}
				}
			}
		});
	}
	
	/**
	 * 呼叫我們自己的伺服器進行登入
	 * @param registerB
	 */
	private void thirdLogin(RegisterB registerB){
		userController.thirdAuth(registerB,new RequestDataCallback<UserP>(){
			@Override
			public void dataCallback(UserP user){
				if(checkCallbackData(user, true)){
					if(user.getError()==user.ErrorNone){
						iView.showToast(R.string.login_success);
						getAppController().sendLoginChangeIntent();
						userController.saveLoginUser(user,FileUtil.getFilePath());
						((ILoginView)iView).toMain();
					}else{
						iView.showToast(user.getError_reason());
					}
				}
			}
		});
	}
	
	/**
	 * 微信分享
	 * @param friendsCircle  是否分享到朋友圈
	 */
	public void share(final boolean friendsCircle,final  VideoB videoB){
		new LoadPicThread(videoB.getCover_url(),new Handler(){
			@Override
			public void handleMessage(Message msg) {
				byte[] bytes=(byte[]) msg.obj;
				if(bytes.length>IMAGE_SIZE){
					iView.showToast(R.string.image_no_big);
					return;
				}
				WXVideoObject videoObject = new WXVideoObject();// 視訊型別
				videoObject.videoUrl = videoB.getShare_url() + Constants.WEI_XIN + "&share_from="+com.kaka.utils.Constants.ANDROID;// 視訊播放url
				WXMediaMessage wxMessage = new WXMediaMessage(videoObject);
				wxMessage.title = videoB.getContent();
				wxMessage.thumbData = bytes;
				SendMessageToWX.Req req = new SendMessageToWX.Req();
				//transaction欄位用於唯一標識一個請求
				req.transaction = String.valueOf(videoB.getId() + System.currentTimeMillis());
				req.message = wxMessage;
				req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
				wxAPI.sendReq(req);
			}
		}).start();
	}
	
	/**
	 * 分享邀請有獎
	 * @param userP  使用者資訊
	 */
	public void shareInvitationPrize(UserP userP,Context context,boolean friendsCircle){
		WXWebpageObject webpage = new WXWebpageObject();
		webpage.webpageUrl = userP.getInvite_url();
		WXMediaMessage msg = new WXMediaMessage(webpage);
		if(friendsCircle){
			msg.title = context.getResources().getString(R.string.share_invitation_prize_content);
		}else{
			msg.description = context.getResources().getString(R.string.share_invitation_prize_content);
		}
		
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inSampleSize=2;
		Bitmap thumb = BitmapFactory.decodeResource(context.getResources(), R.drawable.send_cash_register,options);
		msg.thumbData = bmpToByteArray(thumb);
		
		SendMessageToWX.Req req = new SendMessageToWX.Req();
		req.transaction = String.valueOf(userP.getId() + System.currentTimeMillis()); // transaction欄位用於唯一標識一個請求
		req.message = msg;
		req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
		// 呼叫api介面傳送資料到微信
		wxAPI.sendReq(req);
	}
	
	private class LoadPicThread extends Thread{
		private String url;
		private Handler handler;
		public LoadPicThread(String url,Handler handler){
			this.url=url;
			this.handler=handler;
		}
		
		@Override
		public void run(){
			try {
				URL picurl = new URL(url); 
				HttpURLConnection conn = (HttpURLConnection)picurl.openConnection(); // 獲得連線 
				conn.setConnectTimeout(6000);//設定超時 
				conn.setDoInput(true); 
				conn.setUseCaches(false);//不快取 
				conn.connect();
				
				Message message=handler.obtainMessage();
				
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize=2;
				message.obj=bmpToByteArray(BitmapFactory.decodeStream(conn.getInputStream(),null,options));
				message.sendToTarget();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	//檢查微信是否安裝
	public boolean isWXAppInstalled(){
		return wxAPI.isWXAppInstalled();
	}
	
	
	public void wxPay(final BaseActivity activity,String order_id,String payType){
		activity.showProgress("");
		ControllerFactory.getWalletsController().getPayments(order_id, payType, new RequestDataCallback<PaymentsP>() {
			@Override
			public void dataCallback(PaymentsP obj) {
				if(checkCallbackData(obj, true)){
					if(obj.getError()==obj.ErrorNone){
						PayReq req = new PayReq();//待修改
						
						req.appId = obj.getAppid();
//						init(obj.getAppid());
						
						req.nonceStr=obj.getNoncestr();
						req.packageValue=obj.getPackage_value();
						req.sign=obj.getSign();
						req.partnerId=obj.getPartnerid();
						req.prepayId=obj.getPrepayid();
						req.timeStamp=obj.getTimestamp();
						
						wxAPI.registerApp(obj.getAppid());
						wxAPI.sendReq(req);
						
						MLog.i("ansen", "開始進行微信支付..");
//						iView.showToast("開始進行微信支付..");
					}
				}else{
					iView.showToast(obj.getError_reason());
				}
				activity.hideProgress();
			}
		});
	}


強調一點,一定要注意接收微信的請求及返回值的包名跟類名,包名是應用程式的包名+“。wxapi”類名必須是微信指定的類名並且這兩個Activity一定要在AndroidManifest.xml中註冊,上傳一張是我做的app中包名跟類名的截圖

如何在活動中呼叫微信登陸

1)登陸廣播監聽內部類如果接收到了廣播就去獲取微信令牌

	private class WXEntryReceiver extends BroadcastReceiver {
		@Override
		public void onReceive(Context context, Intent intent){
			if(intent.getAction().equals(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN)){
				MLog.i("WXEntryReceiver","接收微信登陸廣播");
				int errCode = intent.getExtras().getInt("errCode");
				if(errCode==BaseResp.ErrCode.ERR_USER_CANCEL||errCode==BaseResp.ErrCode.ERR_AUTH_DENIED){
					requestDataFinish();
				}else{
			        String code = intent.getExtras().getString("code");
			        xinTestPresenter.getAccessToken(code);
				}
			}
		}
	}
2)。定義成員變數
    private WXEntryReceiver wxEntryReceiver = NULL;

3)。在OnCreate中中註冊廣播

    //微信登陸廣播
    wxEntryReceiver= new WXEntryReceiver();
    LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
    IntentFilter filter = new IntentFilter(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN);
    lbm.registerReceiver(wxEntryReceiver,filter);

4)呼叫微信登陸

    WeiXinPresenter xinTestPresenter =new WeiXinPresenter(this);
    xinTestPresenter.login();

在Activity中呼叫微信分享跟呼叫微信支付的程式碼我就不貼出來了,我這篇部落格只是給大家一個參考的地方,遇到問題還是建議第一時間看官方文件.
說說我在做微信登陸碰到的問題

1.微信登陸,分享,支付回撥的活動包名跟類名一定要嚴格按照要求去寫

2.接收回調的是活動一定要在AndroidManifest.xml中中註冊

3.WeiXinPresenter中有兩個常量APP_ID跟SECRET要去微信申請的時候才有的。你們複製程式碼的時候要給這兩個常量賦值

4.可能訪問網路神馬的還需要一些許可權記得在AndroidManifest.xml中新增許可權

5.呼叫微信的登陸,分享,支付你的安裝包一定要有簽名,簽名信息一定要跟你在微信官網上申請時簽名信息一致

6.微信沒有客服支援.....如果出了問題看官方的演示或者官方API

7.微信SDK經常升級,如果你開發的時候有最新的就用最新的吧.....

說了那麼多,感覺說了一大堆廢話......希望能幫到大家....有神馬問題可以給我留言....
我在csdn上上傳了一個微信sdk的jar包,有需要的可以去下載

推薦一個Android開發者公眾號,每週都有原創乾貨



相關推薦

Android呼叫登陸分享支付第一版

建議大家看第二版本(最新版):http://blog.csdn.net/lowprofile_coding/article/details/78004224轉載請註明出處:http://blog.csdn.net/lowprofile_coding/article/detai

Android呼叫掃一掃和支付寶掃一掃

微信在自己的應用中開啟微信掃一掃程式碼:private void toWeChatScan() { try { //利用Intent開啟微信 Uri uri =

第三方接登陸分享支付的一些坑1

最近接了公司遺漏專案,另一個安卓走了,接過他留下的bug,有點辛苦主要就在這裡講講接微信的一些問題,花費了我好久,主要出現在登陸部分和支付返回的JSON資料解析,以及分享純圖片時的一些問題。那首先就是去微信公眾平臺註冊,目前好像只支援企業註冊,而且需要支付300元的費用,有點

Android呼叫原生分享介面,進入微分享介面返回不了!

今天測試員發現一個bug,分享停在微信介面,返回不了了,我擦!我就慢慢排除bug······首先圖片符合微信分享限制的大public static final int THUMB_LENGTH_L

網頁授權-公眾號支付獲取openid用戶息等

blog red code rect ref true 說明 oauth2 具體細節 名詞解釋: openid 用戶唯一標識,請註意,在未關註公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID 業務功能描述:實現H

呼叫JSSDK實現分享功能

最近遇到一個專案是基於微擎框架做一個分享功能的,微擎本身是自帶分享功能的,只是這次想要實現自定義分享內容,故進行了以下程式碼處理 * $_W[‘account’][‘jssdkconfig’]是微擎封裝好的jssdk簽名包的內容 * php頁面程式碼 <?php if

公眾號開發 自定義分享 從前臺到Java後臺 呼叫JS介面分享朋友圈

20180811寫在前面的話 有很多人遇到問題之後問我,結果大多數是因為配置問題,所以請詳細閱讀前面的配置步驟。 20181016注意事項 文中原始碼下載地址 上面這個地址是我當時做的整個專案的原始碼,包含了一些業務在裡面,用的是SSM框架,現在寫了一

Unity使用Share-SDK接登入和分享的總結Android

對於一個工作才不到一年的新手來說,這是我做的第一個專案,收尾階段 分給我了一個接微信登入以及分享的任務。 前期,經過了痛苦的搜尋與探索過程 ,在此就不寫了  如果你也是新手  可以直接按我的文章來寫  保證輕鬆接入,為大家省去大把的時間喲; unity版本:我用的是5.5.

關於呼叫朋友圈分享及引數

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> wx.config({ debug: false, appId: '{$

Android呼叫掃一掃

在自己的應用中開啟微信掃一掃程式碼: private void toWeChatScan() { try { //利用Intent開啟微信

android-----------實現登入和分享功能。

1.通過微信官網獲得APPID和.jks檔案。 (.jks檔案的獲得是通過AS中的Build-Generate Signed APK-如果已有.jks就選擇已有的路徑,對應好兩次的密碼。 ) 2.導依賴 compile 'com.tencent.mm.opensdk:wec

小程式開發基礎篇之請求上傳下載

針對前幾篇的基本的瞭解,然後我們首先要先學習和了解它的基本語法,我主要從API官網上學習,然後總結在這篇部落格中。供自己後期檢視。以備不時之需。因為自己也是初學者,很多的都是按照API來學習講解。 按照API的順序,我先學習網路的模組 一、請求:wx.request(OB

在IOS或Android區分的onResp(分享或登入)回撥的型別,判定當前操作是否成功

大家接過微信開放平臺的SDK都應該知道,如果需要向微信傳送登入或分享請求時,需要構造一個訊息結構體給微信傳送過去,登入的結構體型別是SendAuthReq,分享的訊息結構體是SendMessageToWXReq。 同樣地,在操作完後微信拉起我們自己的應用時也會

Android 呼叫Api

最近一專案需要新增微信的分享:朋友、朋友圈。 原本以為挺簡單的一事,無非就是去官網下個Demo,整合到自己專案中,可以分分鐘搞定,結果這幫寫文件的坑爹玩意,愣是浪費了我N多時間,好了吐槽完畢,接下來分享下此次呼叫微信中遇到的問題和解決方法: 首先第一個問題:死活調不出微

小程式開發技巧總結 -- 檔案的選取移動上傳和下載

微信小程式開發技巧總結(二) -- 檔案的選取、移動、上傳和下載 1.不同型別檔案的選取 1.1 常用的圖片 視訊 對於大部分開發者來說,需要上傳的檔案形式主要為圖片,微信為此提供了介面。 wx.chooseImage({ count: 1, sizeType: ['original

小程式開發常用技巧7——實現一個類似於Android toast效果動畫

很多時候,我們在小程式中使用wx.showToast(),發現樣式不是很好看,那麼我們能不能做一個跟原生APP類似的toast呢?答案是肯定的。今天就利用微信小程式的動畫wx.createAnimation()實現一個簡單的類似原生APP的toast提示。 先

小程序的小問題2

item 但是 一個 我們 nbsp 新的 wid 自動填充 float 1、在小程序中,有時需要用到背景圖片,但是如果使用background-image的話,就無法控制圖片的大小,background-image一般用於將圖片壓縮為1像素的背景圖片,然後自動填充鋪滿。使

小程序組件化

== 什麽 解決方案 chan json 特性 支持 減少 ble 小程序對組件化的“支持”情況 微信小程序(以下簡稱“小程序”,版本)雖然默認定義了很多有用的組件,但是在開發小程序過程中,往往需要自定義業務組件。而小程序開發者文檔中卻未對自定義組件給出很好的解決方案或示例

小程序-卡券開發前端

open openca ppi script 開發者工具 程序 -1 http 緩存 剛完成一個微信小程序卡券開發的項目。下面記錄開發前,自己困惑的幾個問題。 因為我只負責了前端。所以下面主要是前端的工作。 項目概述:按照設計圖開發好首頁上的優惠券列表,點擊某個優惠券,輸入

小程序學習打卡2

lin color navigator 微信 navig 實現 url 底部導航 inf 一、wxml文件:類似於html,<標簽名 屬性=“屬性值”></標簽名> 屬性值可為: 類 class=“info”        id id=“zzz”