支付宝应用支付

单击按钮,调用支付方法。

 1         setContentView(R.layout.activity_main);
 2         findViewById(R.id.button1).setOnClickListener(
 3                 new View.OnClickListener() {
 4                     @Override
 5                     public void onClick(View v) {
 6                         // TODO Auto-generated method stub
 7                         // 拿到 Fiap 对象并传入容器
 8                         Fiap fiap = new Fiap(MainActivity.this);
 9                         // 调用支付方法,并传入支付金额
10                         fiap.android_pay(0.01);
11                     }
12                 });
13         }

支付宝应用支付 Fiap.java

   1 import java.io.BufferedReader;
   2 import java.io.File;
   3 import java.io.FileOutputStream;
   4 import java.io.IOException;
   5 import java.io.InputStream;
   6 import java.io.InputStreamReader;
   7 import java.io.OutputStream;
   8 import java.net.HttpURLConnection;
   9 import java.net.InetSocketAddress;
  10 import java.net.Proxy;
  11 import java.net.URL;
  12 import java.net.URLEncoder;
  13 import java.security.KeyFactory;
  14 import java.security.PrivateKey;
  15 import java.security.PublicKey;
  16 import java.security.spec.PKCS8EncodedKeySpec;
  17 import java.security.spec.X509EncodedKeySpec;
  18 import java.util.ArrayList;
  19 import java.util.List;
  20 import javax.net.ssl.HostnameVerifier;
  21 import javax.net.ssl.HttpsURLConnection;
  22 import javax.net.ssl.SSLSession;
  23 import org.apache.http.client.entity.UrlEncodedFormEntity;
  24 import org.apache.http.message.BasicNameValuePair;
  25 import org.json.JSONException;
  26 import org.json.JSONObject;
  27 import com.alipay.android.app.IAlixPay;
  28 import com.alipay.android.app.IRemoteServiceCallback;
  29 import android.annotation.SuppressLint;
  30 import android.app.Activity;
  31 import android.app.AlertDialog;
  32 import android.app.ProgressDialog;
  33 import android.content.ComponentName;
  34 import android.content.Context;
  35 import android.content.DialogInterface;
  36 import android.content.Intent;
  37 import android.content.ServiceConnection;
  38 import android.content.pm.PackageInfo;
  39 import android.content.pm.PackageManager;
  40 import android.net.ConnectivityManager;
  41 import android.net.NetworkInfo;
  42 import android.net.Uri;
  43 import android.os.Bundle;
  44 import android.os.Handler;
  45 import android.os.IBinder;
  46 import android.os.Looper;
  47 import android.os.Message;
  48 import android.os.RemoteException;
  49 import android.util.Log;
  50 import android.view.KeyEvent;
  51 import android.widget.Toast;
  52 
  53 
  54 @SuppressLint ("HandlerLeak")
  55 public class Fiap{
  56     Activity mActivity = null;
  57     
  58     // ===================================
  59     // JAVA 的接口
  60     // ===================================
  61    
  62     
  63     public Fiap(Activity activity){
  64    
  65     mActivity = activity;
  66    
  67     }
  68     
  69     //这里传过来的是想支付多少钱(最好定义成double的,方便调试,毕竟每次测试都支付几元大洋不是每个人都负担的起的)
  70     public void android_pay (double coin){
  71    
  72     //支付宝支付必须依赖网络,所以在这里必须加网络判定
  73         if (!is_can_internet (mActivity)){
  74        
  75             fiapHandler.sendEmptyMessage(1);
  76             return;
  77         }
  78         
  79         Message msg = new Message ();
  80         Bundle bundle = new Bundle();
  81         bundle.putDouble("coin", coin);
  82         msg.setData(bundle);
  83         msg.what = 1;
  84         fss.sendMessage (msg);
  85     }
  86     
  87     private Handler fiapHandler = new Handler(){
  88    
  89     public void handleMessage(Message msg) {
  90     if (msg.what == 1) {
  91     new AlertDialog.Builder (mActivity).setTitle ("提示").setMessage ("连接不到网络。").setPositiveButton ("确定", new DialogInterface.OnClickListener() {
  92 @Override
  93 public void onClick(DialogInterface dialog, int which) {
  94 // TODO Auto-generated method stub
  95 Intent intent = new Intent(
  96 "android.settings.WIFI_SETTINGS");
  97 mActivity.startActivity(intent);
  98 }
  99 }).create ().show ();
 100 }
 101     };
 102     };
 103     
 104     // ===================================
 105     // 支付宝
 106     // ===================================
 107     public class PartnerConfig {
 108 
 109 
 110 //以下配置涉及到公司内容,所以略去,需自己配置
 111         // 合作商户ID。用签约支付宝账号登录ms.alipay.com后,在账户信息页面获取。
 112         public static final String PARTNER = ""; 
 113         // 商户收款的支付宝账号
 114         public static final String SELLER = "";
 115         // 商户(RSA)私钥(注意一定要转PKCS8格式,否则在Android4.0及以上系统会支付失败)
 116         public static final String RSA_PRIVATE = "";
 117         // 支付宝(RSA)公钥用签约支付宝账号登录ms.alipay.com后,在密钥管理页面获取。
 118         public static final String RSA_ALIPAY_PUBLIC = "";
 119     }
 120     
 121     
 122     private ProgressDialog mProgress = null;
 123     
 124     
 125     public static class AlixOnCancelListener implements DialogInterface.OnCancelListener {
 126         Activity mcontext;
 127         
 128         
 129         AlixOnCancelListener (Activity context){
 130             mcontext = context;
 131         }
 132         
 133         
 134         public void onCancel (DialogInterface dialog){
 135             mcontext.onKeyDown (KeyEvent.KEYCODE_BACK, null);
 136         }
 137     }
 138     
 139     
 140     private Handler fss = new Handler (){
 141         @SuppressWarnings ("deprecation")
 142         public void handleMessage (Message msg){
 143             MobileSecurePayHelper mspHelper = new MobileSecurePayHelper (mActivity);
 144             boolean isMobile_spExist = mspHelper.detectMobile_sp ();
 145             if (!isMobile_spExist)
 146                 return;
 147             // 根据订单信息开始进行支付
 148             try{
 149                 // 准备订单信息
 150                 Bundle bundle = msg.getData();
 151                 double _coin = bundle.getDouble("coin");
 152                 String orderInfo = getOrderInfo(_coin);
 153                 // 这里根据签名方式对订单信息进行签名
 154                 String signType = getSignType ();
 155                 String strsign = sign (signType, orderInfo);
 156                 // 对签名进行编码
 157                 strsign = URLEncoder.encode (strsign);
 158                 // 组装好参数
 159                 String info = orderInfo + "&sign=" + """ + strsign + """ + "&" + getSignType ();
 160                 // 调用pay方法进行支付
 161                 MobileSecurePayer msp = new MobileSecurePayer ();
 162                 boolean bRet = msp.pay (info, mHandler, AlixId.RQF_PAY, mActivity);
 163                 if (bRet){
 164                     // 显示“正在支付”进度条
 165                     closeProgress ();
 166                     mProgress = BaseHelper.showProgress (mActivity, null, "正在支付", false, true);
 167                 }
 168             } catch (Exception ex){
 169                 ex.printStackTrace ();
 170             }
 171         }
 172     };
 173     
 174     private Handler mHandler = new Handler (){
 175         public void handleMessage (Message msg){
 176             try{
 177                 String strRet = (String) msg.obj;
 178                 switch (msg.what){
 179                     case AlixId.RQF_PAY:{
 180                         //
 181                         closeProgress ();
 182                         // 处理交易结果
 183                         try{
 184                             // 获取交易状态码,具体状态代码请参看文档
 185                             String tradeStatus = "resultStatus={";
 186                             int imemoStart = strRet.indexOf ("resultStatus=");
 187                             imemoStart += tradeStatus.length ();
 188                             int imemoEnd = strRet.indexOf ("};memo=");
 189                             tradeStatus = strRet.substring (imemoStart, imemoEnd);
 190                             //先验签通知
 191                             ResultChecker resultChecker = new ResultChecker (strRet);
 192                             int retVal = resultChecker.checkSign ();
 193                             if (retVal == ResultChecker.RESULT_CHECK_SIGN_FAILED){
 194                                 BaseHelper.showDialog (mActivity, "提示", "您的订单信息已被非法篡改。", android.R.drawable.ic_dialog_alert);
 195                             } else{
 196                                 if (tradeStatus.equals ("9000")){
 197                                
 198                                     //程序到这里表示支付已经成功了,想干什么就在这里干吧 -v-
 199                                 Toast.makeText(mActivity, "支付成功",Toast.LENGTH_LONG).show();
 200                                 Log.i("result of this pay:", "successful");
 201                                 
 202                                 } else if (!tradeStatus.equals ("4000")){
 203                                
 204                                 //程序到这里表示此次支付失败,查看具体原因可以从这里打印个log
 205                                 Toast.makeText(mActivity, "支付失败,交易状态码为:" + tradeStatus, Toast.LENGTH_LONG).show();
 206                                 Log.e("result of this pay", "falied");
 207                                 }
 208                             }
 209                         } catch (Exception e){
 210                             e.printStackTrace ();
 211                         }
 212                     }
 213                         break;
 214                 }
 215                 super.handleMessage (msg);
 216             } catch (Exception e){
 217                 e.printStackTrace ();
 218             }
 219         }
 220     };
 221     
 222     
 223     String getSignType (){
 224         String getSignType = "sign_type=" + """ + "RSA" + """;
 225         return getSignType;
 226     }
 227     
 228     
 229     void closeProgress (){
 230         try{
 231             if (mProgress != null){
 232                 mProgress.dismiss ();
 233                 mProgress = null;
 234             }
 235         } catch (Exception e){
 236             e.printStackTrace ();
 237         }
 238     }
 239     
 240     
 241     String getOrderInfo (double position){
 242    
 243         String strOrderInfo = "partner=" + """ + PartnerConfig.PARTNER + """;
 244         strOrderInfo += "&";
 245         strOrderInfo += "seller=" + """ + PartnerConfig.SELLER + """;
 246         strOrderInfo += "&";
 247         strOrderInfo += "out_trade_no=" + """ + get_order_id () + """;
 248         strOrderInfo += "&";
 249         
 250         //这里是显示到支付宝支付界面上的付费信息提示(这里一定要严格按照此格式填写)
 251         strOrderInfo += "subject=" + ""猫币"";
 252         strOrderInfo += "&";
 253         strOrderInfo += "body=" + ""购买猫币"";
 254         strOrderInfo += "&";
 255         strOrderInfo += "total_fee=" + """ + position + """;
 256         strOrderInfo += "&";
 257         strOrderInfo += "notify_url=" + """ + "http://notify.java.jpxx.org/index.jsp" + """;
 258         return strOrderInfo;
 259     }
 260     
 261     
 262     String sign (String signType, String content){
 263         return Rsa.sign (content, PartnerConfig.RSA_PRIVATE);
 264     }
 265     
 266    
 267     public boolean is_can_internet (final Context context){
 268         try{
 269             ConnectivityManager manger = (ConnectivityManager) context.getSystemService (Context.CONNECTIVITY_SERVICE);
 270             NetworkInfo info = manger.getActiveNetworkInfo ();
 271             
 272             return (info != null && info.isConnected ());
 273         } catch (Exception e){
 274        
 275             return false;
 276         }
 277     }
 278     
 279    
 280     public String get_order_id (){
 281         long ran1 = get_round (1111, 9999);
 282         long ran2 = get_round (1111, 9999);
 283         
 284         //注掉的这里是返回的渠道号(我们用的友盟)+随机数和当前系统时间组合
 285         //return android_get_umeng_channel () + "_" + ran1 + System.currentTimeMillis () + ran2;
 286         return "_"+ran1 + System.currentTimeMillis () + ran2;
 287     }
 288     
 289    
 290     public long get_round (int min, int max){
 291         return Math.round (Math.random () * (max - min) + min);
 292     }
 293     
 294     
 295     //=================================================================================================
 296     // 
 297     // 支付宝不用动的
 298     // ==================================================================================================
 299     public final class AlixId {
 300         public static final int BASE_ID = 0;
 301         public static final int RQF_PAY = BASE_ID + 1;
 302         public static final int RQF_INSTALL_CHECK = RQF_PAY + 1;
 303     }
 304     
 305     final class AlixDefine {
 306         public static final String IMEI = "imei";
 307         public static final String IMSI = "imsi";
 308         public static final String KEY = "key";
 309         public static final String USER_AGENT = "user_agent";
 310         public static final String VERSION = "version";
 311         public static final String DEVICE = "device";
 312         public static final String SID = "sid";
 313         public static final String partner = "partner";
 314         public static final String charset = "charset";
 315         public static final String sign_type = "sign_type";
 316         public static final String sign = "sign";
 317         public static final String URL = "URL";
 318         public static final String split = "&";
 319         public static final String AlixPay = "AlixPay";
 320         public static final String action = "action";
 321         public static final String actionUpdate = "update";
 322         public static final String data = "data";
 323         public static final String platform = "platform";
 324     }
 325     
 326     public static final class Base64 {
 327         static private final int BASELENGTH = 128;
 328         static private final int LOOKUPLENGTH = 64;
 329         static private final int TWENTYFOURBITGROUP = 24;
 330         static private final int EIGHTBIT = 8;
 331         static private final int SIXTEENBIT = 16;
 332         static private final int FOURBYTE = 4;
 333         static private final int SIGN = -128;
 334         static private final char PAD = '=';
 335         static private final boolean fDebug = false;
 336         static final private byte[] base64Alphabet = new byte[BASELENGTH];
 337         static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
 338         static{
 339             for (int i = 0; i < BASELENGTH; ++i){
 340                 base64Alphabet[i] = -1;
 341             }
 342             for (int i = 'Z'; i >= 'A'; i--){
 343                 base64Alphabet[i] = (byte) (i - 'A');
 344             }
 345             for (int i = 'z'; i >= 'a'; i--){
 346                 base64Alphabet[i] = (byte) (i - 'a' + 26);
 347             }
 348             for (int i = '9'; i >= '0'; i--){
 349                 base64Alphabet[i] = (byte) (i - '0' + 52);
 350             }
 351             base64Alphabet['+'] = 62;
 352             base64Alphabet['/'] = 63;
 353             for (int i = 0; i <= 25; i++){
 354                 lookUpBase64Alphabet[i] = (char) ('A' + i);
 355             }
 356             for (int i = 26, j = 0; i <= 51; i++, j++){
 357                 lookUpBase64Alphabet[i] = (char) ('a' + j);
 358             }
 359             for (int i = 52, j = 0; i <= 61; i++, j++){
 360                 lookUpBase64Alphabet[i] = (char) ('0' + j);
 361             }
 362             lookUpBase64Alphabet[62] = (char) '+';
 363             lookUpBase64Alphabet[63] = (char) '/';
 364         }
 365         
 366         
 367         private static boolean isWhiteSpace (char octect){
 368             return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
 369         }
 370         
 371         
 372         private static boolean isPad (char octect){
 373             return (octect == PAD);
 374         }
 375         
 376         
 377         private static boolean isData (char octect){
 378             return (octect < BASELENGTH && base64Alphabet[octect] != -1);
 379         }
 380         
 381         
 382        
 383         public static String encode (byte[] binaryData){
 384             if (binaryData == null){
 385                 return null;
 386             }
 387             int lengthDataBits = binaryData.length * EIGHTBIT;
 388             if (lengthDataBits == 0){
 389                 return "";
 390             }
 391             int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
 392             int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
 393             int numberQuartet = fewerThan24bits != 0? numberTriplets + 1 : numberTriplets;
 394             char encodedData[] = null;
 395             encodedData = new char[numberQuartet * 4];
 396             byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
 397             int encodedIndex = 0;
 398             int dataIndex = 0;
 399             if (fDebug){
 400                 System.out.println ("number of triplets = " + numberTriplets);
 401             }
 402             for (int i = 0; i < numberTriplets; i++){
 403                 b1 = binaryData[dataIndex++];
 404                 b2 = binaryData[dataIndex++];
 405                 b3 = binaryData[dataIndex++];
 406                 if (fDebug){
 407                     System.out.println ("b1= " + b1 + ", b2= " + b2 + ", b3= " + b3);
 408                 }
 409                 l = (byte) (b2 & 0x0f);
 410                 k = (byte) (b1 & 0x03);
 411                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
 412                 byte val2 = ((b2 & SIGN) == 0)? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
 413                 byte val3 = ((b3 & SIGN) == 0)? (byte) (b3 >> 6) : (byte) ((b3) >> 6 ^ 0xfc);
 414                 if (fDebug){
 415                     System.out.println ("val2 = " + val2);
 416                     System.out.println ("k4   = " + (k << 4));
 417                     System.out.println ("vak  = " + (val2 | (k << 4)));
 418                 }
 419                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
 420                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
 421                 encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
 422                 encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
 423             }
 424             // form integral number of 6-bit groups
 425             if (fewerThan24bits == EIGHTBIT){
 426                 b1 = binaryData[dataIndex];
 427                 k = (byte) (b1 & 0x03);
 428                 if (fDebug){
 429                     System.out.println ("b1=" + b1);
 430                     System.out.println ("b1<<2 = " + (b1 >> 2));
 431                 }
 432                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
 433                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
 434                 encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
 435                 encodedData[encodedIndex++] = PAD;
 436                 encodedData[encodedIndex++] = PAD;
 437             } else if (fewerThan24bits == SIXTEENBIT){
 438                 b1 = binaryData[dataIndex];
 439                 b2 = binaryData[dataIndex + 1];
 440                 l = (byte) (b2 & 0x0f);
 441                 k = (byte) (b1 & 0x03);
 442                 byte val1 = ((b1 & SIGN) == 0)? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
 443                 byte val2 = ((b2 & SIGN) == 0)? (byte) (b2 >> 4) : (byte) ((b2) >> 4 ^ 0xf0);
 444                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
 445                 encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
 446                 encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
 447                 encodedData[encodedIndex++] = PAD;
 448             }
 449             return new String (encodedData);
 450         }
 451         
 452         
 453        
 454         public static byte[] decode (String encoded){
 455             if (encoded == null){
 456                 return null;
 457             }
 458             char[] base64Data = encoded.toCharArray ();
 459             // remove white spaces
 460             int len = removeWhiteSpace (base64Data);
 461             if (len % FOURBYTE != 0){
 462                 return null;// should be divisible by four
 463             }
 464             int numberQuadruple = (len / FOURBYTE);
 465             if (numberQuadruple == 0){
 466                 return new byte[0];
 467             }
 468             byte decodedData[] = null;
 469             byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
 470             char d1 = 0, d2 = 0, d3 = 0, d4 = 0;
 471             int i = 0;
 472             int encodedIndex = 0;
 473             int dataIndex = 0;
 474             decodedData = new byte[(numberQuadruple) * 3];
 475             for (; i < numberQuadruple - 1; i++){
 476                 if (!isData ((d1 = base64Data[dataIndex++])) || !isData ((d2 = base64Data[dataIndex++])) || !isData ((d3 = base64Data[dataIndex++])) || !isData ((d4 = base64Data[dataIndex++]))){
 477                     return null;
 478                 }// if found "no data" just return null
 479                 b1 = base64Alphabet[d1];
 480                 b2 = base64Alphabet[d2];
 481                 b3 = base64Alphabet[d3];
 482                 b4 = base64Alphabet[d4];
 483                 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
 484                 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
 485                 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
 486             }
 487             if (!isData ((d1 = base64Data[dataIndex++])) || !isData ((d2 = base64Data[dataIndex++]))){
 488                 return null;// if found "no data" just return null
 489             }
 490             b1 = base64Alphabet[d1];
 491             b2 = base64Alphabet[d2];
 492             d3 = base64Data[dataIndex++];
 493             d4 = base64Data[dataIndex++];
 494             if (!isData ((d3)) || !isData ((d4))){// Check if they are PAD characters
 495                 if (isPad (d3) && isPad (d4)){
 496                     if ((b2 & 0xf) != 0)// last 4 bits should be zero
 497                     {
 498                         return null;
 499                     }
 500                     byte[] tmp = new byte[i * 3 + 1];
 501                     System.arraycopy (decodedData, 0, tmp, 0, i * 3);
 502                     tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
 503                     return tmp;
 504                 } else if (!isPad (d3) && isPad (d4)){
 505                     b3 = base64Alphabet[d3];
 506                     if ((b3 & 0x3) != 0)// last 2 bits should be zero
 507                     {
 508                         return null;
 509                     }
 510                     byte[] tmp = new byte[i * 3 + 2];
 511                     System.arraycopy (decodedData, 0, tmp, 0, i * 3);
 512                     tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
 513                     tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
 514                     return tmp;
 515                 } else{
 516                     return null;
 517                 }
 518             } else{ // No PAD e.g 3cQl
 519                 b3 = base64Alphabet[d3];
 520                 b4 = base64Alphabet[d4];
 521                 decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
 522                 decodedData[encodedIndex++] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
 523                 decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
 524             }
 525             return decodedData;
 526         }
 527         
 528         
 529        
 530         private static int removeWhiteSpace (char[] data){
 531             if (data == null){
 532                 return 0;
 533             }
 534             // count characters that's not whitespace
 535             int newSize = 0;
 536             int len = data.length;
 537             for (int i = 0; i < len; i++){
 538                 if (!isWhiteSpace (data[i])){
 539                     data[newSize++] = data[i];
 540                 }
 541             }
 542             return newSize;
 543         }
 544     }
 545     
 546     public static class BaseHelper {
 547        
 548         public static String convertStreamToString (InputStream is){
 549             BufferedReader reader = new BufferedReader (new InputStreamReader (is));
 550             StringBuilder sb = new StringBuilder ();
 551             String line = null;
 552             try{
 553                 while ((line = reader.readLine ()) != null){
 554                     sb.append (line);
 555                 }
 556             } catch (IOException e){
 557                 e.printStackTrace ();
 558             } finally{
 559                 try{
 560                     is.close ();
 561                 } catch (IOException e){
 562                     e.printStackTrace ();
 563                 }
 564             }
 565             return sb.toString ();
 566         }
 567         
 568         
 569        
 570         public static void showDialog (Activity context, String strTitle, String strText, int icon){
 571             AlertDialog.Builder tDialog = new AlertDialog.Builder (context);
 572             tDialog.setIcon (icon);
 573             tDialog.setTitle (strTitle);
 574             tDialog.setMessage (strText);
 575             tDialog.setPositiveButton ("确定", null);
 576             tDialog.show ();
 577         }
 578         
 579         
 580        
 581         public static void log (String tag, String info){
 582             // Log.d(tag, info);
 583         }
 584         
 585         
 586        
 587         public static void chmod (String permission, String path){
 588             try{
 589                 String command = "chmod " + permission + " " + path;
 590                 Runtime runtime = Runtime.getRuntime ();
 591                 runtime.exec (command);
 592             } catch (IOException e){
 593                 e.printStackTrace ();
 594             }
 595         }
 596         
 597         
 598         //
 599         // show the progress bar.
 600        
 601         public static ProgressDialog showProgress (Context context, CharSequence title, CharSequence message, boolean indeterminate, boolean cancelable){
 602             ProgressDialog dialog = new ProgressDialog (context);
 603             dialog.setTitle (title);
 604             dialog.setMessage (message);
 605             dialog.setIndeterminate (indeterminate);
 606             dialog.setCancelable (false);
 607             // dialog.setDefaultButton(false);
 608             dialog.setOnCancelListener (new Fiap.AlixOnCancelListener ((Activity) context));
 609             dialog.show ();
 610             return dialog;
 611         }
 612         
 613         
 614        
 615         public static JSONObject string2JSON (String str, String split){
 616             JSONObject json = new JSONObject ();
 617             try{
 618                 String[] arrStr = str.split (split);
 619                 for (int i = 0; i < arrStr.length; i++){
 620                     String[] arrKeyValue = arrStr[i].split ("=");
 621                     json.put (arrKeyValue[0], arrStr[i].substring (arrKeyValue[0].length () + 1));
 622                 }
 623             } catch (Exception e){
 624                 e.printStackTrace ();
 625             }
 626             return json;
 627         }
 628     }
 629     
 630     public class Constant {
 631         public final static String server_url = "https://msp.alipay.com/x.htm";
 632     }
 633     
 634     public class MobileSecurePayer {
 635         Integer lock = 0;
 636         IAlixPay mAlixPay = null;
 637         boolean mbPaying = false;
 638         Activity mActivity = null;
 639         // 和安全支付服务建立连接
 640         private ServiceConnection mAlixPayConnection = new ServiceConnection (){
 641             public void onServiceConnected (ComponentName className, IBinder service){
 642                 //
 643                 // wake up the binder to continue.
 644                 // 获得通信通道
 645                 synchronized (lock){
 646                     mAlixPay = IAlixPay.Stub.asInterface (service);
 647                     lock.notify ();
 648                 }
 649             }
 650             
 651             
 652             public void onServiceDisconnected (ComponentName className){
 653                 mAlixPay = null;
 654             }
 655         };
 656         
 657         
 658        
 659         public boolean pay (final String strOrderInfo, final Handler callback, final int myWhat, final Activity activity){
 660             if (mbPaying)
 661                 return false;
 662             mbPaying = true;
 663             //
 664             mActivity = activity;
 665             // bind the service.
 666             // 绑定服务
 667             if (mAlixPay == null){
 668                 // 绑定安全支付服务需要获取上下文环境,
 669                 // 如果绑定不成功使用mActivity.getApplicationContext().bindService
 670                 // 解绑时同理
 671                 mActivity.getApplicationContext ().bindService (new Intent (IAlixPay.class.getName ()), mAlixPayConnection, Context.BIND_AUTO_CREATE);
 672             }
 673             // else ok.
 674             // 实例一个线程来进行支付
 675             new Thread (new Runnable (){
 676                 public void run (){
 677                     try{
 678                         // wait for the service bind operation to completely
 679                         // finished.
 680                         // Note: this is important,otherwise the next mAlixPay.Pay()
 681                         // will fail.
 682                         // 等待安全支付服务绑定操作结束
 683                         // 注意:这里很重要,否则mAlixPay.Pay()方法会失败
 684                         synchronized (lock){
 685                             if (mAlixPay == null)
 686                                 lock.wait ();
 687                         }
 688                         // register a Callback for the service.
 689                         // 为安全支付服务注册一个回调
 690                         mAlixPay.registerCallback (mCallback);
 691                         // call the MobileSecurePay service.
 692                         // 调用安全支付服务的pay方法
 693                         String strRet = mAlixPay.Pay (strOrderInfo);
 694                         // set the flag to indicate that we have finished.
 695                         // unregister the Callback, and unbind the service.
 696                         // 将mbPaying置为false,表示支付结束
 697                         // 移除回调的注册,解绑安全支付服务
 698                         mbPaying = false;
 699                         mAlixPay.unregisterCallback (mCallback);
 700                         mActivity.getApplicationContext ().unbindService (mAlixPayConnection);
 701                         // send the result back to caller.
 702                         // 发送交易结果
 703                         Message msg = new Message ();
 704                         msg.what = myWhat;
 705                         msg.obj = strRet;
 706                         callback.sendMessage (msg);
 707                     } catch (Exception e){
 708                         e.printStackTrace ();
 709                         // send the result back to caller.
 710                         // 发送交易结果
 711                         Message msg = new Message ();
 712                         msg.what = myWhat;
 713                         msg.obj = e.toString ();
 714                         callback.sendMessage (msg);
 715                     }
 716                 }
 717             }).start ();
 718             return true;
 719         }
 720         
 721         
 722        
 723         private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub (){
 724            
 725             public void startActivity (String packageName, String className, int iCallingPid, Bundle bundle) throws RemoteException{
 726                 Intent intent = new Intent (Intent.ACTION_MAIN, null);
 727                 if (bundle == null)
 728                     bundle = new Bundle ();
 729                 // else ok.
 730                 try{
 731                     bundle.putInt ("CallingPid", iCallingPid);
 732                     intent.putExtras (bundle);
 733                 } catch (Exception e){
 734                     e.printStackTrace ();
 735                 }
 736                 intent.setClassName (packageName, className);
 737                 mActivity.startActivity (intent);
 738             }
 739 
 740 
 741             @Override
 742             public boolean isHideLoadingScreen () throws RemoteException{
 743                 return false;
 744             }
 745 
 746 
 747             @Override
 748             public void payEnd (boolean arg0, String arg1) throws RemoteException{
 749                 
 750             }
 751         };
 752     }
 753     
 754     public class MobileSecurePayHelper {
 755         static final String TAG = "MobileSecurePayHelper";
 756         private ProgressDialog mProgress = null;
 757         Context mContext = null;
 758         
 759         
 760         public MobileSecurePayHelper (Context context){
 761             this.mContext = context;
 762         }
 763         
 764         
 765        
 766         public boolean detectMobile_sp (){
 767             boolean isMobile_spExist = isMobile_spExist ();
 768             if (!isMobile_spExist){
 769                 // 获取系统缓冲绝对路径获取/data/data//cache目录
 770                 File cacheDir = mContext.getCacheDir ();
 771                 final String cachePath = cacheDir.getAbsolutePath () + "/temp.apk";
 772                 mProgress = BaseHelper.showProgress (mContext, null, "正在检测安全支付服务版本", false, true);
 773                 // 实例新线程检测是否有新版本进行下载
 774                 new Thread (new Runnable (){
 775                     public void run (){
 776                         // 检测是否有新的版本。
 777                         String newApkdlUrl = checkNewUpdate ();
 778                         closeProgress ();
 779                         // 动态下载
 780                         if (newApkdlUrl != null)
 781                             retrieveApkFromNet (mContext, newApkdlUrl, cachePath);
 782                         showInstallConfirmDialog (mContext, cachePath);
 783                     }
 784                 }).start ();
 785             }
 786             return isMobile_spExist;
 787         }
 788         
 789         
 790        
 791         public void showInstallConfirmDialog (final Context context, final String cachePath){
 792             Looper.prepare ();
 793             AlertDialog.Builder tDialog = new AlertDialog.Builder (context);
 794             tDialog.setTitle ("安装提示");
 795             tDialog.setMessage ("为保证您的交易安全,需要您安装支付宝安全支付服务,才能进行付款。\n\n点击确定,立即安装。");
 796             tDialog.setPositiveButton ("确定", new DialogInterface.OnClickListener (){
 797                 public void onClick (DialogInterface dialog, int which){
 798                     //
 799                     // 修改apk权限
 800                     BaseHelper.chmod ("777", cachePath);
 801                     //
 802                     // install the apk.
 803                     // 安装安全支付服务APK
 804                     Intent intent = new Intent (Intent.ACTION_VIEW);
 805                     intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
 806                     intent.setDataAndType (Uri.parse ("file://" + cachePath), "application/vnd.android.package-archive");
 807                     context.startActivity (intent);
 808                 }
 809             });
 810             tDialog.setNegativeButton ("取消", new DialogInterface.OnClickListener (){
 811                 public void onClick (DialogInterface dialog, int which){}
 812             });
 813             tDialog.show ();
 814             Looper.loop ();
 815         }
 816         
 817         
 818        
 819         public boolean isMobile_spExist (){
 820             PackageManager manager = mContext.getPackageManager ();
 821             List<PackageInfo> pkgList = manager.getInstalledPackages (0);
 822             for (int i = 0; i < pkgList.size (); i++){
 823                 PackageInfo pI = pkgList.get (i);
 824                 if (pI.packageName.equalsIgnoreCase ("com.alipay.android.app"))
 825                     return true;
 826             }
 827             return false;
 828         }
 829         
 830         
 831        
 832         public boolean retrieveApkFromAssets (Context context, String fileName, String path){
 833             boolean bRet = false;
 834             try{
 835                 InputStream is = context.getAssets ().open (fileName);
 836                 File file = new File (path);
 837                 file.createNewFile ();
 838                 FileOutputStream fos = new FileOutputStream (file);
 839                 byte[] temp = new byte[1024];
 840                 int i = 0;
 841                 while ((i = is.read (temp)) > 0){
 842                     fos.write (temp, 0, i);
 843                 }
 844                 fos.close ();
 845                 is.close ();
 846                 bRet = true;
 847             } catch (IOException e){
 848                 e.printStackTrace ();
 849             }
 850             return bRet;
 851         }
 852         
 853         
 854        
 855         public PackageInfo getApkInfo (Context context, String archiveFilePath){
 856             PackageManager pm = context.getPackageManager ();
 857             PackageInfo apkInfo = pm.getPackageArchiveInfo (archiveFilePath, PackageManager.GET_META_DATA);
 858             return apkInfo;
 859         }
 860         
 861         
 862        
 863         public String checkNewUpdate (){
 864             String url = null;
 865             try{
 866 //                JSONObject resp = sendCheckNewUpdate (packageInfo.versionName);
 867                  JSONObject resp = sendCheckNewUpdate("1.0.0");
 868                 if (resp.getString ("needUpdate").equalsIgnoreCase ("true")){
 869                     url = resp.getString ("updateUrl");
 870                 }
 871                 // else ok.
 872             } catch (Exception e){
 873                 e.printStackTrace ();
 874             }
 875             return url;
 876         }
 877         
 878         
 879        
 880         public JSONObject sendCheckNewUpdate (String versionName){
 881             JSONObject objResp = null;
 882             try{
 883                 JSONObject req = new JSONObject ();
 884                 req.put (AlixDefine.action, AlixDefine.actionUpdate);
 885                 JSONObject data = new JSONObject ();
 886                 data.put (AlixDefine.platform, "android");
 887                 data.put (AlixDefine.VERSION, versionName);
 888                 data.put (AlixDefine.partner, "");
 889                 req.put (AlixDefine.data, data);
 890                 objResp = sendRequest (req.toString ());
 891             } catch (JSONException e){
 892                 e.printStackTrace ();
 893             }
 894             return objResp;
 895         }
 896         
 897         
 898        
 899         public JSONObject sendRequest (final String content){
 900             NetworkManager nM = new NetworkManager (this.mContext);
 901             //
 902             JSONObject jsonResponse = null;
 903             try{
 904                 String response = null;
 905                 synchronized (nM){
 906                     //
 907                     response = nM.SendAndWaitResponse (content, Constant.server_url);
 908                 }
 909                 jsonResponse = new JSONObject (response);
 910             } catch (Exception e){
 911                 e.printStackTrace ();
 912             }
 913             //
 914             if (jsonResponse != null)
 915                 BaseHelper.log (TAG, jsonResponse.toString ());
 916             return jsonResponse;
 917         }
 918         
 919         
 920        
 921         public boolean retrieveApkFromNet (Context context, String strurl, String filename){
 922             boolean bRet = false;
 923             try{
 924                 NetworkManager nM = new NetworkManager (this.mContext);
 925                 bRet = nM.urlDownloadToFile (context, strurl, filename);
 926             } catch (Exception e){
 927                 e.printStackTrace ();
 928             }
 929             return bRet;
 930         }
 931         
 932         
 933         //
 934         // close the progress bar
 935         void closeProgress (){
 936             try{
 937                 if (mProgress != null){
 938                     mProgress.dismiss ();
 939                     mProgress = null;
 940                 }
 941             } catch (Exception e){
 942                 e.printStackTrace ();
 943             }
 944         }
 945     }
 946     
 947     public class NetworkManager {
 948         static final String TAG = "NetworkManager";
 949         private int connectTimeout = 30 * 1000;
 950         private int readTimeout = 30 * 1000;
 951         Proxy mProxy = null;
 952         Context mContext;
 953         
 954         
 955         public NetworkManager (Context context){
 956             this.mContext = context;
 957             setDefaultHostnameVerifier ();
 958         }
 959         
 960         
 961        
 962         @SuppressWarnings ("deprecation")
 963         private void detectProxy (){
 964             ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService (Context.CONNECTIVITY_SERVICE);
 965             NetworkInfo ni = cm.getActiveNetworkInfo ();
 966             if (ni != null && ni.isAvailable () && ni.getType () == ConnectivityManager.TYPE_MOBILE){
 967                 String proxyHost = android.net.Proxy.getDefaultHost ();
 968                 int port = android.net.Proxy.getDefaultPort ();
 969                 if (proxyHost != null){
 970                     final InetSocketAddress sa = new InetSocketAddress (proxyHost, port);
 971                     mProxy = new Proxy (Proxy.Type.HTTP, sa);
 972                 }
 973             }
 974         }
 975         
 976         
 977         private void setDefaultHostnameVerifier (){
 978             //
 979             HostnameVerifier hv = new HostnameVerifier (){
 980                 public boolean verify (String hostname, SSLSession session){
 981                     return true;
 982                 }
 983             };
 984             HttpsURLConnection.setDefaultHostnameVerifier (hv);
 985         }
 986         
 987         
 988        
 989         public String SendAndWaitResponse (String strReqData, String strUrl){
 990             //
 991             detectProxy ();
 992             String strResponse = null;
 993             ArrayList<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair> ();
 994             pairs.add (new BasicNameValuePair ("requestData", strReqData));
 995             HttpURLConnection httpConnect = null;
 996             UrlEncodedFormEntity p_entity;
 997             try{
 998                 p_entity = new UrlEncodedFormEntity (pairs, "utf-8");
 999                 URL url = new URL (strUrl);
1000                 if (mProxy != null){
1001                     httpConnect = (HttpURLConnection) url.openConnection (mProxy);
1002                 } else{
1003                     httpConnect = (HttpURLConnection) url.openConnection ();
1004                 }
1005                 httpConnect.setConnectTimeout (connectTimeout);
1006                 httpConnect.setReadTimeout (readTimeout);
1007                 httpConnect.setDoOutput (true);
1008                 httpConnect.addRequestProperty ("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
1009                 httpConnect.connect ();
1010                 OutputStream os = httpConnect.getOutputStream ();
1011                 p_entity.writeTo (os);
1012                 os.flush ();
1013                 InputStream content = httpConnect.getInputStream ();
1014                 strResponse = BaseHelper.convertStreamToString (content);
1015                 BaseHelper.log (TAG, "response " + strResponse);
1016             } catch (IOException e){
1017                 e.printStackTrace ();
1018             } finally{
1019                 httpConnect.disconnect ();
1020             }
1021             return strResponse;
1022         }
1023         
1024         
1025        
1026         public boolean urlDownloadToFile (Context context, String strurl, String path){
1027             boolean bRet = false;
1028             //
1029             detectProxy ();
1030             try{
1031                 URL url = new URL (strurl);
1032                 HttpURLConnection conn = null;
1033                 if (mProxy != null){
1034                     conn = (HttpURLConnection) url.openConnection (mProxy);
1035                 } else{
1036                     conn = (HttpURLConnection) url.openConnection ();
1037                 }
1038                 conn.setConnectTimeout (connectTimeout);
1039                 conn.setReadTimeout (readTimeout);
1040                 conn.setDoInput (true);
1041                 conn.connect ();
1042                 InputStream is = conn.getInputStream ();
1043                 File file = new File (path);
1044                 file.createNewFile ();
1045                 FileOutputStream fos = new FileOutputStream (file);
1046                 byte[] temp = new byte[1024];
1047                 int i = 0;
1048                 while ((i = is.read (temp)) > 0){
1049                     fos.write (temp, 0, i);
1050                 }
1051                 fos.close ();
1052                 is.close ();
1053                 bRet = true;
1054             } catch (IOException e){
1055                 e.printStackTrace ();
1056             }
1057             return bRet;
1058         }
1059     }
1060     
1061     public class ResultChecker {
1062         public static final int RESULT_INVALID_PARAM = 0;
1063         public static final int RESULT_CHECK_SIGN_FAILED = 1;
1064         public static final int RESULT_CHECK_SIGN_SUCCEED = 2;
1065         String mContent;
1066         
1067         
1068         public ResultChecker (String content){
1069             this.mContent = content;
1070         }
1071         
1072         
1073        
1074         int checkSign (){
1075             int retVal = RESULT_CHECK_SIGN_SUCCEED;
1076             try{
1077                 JSONObject objContent = BaseHelper.string2JSON (this.mContent, ";");
1078                 String result = objContent.getString ("result");
1079                 result = result.substring (1, result.length () - 1);
1080                 // 获取待签名数据
1081                 int iSignContentEnd = result.indexOf ("&sign_type=");
1082                 String signContent = result.substring (0, iSignContentEnd);
1083                 // 获取签名
1084                 JSONObject objResult = BaseHelper.string2JSON (result, "&");
1085                 String signType = objResult.getString ("sign_type");
1086                 signType = signType.replace (""", "");
1087                 String sign = objResult.getString ("sign");
1088                 sign = sign.replace (""", "");
1089                 // 进行验签 返回验签结果
1090                 if (signType.equalsIgnoreCase ("RSA")){
1091                     if (!Rsa.doCheck (signContent, sign, PartnerConfig.RSA_ALIPAY_PUBLIC))
1092                         retVal = RESULT_CHECK_SIGN_FAILED;
1093                 }
1094             } catch (Exception e){
1095                 retVal = RESULT_INVALID_PARAM;
1096                 e.printStackTrace ();
1097             }
1098             return retVal;
1099         }
1100     }
1101     
1102     public static class Rsa {
1103         public static final String SIGN_ALGORITHMS = "SHA1WithRSA";
1104         
1105         
1106         public static String sign (String content, String privateKey){
1107             String charset = "utf-8";
1108             try{
1109                 PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec (Base64.decode (privateKey));
1110                 KeyFactory keyf = KeyFactory.getInstance ("RSA");
1111                 PrivateKey priKey = keyf.generatePrivate (priPKCS8);
1112                 java.security.Signature signature = java.security.Signature.getInstance (SIGN_ALGORITHMS);
1113                 signature.initSign (priKey);
1114                 signature.update (content.getBytes (charset));
1115                 byte[] signed = signature.sign ();
1116                 return Base64.encode (signed);
1117             } catch (Exception e){
1118                 e.printStackTrace ();
1119             }
1120             return null;
1121         }
1122         
1123         
1124         public static boolean doCheck (String content, String sign, String publicKey){
1125             try{
1126                 KeyFactory keyFactory = KeyFactory.getInstance ("RSA");
1127                 byte[] encodedKey = Base64.decode (publicKey);
1128                 PublicKey pubKey = keyFactory.generatePublic (new X509EncodedKeySpec (encodedKey));
1129                 java.security.Signature signature = java.security.Signature.getInstance (SIGN_ALGORITHMS);
1130                 signature.initVerify (pubKey);
1131                 signature.update (content.getBytes ("utf-8"));
1132                 boolean bverify = signature.verify (Base64.decode (sign));
1133                 return bverify;
1134             } catch (Exception e){
1135                 e.printStackTrace ();
1136             }
1137             return false;
1138         }
1139     }
1140 }
Fiap.java

 

posted @ 2015-05-20 15:40  壬子木  阅读(673)  评论(0)    收藏  举报