Android 应用接入Bmob后台云第三方支付
概述:本篇文章是基于Android studio 开发平台,后端云Bmob服务开发的一款移动应用个人支付应用.(现在第三方支付平台都需要资格审查,需要提供营业执照等相关证明,没有供但个人开发者提供服务,bmob给个人开发者做第三方支付带来了福音)
那我们就开始我们的高端操作吧!!!
(本案例运行环境为真机运行,需安装支付宝)
一.
首先我们来注册一个账号
1. 进入Bmob官方网站
点击打开链接
2.注册一个自己的账号
3.登陆Bmob后端云,创建一个应用
4.点击自己刚刚创建的应用,进入详情页
找到设置,点击后可查看自己的APPID,将其记好,后边我们要用到它
5.填写打款信息
6.下载Bmob 支付SDK 点击打开链接,下载SDK
将下载的压缩包解压
7.打开Android studio 创建一个工程,将刚解压的文件libs下的 文件复制到app/libs下 将assets放 在app\src\main\下
如图所示:
将BmobPay_v3.2.0_170602.jar导入工程, 右键点击BmobPay_v3.2.0_170602.jar,点击Add as Library
在
Project
的build.gradle
文件中添加Bmob的maven仓库地址
,示例如下:(注意文字说明部分):buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
allprojects {
repositories {
jcenter()
//Bmob的maven仓库地址,必须填写
maven { url "https://raw.github.com/bmob/bmob-android-sdk/master" }
}
}
在
app
的
build.gradle
文件中添加
compile依赖文件
,示例如下:(
注意文字说明部分
):
android {
useLibrary 'org.apache.http.legacy'
sourceSets {
main {
jniLibs.srcDirs = ['libs']//将so文件目录指向libs目录
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.0.1'
//bmob-sdk:Bmob的android sdk包,包含了Bmob的数据存储、文件等服务,以下是最新的bmob-sdk:
//3.4.7-aar:具务必查看下面注释[1]
compile 'cn.bmob.android:bmob-sdk:3.4.7-aar'
//bmob-push:Bmob的推送包
compile 'cn.bmob.android:bmob-push:0.8'
//bmob-im:Bmob的即时通讯包,注意每个版本的im依赖特定版本的bmob-sdk,具体的依赖关系可查看下面注释[3]
compile 'cn.bmob.android:bmob-im:2.0.4'
compile 'cn.bmob.android:androidasync:2.1.6'
compile 'cn.bmob.android:bmob-sdk:3.4.6'
//注:别忘记导入3.4.6的相关依赖包[2]
//bmob-sms :Bmob单独为短信服务提供的包
compile 'cn.bmob.android:bmob-sms:1.0.1'
//如果你想应用能够兼容Android6.0,请添加此依赖(org.apache.http.legacy.jar)
compile 'cn.bmob.android:http-legacy:1.0'
compile files('libs/BmobPay_v3.2.0_170602.jar')
}
如图:
修改混淆规则在proguard-rules.pro
-libraryjars libs/BmobPay_v3.2.0_170602.jar
-keepclasseswithmembers class c.b.** { *; }
-keep interface c.b.PListener{ *; }
-keep interface c.b.QListener{ *; }
如图:
在您项目的AndroidManifest.xml中添加以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
如图:
在AndroidManifest.xml的Application标签下添加以下内容:
<activity
android:name="c.b.a.A"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name="c.b.a.B"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent" />
<activity
android:name="cn.bmob.pay.v3.act.PayAct"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent" />
如图:
8.Android 代码部分,我们定义一下布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.dreamer.neusoft.mybmobpay.MainActivity"
android:orientation="vertical">
<EditText
android:id="@+id/goodName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:layout_marginBottom="10dp"
android:hint="商品名" />
<EditText
android:id="@+id/goodDiscropte"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:layout_marginBottom="10dp"
android:hint="商品描述" />
<EditText
android:id="@+id/goodPrice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:layout_marginBottom="10dp"
android:inputType="textPersonName"
android:hint="价钱" />
<RadioGroup
android:id="@+id/type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton
android:id="@+id/alipay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:checked="true"
android:text="支付宝" />
<RadioButton
android:id="@+id/wxpay"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="微信" />
</RadioGroup>
<Button
android:id="@+id/pay"
style="@android:style/Widget.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:text="支付" />
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:text="TextView" />
</LinearLayout>
效果如图:
在你的应用程序主Activity的onCreate中调用如下方法:
(Application ID在后台应用管理的 数据浏览->应用信息->应用密钥->Application ID)就是我们上面看到的那个APPID
支付实现:
1.初始化BmobPay对象,可支付时在初始化
BP.init(APPID);
2.选择支付方式: 第4个参数, true为支付宝支付,false为微信支付
BP.pay("商品名称", "商品描述", 0.02, true, new Plistener(){...});
代码实现:MainActivity
package com.dreamer.neusoft.mybmobpay;
import android.Manifest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import c.b.BP;
import c.b.PListener;
public class MainActivity extends Activity {
ProgressDialog dialog;
private EditText goodName,goodPrice,gooddisprice;
private String name,dis;
double price;
private Button pay;
private TextView tv;
private RadioGroup type;
private final static String APPKEY="你的APPID";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inilite();
pay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
name=goodName.getText().toString();
price=Double.parseDouble(goodPrice.getText().toString());
dis=gooddisprice.getText().toString();
if (type.getCheckedRadioButtonId() == R.id.alipay) // 当选择的是支付宝支付时
pay(true);
else // 调用插件用微信支付
pay(false);
}
});
}
private void inilite() {
goodName=(EditText) findViewById(R.id.goodName);
goodPrice=(EditText) findViewById(R.id.goodPrice);
gooddisprice=(EditText) findViewById(R.id.goodDiscropte);
pay=(Button) findViewById(R.id.pay);
tv=(TextView)findViewById(R.id.tv);
type = (RadioGroup) findViewById(R.id.type);
BP.init(APPKEY);
}
private void pay(boolean type) {
if (type) {
if (!checkPackageInstalled("com.eg.android.AlipayGphone",
"https://www.alipay.com")) { // 支付宝支付要求用户已经安装支付宝客户端
Toast.makeText(MainActivity.this, "请安装支付宝客户端", Toast.LENGTH_SHORT)
.show();
return;
}
} else {
if (checkPackageInstalled("com.tencent.mm", "http://weixin.qq.com")) {// 需要用微信支付时,要安装微信客户端,然后需要插件
// 有微信客户端,看看有无微信支付插件,170602更新了插件,这里可检查可不检查
if (!BP.isAppUpToDate(this, "cn.bmob.knowledge", 8)){
Toast.makeText(
MainActivity.this,
"监测到本机的支付插件不是最新版,最好进行更新,请先更新插件(无流量消耗)",
Toast.LENGTH_SHORT).show();
installApk("bp.db");
return;
}
} else {// 没有安装微信
Toast.makeText(MainActivity.this, "请安装微信客户端", Toast.LENGTH_SHORT).show();
return;
}
}
BP.pay(name, dis, price, type, new PListener() {
// 因为网络等原因,支付结果未知(小概率事件),出于保险起见稍后手动查询
@Override
public void unknow() {
Toast.makeText(MainActivity.this, "支付结果未知,请稍后手动查询", Toast.LENGTH_SHORT)
.show();
tv.append(name + "'s pay status is unknow\n\n");
hideDialog();
}
// 支付成功,如果金额较大请手动查询确认
@Override
public void succeed() {
Toast.makeText(MainActivity.this, "支付成功!", Toast.LENGTH_SHORT).show();
tv.append(name + "'s pay status is success\n\n");
hideDialog();
}
// 无论成功与否,返回订单号
@Override
public void orderId(String orderId) {
// 此处应该保存订单号,比如保存进数据库等,以便以后查询
tv.append(name + "'s orderid is " + orderId + "\n\n");
showDialog("获取订单成功!请等待跳转到支付页面~");
}
// 支付失败,原因可能是用户中断支付操作,也可能是网络原因
@Override
public void fail(int code, String reason) {
// 当code为-2,意味着用户中断了操作
// code为-3意味着没有安装BmobPlugin插件
if (code == -3) {
Toast.makeText(
MainActivity.this,
"监测到你尚未安装支付插件,无法进行支付,请先安装插件(已打包在本地,无流量消耗),安装结束后重新支付",
Toast.LENGTH_SHORT).show();
// installBmobPayPlugin("bp.db");
installApk("bp.db");
} else {
Toast.makeText(MainActivity.this, "支付中断!", Toast.LENGTH_SHORT)
.show();
}
tv.append(name + "'s pay status is fail, error code is \n"
+ code + " ,reason is " + reason + "\n\n");
hideDialog();
}
});
}
void showDialog(String message) {
try {
if (dialog == null) {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
}
dialog.setMessage(message);
dialog.show();
} catch (Exception e) {
// 在其他线程调用dialog会报错
}
}
void hideDialog() {
if (dialog != null && dialog.isShowing())
try {
dialog.dismiss();
} catch (Exception e) {
}
}
private static final int REQUESTPERMISSION = 101;
private void installApk(String s) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//申请权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUESTPERMISSION);
} else {
installBmobPayPlugin(s);
}
}
void installBmobPayPlugin(String fileName) {
try {
InputStream is = getAssets().open(fileName);
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + fileName + ".apk");
if (file.exists())
file.delete();
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
byte[] temp = new byte[1024];
int i = 0;
while ((i = is.read(temp)) > 0) {
fos.write(temp, 0, i);
}
fos.close();
is.close();
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");
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 检查某包名应用是否已经安装
*
* @param packageName 包名
* @param browserUrl 如果没有应用市场,去官网下载
* @return
*/
private boolean checkPackageInstalled(String packageName, String browserUrl) {
try {
// 检查是否有支付宝客户端
getPackageManager().getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
// 没有安装支付宝,跳转到应用市场
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id=" + packageName));
startActivity(intent);
} catch (Exception ee) {// 连应用市场都没有,用浏览器去支付宝官网下载
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(browserUrl));
startActivity(intent);
} catch (Exception eee) {
Toast.makeText(MainActivity.this,
"您的手机上没有没有应用市场也没有浏览器,我也是醉了,你去想办法安装支付宝/微信吧",
Toast.LENGTH_SHORT).show();
}
}
}
return false;
}
}
到此我们的Bmob 第三方支付就完成了:
效果图如下: