編輯:關於Android編程
參考安卓Dialog源碼,他的builder設計模式實現方式是,使用內部類來實現功能,外部類的作用是通過build()函數,來對內部類進行參數設置,例如setter方法。
Buidler設計模式它一般用於用戶不知道內部構建細節的情況下更加精細地控制對象構建流程,例如安卓系統的AlertDialog類,它包括了icon、title、msg、button1、button2等,這些裝配的部分是比較多的,代碼實現過程也較為漫長。使用Builder模式,可以使得這些調用變得簡單,在構建過程各個部件可以自由擴展,以及重新設置參數。
首先集成支付寶SDK
下載地址:https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1
下載完成後,把壓縮包解壓,在下圖的路徑下找到這個jar文件,並把它引入到項目中。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160707/20160707091159988.png" title="\" />
然後把demo中的三個java文件復制到項目中,它們是:Base64.java、PayResult.java、SignUtils.java。
筆者參考AlerDialog的類源碼,對支付寶支付的過程進行一個Builder設計模式封裝。你可以支付復制拿去用,立刻完成支付功能。其AliPay.java代碼如下:
public class AliPay {
public static class Builder {
private Activity mActivity;
public Builder(Activity activity) {
this.mActivity = activity;
}
/**
* 設置商戶PID
*/
private String PARTNER = "";
// 商戶收款賬號
private String SELLER = "";
// 商戶私鑰,pkcs8格式
private String RSA_PRIVATE = "";
// 支付寶公鑰
private String RSA_PUBLIC = "";
private int SDK_PAY_FLAG = 6406;
private String orderTitle = "";
private String subTitle = "";
private String price = "";
private String notifyURL = "";
/**
* 設置商戶PID
*/
public AliPay.Builder setPARTNER(String PARTNER) {
this.PARTNER = PARTNER;
return this;
}
/**
* 設置商戶收款賬號
*/
public AliPay.Builder setSELLER(String SELLER) {
this.SELLER = SELLER;
return this;
}
/**
* 設置商戶私鑰,pkcs8格式
*/
public AliPay.Builder setRSA_PRIVATE(String RSA_PRIVATE) {
this.RSA_PRIVATE = RSA_PRIVATE;
return this;
}
/**
* 設置支付寶公鑰
*/
public AliPay.Builder setRSA_PUBLIC(String RSA_PUBLIC) {
this.RSA_PUBLIC = RSA_PUBLIC;
return this;
}
/**
* 設置商品名稱
*/
public AliPay.Builder setOrderTitle(String orderTitle) {
this.orderTitle = orderTitle;
return this;
}
/**
* 設置商品詳情
*/
public AliPay.Builder setSubTitle(String subTitle) {
this.subTitle = subTitle;
return this;
}
/**
* 設置商品價格
*/
public AliPay.Builder setPrice(String price) {
this.price = price;
return this;
}
/**
* 設置支付寶支付成功後通知的地址,可以填寫你公司的地址
*/
public AliPay.Builder setNotifyURL(String notifyURL) {
this.notifyURL = notifyURL;
return this;
}
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case 6406: {
PayResult payResult = new PayResult((String) msg.obj);
/**
* 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/
* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
* docType=1) 建議商戶依賴異步通知
*/
String resultInfo = payResult.getResult();// 同步返回需要驗證的信息
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
if (TextUtils.equals(resultStatus, "9000")) {
if (mPayCallBackListener != null) {
mPayCallBackListener.onPayCallBack(9000, "9000", "支付成功");
}
} else {
// 判斷resultStatus 為非"9000"則代表可能支付失敗
// "8000"代表支付結果因為支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知為准(小概率狀態)
if (TextUtils.equals(resultStatus, "8000")) {
if (mPayCallBackListener != null) {
mPayCallBackListener.onPayCallBack(8000, "8000", "支付結果確認中");
}
} else {
// 其他值就可以判斷為支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
if (mPayCallBackListener != null) {
mPayCallBackListener.onPayCallBack(0, "0", "支付失敗");
}
}
}
break;
}
default:
break;
}
}
};
public void pay() {
if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) {
new AlertDialog.Builder(mActivity).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialoginterface, int i) {
//
mActivity.finish();
}
}).show();
return;
}
String orderInfo = getOrderInfo(orderTitle, subTitle, price, notifyURL);
/**
* 特別注意,這裡的簽名邏輯需要放在服務端,切勿將私鑰洩露在代碼中!
*/
String sign = sign(orderInfo);
try {
/**
* 僅需對sign 做URL編碼
*/
sign = URLEncoder.encode(sign, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
/**
* 完整的符合支付寶參數規范的訂單信息
*/
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 構造PayTask 對象
PayTask alipay = new PayTask(mActivity);
// 調用支付接口,獲取支付結果
String result = alipay.pay(payInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必須異步調用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
public void setPayCallBackListener(PayCallBackListener listener) {
this.mPayCallBackListener = listener;
}
private PayCallBackListener mPayCallBackListener;
public interface PayCallBackListener {
void onPayCallBack(int status, String resultStatus, String progress);
}
/**
* 創建訂單信息
*/
private String getOrderInfo(String subject, String body, String price, String notifyURL) {
// 簽約合作者身份ID
String orderInfo = "partner=" + "\"" + PARTNER + "\"";
// 簽約賣家支付寶賬號
orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
// 商戶網站唯一訂單號
orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
// 商品名稱
orderInfo += "&subject=" + "\"" + subject + "\"";
// 商品詳情
orderInfo += "&body=" + "\"" + body + "\"";
// 商品金額
orderInfo += "&total_fee=" + "\"" + price + "\"";
// 服務器異步通知頁面路徑
orderInfo += "¬ify_url=" + "\"" + notifyURL + "\"";
// 服務接口名稱, 固定值
orderInfo += "&service=\"mobile.securitypay.pay\"";
// 支付類型, 固定值
orderInfo += "&payment_type=\"1\"";
// 參數編碼, 固定值
orderInfo += "&_input_charset=\"utf-8\"";
// 設置未付款交易的超時時間
// 默認30分鐘,一旦超時,該筆交易就會自動被關閉。
// 取值范圍:1m~15d。
// m-分鐘,h-小時,d-天,1c-當天(無論交易何時創建,都在0點關閉)。
// 該參數數值不接受小數點,如1.5h,可轉換為90m。
orderInfo += "&it_b_pay=\"30m\"";
// extern_token為經過快登授權獲取到的alipay_open_id,帶上此參數用戶將使用授權的賬戶進行支付
// orderInfo += "&extern_token=" + "\"" + extern_token + "\"";
// 支付寶處理完請求後,當前頁面跳轉到商戶指定頁面的路徑,可空
orderInfo += "&return_url=\"m.alipay.com\"";
// 調用銀行卡支付,需配置此參數,參與簽名, 固定值 (需要簽約《無線銀行卡快捷支付》才能使用)
// orderInfo += "&paymethod=\"expressGateway\"";
return orderInfo;
}
/**
* 生成商戶訂單號,該值在商戶端應保持唯一(可自定義格式規范)
*/
private String getOutTradeNo() {
SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
Date date = new Date();
String key = format.format(date);
Random r = new Random();
key = key + r.nextInt();
key = key.substring(0, 15);
return key;
}
/**
* sign the order info. 對訂單信息進行簽名
*
* @param content 待簽名訂單信息
*/
private String sign(String content) {
return SignUtils.sign(content, RSA_PRIVATE);
}
/**
* 獲取簽名方式
*/
private String getSignType() {
return "sign_type=\"RSA\"";
}
}
// 商戶PID
private String PARTNER="";
// 商戶收款賬號
private String SELLER="";
// 商戶私鑰,pkcs8格式
private String RSA_PRIVATE="";
// 支付寶公鑰
private String RSA_PUBLIC="";
private String orderTitle="";
private String subTitle="";
private String price="";
private String notifyURL="";
private Builder payData;
public Builder build(Activity activity) {
payData = new Builder(activity);
payData.setPARTNER(PARTNER);
payData.setSELLER(SELLER);
payData.setRSA_PRIVATE(RSA_PRIVATE);
payData.setRSA_PUBLIC(RSA_PUBLIC);
payData.setOrderTitle(orderTitle);
payData.setSubTitle(subTitle);
payData.setPrice(price);
payData.setNotifyURL(notifyURL);
return payData;
}
public AliPay setPARTNER(String PARTNER) {
this.PARTNER = PARTNER;
return this;
}
public AliPay setSELLER(String SELLER) {
this.SELLER = SELLER;
return this;
}
public AliPay setRSA_PRIVATE(String RSA_PRIVATE) {
this.RSA_PRIVATE = RSA_PRIVATE;
return this;
}
public AliPay setRSA_PUBLIC(String RSA_PUBLIC) {
this.RSA_PUBLIC = RSA_PUBLIC;
return this;
}
public AliPay setOrderTitle(String orderTitle) {
this.orderTitle = orderTitle;
return this;
}
public AliPay setSubTitle(String subTitle) {
this.subTitle = subTitle;
return this;
}
public AliPay setPrice(String price) {
this.price = price;
return this;
}
public AliPay setNotifyURL(String notifyURL) {
this.notifyURL = notifyURL;
return this;
}
public void pay() {
if (payData != null) {
payData.pay();
}
}
}
它會有一個回調狀態處理,調用setPayCallBackListener即可得到。
私鑰或公鑰的生成,支付寶已經在demo文件夾中提供了工具。
RSA密鑰生成命令
生成RSA私鑰
genrsa -out rsa_private_key.pem 1024
生成RSA公鑰
openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
將RSA私鑰轉換成PKCS8格式
openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
然後,將生成的公鑰上傳到支付寶商戶賬戶中,具體文檔在下面連接中:
https://doc.open.alipay.com/doc2/detail.htm?treeId=58&articleId=103578&docType=1
將私鑰PKCS8格式保存在代碼中,
到這裡你已經可以完成支付寶支付功能,很簡單吧。筆者繼續研究微信支付…
上篇分析AsyncTask的一些基本用法以及不同android版本下的區別,接著本篇我們就來全面剖析一下AsyncTask的工作原理。在開始之前我們先來了解一個多線程的知
ListView是每個app中都要使用的,所以今天我來總結下ListView的使用和一些簡單的優化。先看下運行效果:一、創建數據庫為了模擬數據,這裡將數據保存數據庫中,順
先給大家展示下效果圖,如果感覺不錯,請參考實現思路:我們要實現一個自定義的再一個圓形中繪制一個弧形的自定義View,思路是這樣的: 先要創建一個類ProgressVie
一、問題描述Android應用中經常涉及從網絡中加載大量圖片,為提升加載速度和效率,減少網絡流量都會采用二級緩存和異步加載機制,所謂二級緩存就是通過先從內存中獲取、再從文