編輯:關於Android編程
如果是公司的產品,那麼也就不存在問題了,Ping++對所有支付做了一個集成。如果開發者個人想接入支付系統,這個申請過程幾乎是不大可能的。而Bmob為廣大開發人員提供的統一、正規的收費手段,讓沒有企業認證的個人開發者,也能通過支付寶和微信向用戶收費。但是有一個缺點,支持的渠道少,只支持支付寶和微信。此外,微信支付還要安裝一個插件,用戶體驗及其不好。
官方的文檔在這裡Android支付SDK
接入Bomb也很簡單,首先下載BmobPay_Sdk_V1.0.2a.zip
將Lib中的四個jar文件拷到項目中的libs目錄下,將plugin目錄中的assets拷到項目的main目錄下。如圖
聲明權限<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">
由於微信支付需要安裝它的插件,所以如果在root的設備上我們希望能夠靜默安裝,否則使用正常的安裝方式,靜默安裝需要一個權限。
在AndroidManifest.xml的Application標簽下添加以下內容,聲明組件
在您的應用程序主Activity的onCreate中調用如下方法:(Application ID在後台應用管理的 數據浏覽->應用信息->應用密鑰->Application ID)
private BmobPay bmobPay = null;
BmobPay.init(context,你的Application ID);
bmobPay = new BmobPay(MainActivity.this);
調用支付寶支付
bmobPay.pay(0.01, 某商品,這裡是商品描述, new PayListener() {
@Override
public void orderId(String s) {
orderId = s;
Toast.makeText(MainActivity.this, 訂單號: + s, Toast.LENGTH_SHORT).show();
}
@Override
public void succeed() {
Toast.makeText(MainActivity.this, 支付成功, Toast.LENGTH_SHORT).show();
}
@Override
public void fail(int i, String s) {
Toast.makeText(MainActivity.this, 支付失敗: + s, Toast.LENGTH_SHORT).show();
}
@Override
public void unknow() {
Toast.makeText(MainActivity.this, 未知, Toast.LENGTH_SHORT).show();
}
});
調用微信支付,微信支付需要安裝插件,我們首先嘗試進行靜默安裝,如果返回異常,則進行正常安裝。我們需要編寫一個工具類
public class PackageUtils {
public static String moveFileFromAssetsToSdcard(Context context, String fileName) {
return moveFileFromAssetsToSdcard(context,fileName,fileName);
}
public static String moveFileFromAssetsToSdcard(Context context, String fileName, String tempName) {
InputStream is = null;
FileOutputStream fos = null;
try {
is = context.getAssets().open(fileName);
File file = new File(Environment.getExternalStorageDirectory()
.getPath() + / + tempName);
file.createNewFile();
fos = new FileOutputStream(file);
byte[] temp = new byte[1024];
int i = 0;
while ((i = is.read(temp)) > 0) {
fos.write(temp, 0, i);
}
return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
/**
* install slient
*
* @param context
* @param filePath
* @return 0 means normal, 1 means file not exist, 2 means other exception error
*/
public static int installSlient(Context context, String filePath) {
File file = new File(filePath);
if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == null || file.length() <= 0
|| !file.exists() || !file.isFile()) {
return 1;
}
String[] args = {pm, install, -r, filePath};
ProcessBuilder processBuilder = new ProcessBuilder(args);
Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = new StringBuilder();
StringBuilder errorMsg = new StringBuilder();
int result;
try {
process = processBuilder.start();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
} catch (IOException e) {
e.printStackTrace();
result = 2;
} catch (Exception e) {
e.printStackTrace();
result = 2;
} finally {
try {
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
if (successMsg.toString().contains(Success) || successMsg.toString().contains(success)) {
result = 0;
} else {
result = 2;
}
Log.e(installSlient, successMsg: + successMsg + , ErrorMsg: + errorMsg);
return result;
}
public static void installNormal(Context context, String fileName) {
File file = new File(fileName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.parse(file:// + file),
application/vnd.android.package-archive);
context.startActivity(intent);
}
需要將assets目錄下的插件拷到文件系統中,然後調用靜默安裝方法,如果返回0,則安裝成功,否則調用正常安裝方法。我們可以在微信支付的回調函數中判斷是否安裝過插件。
bmobPay.payByWX(0.01, 某商品,這裡是商品描述, new PayListener() {
@Override
public void orderId(String s) {
orderId = s;
Toast.makeText(MainActivity.this, 訂單號: + s, Toast.LENGTH_SHORT).show();
}
@Override
public void succeed() {
Toast.makeText(MainActivity.this, 支付成功, Toast.LENGTH_SHORT).show();
}
@Override
public void fail(int i, String s) {
if (i == -3) {
Toast.makeText(MainActivity.this, 未安裝支付插件,正在准備安裝 + s, Toast.LENGTH_SHORT).show();
String tempFile = PackageUtils.moveFileFromAssetsToSdcard(MainActivity.this, BmobPayPlugin.apk);
Log.e(TAG, installFile: + tempFile);
int installResult = PackageUtils.installSlient(MainActivity.this,tempFile);
Log.e(TAG, installResult: + installResult);
if(installResult!=0){
PackageUtils.installNormal(MainActivity.this,tempFile);
}
Toast.makeText(MainActivity.this, 插件安裝成功! + s, Toast.LENGTH_SHORT).show();
return ;
}
Toast.makeText(MainActivity.this, 支付失敗: + s, Toast.LENGTH_SHORT).show();
}
@Override
public void unknow() {
Toast.makeText(MainActivity.this, 未知, Toast.LENGTH_SHORT).show();
}
});
支付過程中會生成一個訂單,該訂單開發者需要自己進行存儲,可以用該訂單號進行查詢支付狀態
bmobPay.query(orderId, new OrderQueryListener() {
@Override
public void succeed(String s) {
Toast.makeText(MainActivity.this, 查詢結果: + s, Toast.LENGTH_SHORT).show();
}
@Override
public void fail(int i, String s) {
Toast.makeText(MainActivity.this, 查詢失敗: + s, Toast.LENGTH_SHORT).show();
}
});
succeed回調說明查詢成功(並不是說支付成功),返回的status有NOTPAY和SUCCESS兩種可能,只有返回SUCCESS才說明支付成功。
支付過程中可能會返回錯誤碼,常見的錯誤碼如下
還有一點需要注意的就是
當上一次支付操作尚未完成時,如果BmobPay對象發起再次請求,PayListener會回調fail方法返回並10077錯誤碼,以免生成多個訂單
如果使用過程中出現了阻塞(比如異常強制關閉支付插件頁面,會導致一直不能再發起請求,這是小概率事件),則調用此方法進行BmobPay的重置
僅對下一次請求生效,而不是永久消除限制。
如果你想查詢訂單的詳細信息,可以使用GET請求,使用Bomb的Restful API發起查詢,返回結果是一個json字符串,詳細內容如下
效果圖
後台訂單查詢
一直以來Android性能測試一直是Android測試中一個被一部分人遺忘,有被一部分人無可奈何的東西。在絕大部分的創業公司,性能測試基本上都是被遺忘的,因為功能測試和穩
基本介紹畫廊在很多的App設計中都有,如下圖所示:該例子是我沒事的時候寫的一個小項目,具體源碼地址請訪問https://github.com/AlexSmille/Yin
(一)概述手勢是:連續觸碰的行為,比如左右上下滑動屏幕,又或者畫一些不規則的幾何圖形! Android對上述兩種手勢行為都提供了支持:Android提供手勢檢測,並為手勢
生命周期一.正常情況下生命周期如圖正常生命周期 開起activity調用onCreate() onStart() onResume(),按下返回鍵 onPause() o