Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android調用微信登陸、分享、支付,

Android調用微信登陸、分享、支付,

編輯:關於android開發

Android調用微信登陸、分享、支付,


前言:用了微信sdk各種痛苦,感覺比qq sdk調用麻煩多了,回調過於麻煩,還必須要在指定包名下的actvity進行回調,所以我在這裡寫一篇博客,有這個需求的朋友可以借鑒一下,以後自己別的項目有用到也有個找資料的地方.

 

一.微信登陸分三個步驟:

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

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

        則新添加的類如下圖所示)

       

        並在manifest文件裡面加上exported屬性,設置為true,例如:

      

      b. 實現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?chapter=8_5 

 

四.貼上代碼進行講解

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

    1).構造方法:初始化對象的時候,順便初始化微信對象,把app_id注冊到微信

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

    3).getAccessToken(String code)  當你從監聽Activity中獲取了code之後就可以通過這個方法獲取微信訪問token了

    4).getWeiXinUserInfo(final WeiXinToken obj)  獲取微信用戶信息   傳入一個WeiXinToken對象,這個對象是第三步的返回值

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

         於32kb

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

    7).wxPay(final BaseActivity activity,String order_id,String payType)  微信支付   我們項目微信支付的一些參數保存在服務器上,所以我這邊還請求了自己的

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

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

 

[java] view plaincopy  
  1. /** 
  2.  * 微信分享,登陸,支付 
  3.  * @author ansen  
  4.  * @create time 2015-08-29 
  5.  */  
  6. public class WeiXinPresenter extends Presenter{  
  7.     public static final int IMAGE_SIZE=32768;//微信分享圖片大小限制  
  8.     public static final String APP_ID = "";//應用唯一標識,在微信開放平台提交應用審核通過後獲得  
  9.     public static final String SECRET="";//應用密鑰AppSecret,在微信開放平台提交應用審核通過後獲得  
  10.       
  11.     private  IWXAPI wxAPI;  
  12.     private  IView iView;  
  13.     private  IUserController userController;  
  14.       
  15.     @Override  
  16.     public IView getIView() {  
  17.         return iView;  
  18.     }  
  19.       
  20.     public WeiXinPresenter(Context context){  
  21.         if(context!=null && context instanceof  IView)  
  22.             iView =(IView) context;  
  23.         if(wxAPI==null){  
  24.             wxAPI = WXAPIFactory.createWXAPI(context,APP_ID,true);  
  25.             wxAPI.registerApp(APP_ID);  
  26.         }  
  27.         if(null==userController)  
  28.             userController=ControllerFactory.getUserController();  
  29.     }  
  30.       
  31.     /** 
  32.      * 微信登陸(三個步驟) 
  33.      * 1.微信授權登陸 
  34.      * 2.根據授權登陸code 獲取該用戶token 
  35.      * 3.根據token獲取用戶資料 
  36.      * @param activity 
  37.      */  
  38.     public void login(){  
  39.         SendAuth.Req req = new SendAuth.Req();  
  40.         req.scope = "snsapi_userinfo";  
  41.         req.state = String.valueOf(System.currentTimeMillis());  
  42.         wxAPI.sendReq(req);  
  43.     }  
  44.       
  45.     /** 
  46.      * 獲取微信訪問token 
  47.      */  
  48.     public void getAccessToken(String code){  
  49.         if(!userController.isLogin()){//沒有登陸的情況用第三方登陸  
  50.             userController.getWeiXinAccessToken(APP_ID,SECRET,code,new RequestDataCallback<WeiXinToken>(){  
  51.                 @Override  
  52.                 public void dataCallback(WeiXinToken obj){  
  53.                     if(obj!=null){  
  54.                         if(obj.getErrcode()==0){  
  55.                             if(MLog.debug)  
  56.                                 iView.showToast("授權用戶唯一標識:"+obj.getOpenid());  
  57.                             getWeiXinUserInfo(obj);  
  58.                         }else{  
  59.                             iView.showToast(obj.getErrmsg());  
  60.                         }  
  61.                     }else{  
  62.                           
  63.                     }  
  64.                 }  
  65.             });  
  66.         }else{//用戶已登陸  
  67.               
  68.         }  
  69.     }  
  70.       
  71.     /** 
  72.      * 獲取微信用戶信息 
  73.      */  
  74.     private void getWeiXinUserInfo(final WeiXinToken obj){  
  75.         userController.getWeiXinUserInfo(obj.getAccess_token(), obj.getOpenid(), new RequestDataCallback<RegisterB>() {  
  76.             @Override  
  77.             public void dataCallback(RegisterB registerB){  
  78.                 registerB.setAccess_token(obj.getAccess_token());  
  79.                 registerB.setToken_expire_at(obj.getExpires_in());  
  80.                 if(registerB.getErrcode()==0){  
  81.                     registerB.setThird_type_name(Constants.WEI_XIN);  
  82.                     thirdLogin(registerB);  
  83.                 }else{  
  84.                     iView.showToast(registerB.getErrmsg());  
  85.                 }  
  86.             }  
  87.         });  
  88.     }  
  89.       
  90.     /** 
  91.      * 調用我們自己的服務器進行登錄 
  92.      * @param registerB 
  93.      */  
  94.     private void thirdLogin(RegisterB registerB){  
  95.         userController.thirdAuth(registerB,new RequestDataCallback<UserP>(){  
  96.             @Override  
  97.             public void dataCallback(UserP user){  
  98.                 if(checkCallbackData(user, true)){  
  99.                     if(user.getError()==user.ErrorNone){  
  100.                         iView.showToast(R.string.login_success);  
  101.                         getAppController().sendLoginChangeIntent();  
  102.                         userController.saveLoginUser(user,FileUtil.getFilePath());  
  103.                         ((ILoginView)iView).toMain();  
  104.                     }else{  
  105.                         iView.showToast(user.getError_reason());  
  106.                     }  
  107.                 }  
  108.             }  
  109.         });  
  110.     }  
  111.       
  112.     /** 
  113.      * 微信分享 
  114.      * @param friendsCircle  是否分享到朋友圈 
  115.      */  
  116.     public void share(final boolean friendsCircle,final  VideoB videoB){  
  117.         new LoadPicThread(videoB.getCover_url(),new Handler(){  
  118.             @Override  
  119.             public void handleMessage(Message msg) {  
  120.                 byte[] bytes=(byte[]) msg.obj;  
  121.                 if(bytes.length>IMAGE_SIZE){  
  122.                     iView.showToast(R.string.image_no_big);  
  123.                     return;  
  124.                 }  
  125.                 System.out.println("圖片長度:"+bytes.length);  
  126.                 WXVideoObject videoObject = new WXVideoObject();//視頻類型  
  127.                 videoObject.videoUrl = videoB.getShare_url() + Constants.WEI_XIN + "&share_from="+com.kaka.utils.Constants.ANDROID;// 視頻播放url  
  128.                 WXMediaMessage wxMessage = new WXMediaMessage(videoObject);  
  129.                 wxMessage.title = videoB.getContent();  
  130.                 wxMessage.thumbData = bytes;  
  131.                 SendMessageToWX.Req req = new SendMessageToWX.Req();  
  132.                 //transaction字段用於唯一標識一個請求  
  133.                 req.transaction = String.valueOf(videoB.getId() + System.currentTimeMillis());  
  134.                 req.message = wxMessage;  
  135.                 req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;  
  136.                 wxAPI.sendReq(req);  
  137.             }  
  138.         }).start();  
  139.     }  
  140.       
  141.     private class LoadPicThread extends Thread{  
  142.         private String url;  
  143.         private Handler handler;  
  144.         public LoadPicThread(String url,Handler handler){  
  145.             this.url=url;  
  146.             this.handler=handler;  
  147.         }  
  148.           
  149.         @Override  
  150.         public void run(){  
  151.             try {  
  152.                 URL picurl = new URL(url);   
  153.                 HttpURLConnection conn = (HttpURLConnection)picurl.openConnection(); // 獲得連接   
  154.                 conn.setConnectTimeout(6000);//設置超時   
  155.                 conn.setDoInput(true);   
  156.                 conn.setUseCaches(false);//不緩存   
  157.                 conn.connect();  
  158.                 Bitmap bmp=BitmapFactory.decodeStream(conn.getInputStream());  
  159.                   
  160.                 ByteArrayOutputStream output = new ByteArrayOutputStream();  
  161.                   
  162.                 bmp.compress(Bitmap.CompressFormat.JPEG, 100, output);  
  163.                 int options = 100;  
  164.                 while (output.toByteArray().length > IMAGE_SIZE && options != 10) {   
  165.                     output.reset();  // 清空baos  
  166.                     bmp.compress(Bitmap.CompressFormat.JPEG, options, output);// 這裡壓縮options%,把壓縮後的數據存放到baos中    
  167.                     options -= 10;  
  168.                 }  
  169.                   
  170.                 bmp.recycle();  
  171.                 byte[] result = output.toByteArray();  
  172.                 output.close();  
  173.                   
  174.                 Message message=handler.obtainMessage();  
  175.                 message.obj=result;  
  176.                 message.sendToTarget();  
  177.             } catch (Exception e) {  
  178.                 e.printStackTrace();  
  179.             }  
  180.         }  
  181.     }  
  182.       
  183.     //檢查微信是否安裝  
  184.     public boolean isWXAppInstalled(){  
  185.         return wxAPI.isWXAppInstalled();  
  186.     }  
  187.       
  188.       
  189.     public void wxPay(final BaseActivity activity,String order_id,String payType){  
  190.         activity.showProgress("");  
  191.         ControllerFactory.getWalletsController().getPayments(order_id, payType, new RequestDataCallback<PaymentsP>() {  
  192.             @Override  
  193.             public void dataCallback(PaymentsP obj) {  
  194.                 if(checkCallbackData(obj, true)){  
  195.                     if(obj.getError()==obj.ErrorNone){  
  196.                         PayReq req = new PayReq();//待修改  
  197.   
  198.                         req.appId = obj.getAppid();  
  199.                         req.nonceStr=obj.getNoncestr();  
  200.                         req.packageValue=obj.getPackage_value();  
  201.                         req.sign=obj.getSign();  
  202.                         req.partnerId=obj.getPartnerid();  
  203.                         req.prepayId=obj.getPrepayid();  
  204.                         req.timeStamp=obj.getTimestamp();  
  205.                           
  206.                         wxAPI.registerApp(obj.getAppid());  
  207.                         wxAPI.sendReq(req);  
  208.                           
  209.                         MLog.i("ansen", "開始進行微信支付..");  
  210.                         iView.showToast("開始進行微信支付..");  
  211.                     }  
  212.                 }else{  
  213.                     iView.showToast(obj.getError_reason());  
  214.                 }  
  215.                 activity.hideProgress();  
  216.             }  
  217.         });  
  218.     }  
  219. }  

 

 

 

微信登陸以及分享 請求跟返回值的接收   我這邊登陸.分享的狀態都是發送廣播出去,然後結束當前的Activity.

 

[java] view plaincopy  
  1. /** 
  2.  * 微信登陸分享回調Activity 
  3.  * @author ansen 
  4.  * @create time 2015-05-25 
  5.  */  
  6. public class WXEntryActivity extends Activity implements IWXAPIEventHandler{  
  7.     private IWXAPI wxAPI;  
  8.       
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.   
  13.         if(MLog.debug)  
  14.             System.out.println("WXEntryActivity onCreate");  
  15.           
  16.         wxAPI = WXAPIFactory.createWXAPI(this,WeiXinPresenter.APP_ID,true);  
  17.         wxAPI.registerApp(WeiXinPresenter.APP_ID);  
  18.           
  19.         wxAPI.handleIntent(getIntent(), this);  
  20.     }  
  21.   
  22.     @Override  
  23.     protected void onNewIntent(Intent intent){  
  24.         super.onNewIntent(intent);  
  25.         wxAPI.handleIntent(getIntent(),this);  
  26.         if(MLog.debug)  
  27.             System.out.println("WXEntryActivity onNewIntent");  
  28.     }  
  29.       
  30.     @Override  
  31.     public void onReq(BaseReq arg0) {  
  32.         if(MLog.debug)  
  33.             System.out.println("WXEntryActivity onReq:"+arg0);  
  34.         if(MLog.debug)  
  35.             Toast.makeText(this, "onReq 方法運行", 0).show();  
  36.     }  
  37.   
  38.     @Override  
  39.     public void onResp(BaseResp resp){  
  40.         MLog.d("ansen", "onResp.....");  
  41.         if(MLog.debug)  
  42.             Toast.makeText(this,"onResp 方法運行", 0).show();  
  43.         if(resp.getType()==ConstantsAPI.COMMAND_SENDMESSAGE_TO_WX){//分享  
  44.             switch (resp.errCode){  
  45.             case BaseResp.ErrCode.ERR_OK:  
  46.                     if(MLog.debug)  
  47.                         Toast.makeText(WXEntryActivity.this, "分享成功!", Toast.LENGTH_SHORT).show();  
  48.                 break;  
  49.             case BaseResp.ErrCode.ERR_USER_CANCEL:  
  50. //                Toast.makeText(WXEntryActivity.this, "分享取消!", Toast.LENGTH_SHORT).show();  
  51.                 break;  
  52.             case BaseResp.ErrCode.ERR_AUTH_DENIED:  
  53.                   
  54.                 break;  
  55.             }  
  56.             Intent intent = new Intent();  
  57.             intent.setAction(APIDefineConst.BROADCAST_ACTION_WEIXIN_SHARE);  
  58.                 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);  
  59.                 lbm.sendBroadcast(intent);  
  60.         }else if(resp.getType()==ConstantsAPI.COMMAND_SENDAUTH){//登陸發送廣播  
  61.                 SendAuth.Resp authResp = (Resp) resp;  
  62.             String code = authResp.code;  
  63.             Intent intent = new Intent();  
  64.             intent.setAction(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN);  
  65.             intent.putExtra("errCode", authResp.errCode);  
  66.             if (authResp.errCode == BaseResp.ErrCode.ERR_OK){//用戶同意  
  67.                     intent.putExtra("code", code);  
  68.             }  
  69.               
  70.                 if(MLog.debug)  
  71.                     Toast.makeText(this, "WXEntryActivity 發送登陸廣播!!!!", 0).show();  
  72.                 if (android.os.Build.VERSION.SDK_INT >= 12) {  
  73.                      intent.setFlags(32);//3.1以後的版本需要設置Intent.FLAG_INCLUDE_STOPPED_PACKAGES  
  74.                 }  
  75.                 LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);  
  76.                 lbm.sendBroadcast(intent);  
  77.         }  
  78.         finish();  
  79.     }  
  80. }  



 

微信支付 請求跟返回值的接收   微信支付也是發送廣播,如果你們還有需求判斷支付成功或者失敗,可以在廣播的intent中進行傳參

 

[java] view plaincopy  
  1. /** 
  2.  * 微信支付回調Activity 
  3.  * @author ansen 
  4.  * @create time 2015-08-29 
  5.  */  
  6. public class WXPayEntryActivity extends Activity  implements IWXAPIEventHandler{  
  7.     private IWXAPI wxAPI;  
  8.       
  9.     @Override  
  10.     protected void onCreate(Bundle savedInstanceState) {  
  11.         super.onCreate(savedInstanceState);  
  12.         wxAPI = WXAPIFactory.createWXAPI(this, WeiXinPresenter.APP_ID);  
  13.         wxAPI.handleIntent(getIntent(), this);  
  14.     }  
  15.       
  16.     @Override  
  17.     protected void onNewIntent(Intent intent){  
  18.         super.onNewIntent(intent);  
  19.         setIntent(intent);  
  20.         wxAPI.handleIntent(intent, this);  
  21.     }  
  22.       
  23.     @Override  
  24.     public void onReq(BaseReq arg0) {  
  25.     }  
  26.   
  27.     @Override  
  28.     public void onResp(BaseResp resp) {  
  29.         MLog.i("微信支付回調..", "ansen onResp");  
  30.         if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX){//微信支付回調  
  31.             if(resp.errCode==BaseResp.ErrCode.ERR_OK){//微信支付成功  
  32.                 Intent intent = new Intent();  
  33.                 intent.setAction(APIDefineConst.BROADCAST_ACTION_WEIXIN_PAY);  
  34.                     LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);  
  35.                     lbm.sendBroadcast(intent);  
  36.                 //成功  
  37. //              Toast.makeText(this,R.string.wxpay_success, 0).show();  
  38.             }else{  
  39. //              Toast.makeText(this,R.string.wxpay_success, 0).show();  
  40.             }  
  41.         }  
  42.         finish();  
  43.     }  
  44.       
  45. }  



 

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

 

如何在activity中調用微信登陸

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

 

[java] view plaincopy  
  1. private class WXEntryReceiver extends BroadcastReceiver {  
  2.     @Override  
  3.     public void onReceive(Context context, Intent intent){  
  4.         MLog.i("WXEntryReceiver", "接收微信登陸廣播");  
  5.         if(MLog.debug)  
  6.             showToast("接收微信登陸廣播");  
  7.         if(intent.getAction().equals(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN)){  
  8.             int errCode = intent.getExtras().getInt("errCode");  
  9.             if(MLog.debug)  
  10.                 System.out.println("獲取錯誤碼:"+errCode);  
  11.             if(errCode==BaseResp.ErrCode.ERR_USER_CANCEL||errCode==BaseResp.ErrCode.ERR_AUTH_DENIED){  
  12.                 requestDataFinish();  
  13.             }else{  
  14.                 String code = intent.getExtras().getString("code");  
  15.                 xinTestPresenter.getAccessToken(code);  
  16.             }  
  17.         }  
  18.     }  
  19. }  

 

 

2).定義成員變量

 

[java] view plaincopy  
  1. private WXEntryReceiver wxEntryReceiver=null;  

 

 

3).在oncreate中注冊廣播

 

[java] view plaincopy  
  1. //微信登陸廣播  
  2. wxEntryReceiver= new WXEntryReceiver();  
  3. LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);  
  4. IntentFilter filter = new IntentFilter();  
  5. filter.addAction(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN);  
  6. lbm.registerReceiver(wxEntryReceiver,filter);  

 

 

4).調用微信登陸

 

[java] view plaincopy
  1. WeiXinPresenter xinTestPresenter=new WeiXinPresenter(this);  
  2. xinTestPresenter.login();  

 

在Activity中調用微信分享跟調用微信支付的代碼我就不貼出來了,我這篇博客只是給大家一個參考的地方,遇到問題還是建議第一時間看官方文檔.
說說我在做微信登陸碰到的問題

1.微信登陸、分享、支付    回調的activity    包名跟類名一定要嚴格按照要求去寫

2.接收回調的是activity  一定要在AndroidManifest.xml中注冊

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

4.可能訪問網絡神馬的還需要一些權限   記得在AndroidManifest.xml添加權限

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

6.微信沒有客服支持。。。。。如果出了問題看官方demo   或者 官方API

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

 

說了那麼多,感覺說了一大堆廢話......希望能幫到大家....有神馬問題可以給我留言....
推薦下自己創建的android QQ群:202928390 歡迎大家的加入.
我在csdn上上傳了一個微信sdk的jar包,有需要的可以去下載

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved