Compare commits
3 Commits
dev/app_1_
...
molistar/g
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1b7e8dd8e8 | ||
![]() |
13baa2746d | ||
![]() |
3a9c338df6 |
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[submodule "modules/module_google"]
|
||||
path = modules/module_google
|
||||
url = https://e.coding.net/chwllive/peko/peko-android-gms.git
|
||||
branch = molistar
|
@@ -325,7 +325,9 @@ public class App extends BaseApp {
|
||||
BasicConfig.INSTANCE.setVoiceDir(Constants.VOICE_DIR);
|
||||
BasicConfig.INSTANCE.setCacheDir(Constants.CACHE_DIR);
|
||||
BasicConfig.INSTANCE.setImageDir(Constants.IMAGE_CACHE_DIR);
|
||||
com.example.lib_utils.log.LogUtil.INSTANCE.setConsolePrinterEnabled(BuildConfig.DEBUG);
|
||||
// TODO 临时调整
|
||||
com.example.lib_utils.log.LogUtil.INSTANCE.setConsolePrinterEnabled(true);
|
||||
// com.example.lib_utils.log.LogUtil.INSTANCE.setConsolePrinterEnabled(BuildConfig.DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -84,11 +84,12 @@ class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.
|
||||
binding.tvLanugage.setOnClickListener(this)
|
||||
binding.rlyPayPwd.setOnClickListener(this)
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
// TODO 临时调整
|
||||
// if (BuildConfig.DEBUG) {
|
||||
binding.titleBar.setOnTitleClickListener {
|
||||
debug()
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
@@ -222,8 +223,8 @@ class SettingActivity : BaseViewBindingActivity<ActivitySettingBinding>(), View.
|
||||
}
|
||||
|
||||
private fun debug() {
|
||||
startActivity(Intent(this, DebugActivity::class.java))
|
||||
// CommonWebViewActivity.start(this,"https://api.molistar.xyz/molistar/activity/2024-invitationFission/index.html")
|
||||
// startActivity(Intent(this, DebugActivity::class.java))
|
||||
CommonWebViewActivity.start(this,"http://beta.api.molistar.xyz/molistar/modules/order/index.html")
|
||||
// PublicChatRoomMessageActivity.start(this)
|
||||
// MyDecorationActivity.start(this,0)
|
||||
}
|
||||
|
@@ -0,0 +1,221 @@
|
||||
package com.chwl.app.ui.wallet.payment
|
||||
|
||||
import android.app.Activity
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.chwl.app.R
|
||||
import com.chwl.app.common.widget.dialog.DialogManager
|
||||
import com.chwl.core.pay.PayModel
|
||||
import com.chwl.core.pay.bean.PayRecordId
|
||||
import com.chwl.library.utils.SingleToastUtil
|
||||
import com.example.lib_utils.log.ILog
|
||||
import com.example.module_base.support.billing.IBillingResult
|
||||
import com.example.module_base.support.billing.IBillingService
|
||||
import com.example.module_base.support.billing.IProductDetails
|
||||
import com.example.module_base.support.billing.IPurchase
|
||||
import com.example.module_base.support.google.IGoogleService
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
|
||||
class GPaymentClient(val activity: Activity) : IPaymentClient, IBillingService.Listener,
|
||||
IBillingService.ProductDetailsResponseListener, LifecycleEventObserver, ILog {
|
||||
|
||||
private var compositeDisposable: CompositeDisposable? = null
|
||||
private var _billingService: IBillingService? = null
|
||||
private val dialogManager = DialogManager(activity)
|
||||
|
||||
private var paymentIntent: PaymentIntent? = null
|
||||
private var productItem: IProductDetails? = null
|
||||
private var orderId: String? = null
|
||||
|
||||
init {
|
||||
dialogManager.setCanceledOnClickOutside(false)
|
||||
dialogManager.setCanceledOnClickBackKey(false)
|
||||
(activity as? LifecycleOwner)?.lifecycle?.addObserver(this)
|
||||
}
|
||||
|
||||
private fun getBillingService(): IBillingService? {
|
||||
if (_billingService == null) {
|
||||
_billingService = IGoogleService.newBillingService(activity, this)
|
||||
}
|
||||
return _billingService
|
||||
}
|
||||
|
||||
override fun launchPayment(intent: PaymentIntent) {
|
||||
logD("launchPayment() intent:${intent.productId}")
|
||||
if (paymentIntent != null) {
|
||||
SingleToastUtil.showToast(R.string.avroom_activity_roomblacklistactivity_015)
|
||||
return
|
||||
}
|
||||
dialogManager.showProgressDialog(activity)
|
||||
this.paymentIntent = intent
|
||||
tryLaunch()
|
||||
}
|
||||
|
||||
private fun tryLaunch() {
|
||||
val productId = paymentIntent?.productId
|
||||
val productItem = productItem
|
||||
logD("tryLaunch() productId:$productId productItem:$productItem")
|
||||
if (productId == null) {
|
||||
return
|
||||
}
|
||||
if (getBillingService()?.isServiceConnected() != true) {
|
||||
logD("tryLaunch() isServiceConnected = false")
|
||||
return
|
||||
}
|
||||
if (productItem == null) {
|
||||
getBillingService()?.querySkuDetailsAsync(listOf(productId), this)
|
||||
} else {
|
||||
placeOrder(productItem)
|
||||
}
|
||||
}
|
||||
|
||||
private fun placeOrder(productItem: IProductDetails) {
|
||||
logD("placeOrder() productItem:${productItem.getProductId()}")
|
||||
addDisposable(PayModel.get().placeOrder(productItem.getProductId())
|
||||
.subscribe(
|
||||
{ recordId: PayRecordId ->
|
||||
if (paymentIntent?.productId == productItem.getProductId()) {
|
||||
orderId = recordId.recordId
|
||||
getBillingService()?.initiatePurchaseFlow(
|
||||
productItem,
|
||||
recordId.recordId
|
||||
)
|
||||
} else {
|
||||
logE("placeOrder() 意图发生改变")
|
||||
}
|
||||
}
|
||||
) { throwable: Throwable ->
|
||||
callFailed(IPaymentClient.CODE_PLACE_ORDER_FAILED, throwable)
|
||||
})
|
||||
}
|
||||
|
||||
override fun onBillingClientSetupFinished() {
|
||||
logD("onBillingClientSetupFinished()")
|
||||
tryLaunch()
|
||||
}
|
||||
|
||||
override fun onPurchasesUpdated(purchases: List<IPurchase>) {
|
||||
logD("onPurchasesUpdated() purchases:${purchases.size}")
|
||||
purchases.forEach {
|
||||
logD("onPurchasesUpdated() item.state:${it.getPurchaseState()}")
|
||||
logD("onPurchasesUpdated() item.orderId:${it.getOrderId()}")
|
||||
logD("onPurchasesUpdated() item.token:${it.getPurchaseToken()}")
|
||||
logD("onPurchasesUpdated() item.data:${it.getData()}")
|
||||
val identifiers = it.getAccountIdentifiers()
|
||||
if (it.isPurchasedState() && identifiers != null) {
|
||||
addDisposable(
|
||||
PayModel.get().verifyOrder(
|
||||
identifiers.getObfuscatedAccountId(),
|
||||
it.getProducts().firstOrNull(),
|
||||
it.getPackageName(),
|
||||
it.getPurchaseToken()
|
||||
).subscribe({
|
||||
getBillingService()?.consumeAsync(it)
|
||||
}, {
|
||||
callFailed(IPaymentClient.CODE_VERIFY_ORDER_FAILED, it)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConsumeFinished(token: String?, result: Int) {
|
||||
logD("onConsumeFinished() token:${token} result:$result")
|
||||
val orderId = orderId
|
||||
if (orderId != null) {
|
||||
callSuccess(orderId)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailedHandle(result: Int) {
|
||||
logD("onFailedHandle() result:${result}")
|
||||
callFailed(IPaymentClient.CODE_OTHER)
|
||||
}
|
||||
|
||||
override fun onProductDetailsResponse(
|
||||
billingResult: IBillingResult,
|
||||
productDetails: List<IProductDetails>
|
||||
) {
|
||||
logD("onProductDetailsResponse() billingResult:${billingResult.getResponseCode()} productDetails:${productDetails.size}")
|
||||
if (billingResult.isResponseOk()) {
|
||||
val item = productDetails.firstOrNull {
|
||||
it.getProductId() == paymentIntent?.productId
|
||||
}
|
||||
productItem = item
|
||||
if (item != null) {
|
||||
tryLaunch()
|
||||
} else {
|
||||
callFailed(IPaymentClient.CODE_NOT_FOUND)
|
||||
}
|
||||
} else {
|
||||
callFailed(IPaymentClient.CODE_NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
private fun callSuccess(orderRecordId: String) {
|
||||
logD("callSuccess() orderRecordId:${orderRecordId} productId:${paymentIntent?.productId}")
|
||||
paymentIntent?.let {
|
||||
it.listener.onResponse(PaymentResult.PaymentSuccess(it.productId, orderRecordId))
|
||||
}
|
||||
paymentIntent = null
|
||||
dialogManager.dismissDialog()
|
||||
}
|
||||
|
||||
private fun callFailed(code: Int, throwable: Throwable? = null) {
|
||||
throwable?.printStackTrace()
|
||||
logD("callFailed() code:${code} throwable:${throwable?.message}")
|
||||
throwable?.let {
|
||||
SingleToastUtil.showToast(
|
||||
it.message
|
||||
)
|
||||
}
|
||||
paymentIntent?.let {
|
||||
it.listener.onResponse(PaymentResult.PaymentFailed(it.productId, code, throwable))
|
||||
}
|
||||
paymentIntent = null
|
||||
dialogManager.dismissDialog()
|
||||
}
|
||||
|
||||
private fun getCompositeDisposable(): CompositeDisposable {
|
||||
var disposable = compositeDisposable
|
||||
if (disposable == null) {
|
||||
disposable = CompositeDisposable()
|
||||
compositeDisposable = disposable
|
||||
}
|
||||
return disposable
|
||||
}
|
||||
|
||||
private fun addDisposable(disposable: Disposable) {
|
||||
getCompositeDisposable().add(disposable)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
logD("onCleared()")
|
||||
paymentIntent = null
|
||||
compositeDisposable?.dispose()
|
||||
compositeDisposable = null
|
||||
dialogManager.dismissDialog()
|
||||
}
|
||||
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||
logD("onStateChanged() event:$event")
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_RESUME -> {
|
||||
if (_billingService?.isServiceConnected() == true) {
|
||||
_billingService?.onQueryPurchases()
|
||||
}
|
||||
}
|
||||
|
||||
Lifecycle.Event.ON_DESTROY -> {
|
||||
(activity as? LifecycleOwner)?.lifecycle?.removeObserver(this)
|
||||
onCleared()
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package com.chwl.app.ui.wallet.payment
|
||||
|
||||
import com.example.lib_utils.ICleared
|
||||
|
||||
interface IPaymentClient : ICleared {
|
||||
companion object {
|
||||
// 支付成功
|
||||
const val CODE_SUCCESS = 200
|
||||
|
||||
// 未知异常原因
|
||||
const val CODE_OTHER = 0
|
||||
|
||||
// 服务不可用
|
||||
const val CODE_UNAVAILABLE = 1
|
||||
|
||||
// 查询订单信息失败
|
||||
const val CODE_NOT_FOUND = 2
|
||||
|
||||
// 预下单失败
|
||||
const val CODE_PLACE_ORDER_FAILED = 3
|
||||
|
||||
// 验证订单失败
|
||||
const val CODE_VERIFY_ORDER_FAILED = 4
|
||||
}
|
||||
|
||||
fun launchPayment(intent: PaymentIntent)
|
||||
|
||||
override fun onCleared()
|
||||
|
||||
interface Listener {
|
||||
fun onResponse(result: PaymentResult)
|
||||
}
|
||||
}
|
@@ -0,0 +1,4 @@
|
||||
package com.chwl.app.ui.wallet.payment
|
||||
|
||||
class PaymentIntent(val productId: String, val listener: IPaymentClient.Listener) {
|
||||
}
|
@@ -0,0 +1,12 @@
|
||||
package com.chwl.app.ui.wallet.payment
|
||||
|
||||
sealed class PaymentResult {
|
||||
|
||||
data class PaymentSuccess(val productId: String, val orderId: String) : PaymentResult()
|
||||
|
||||
data class PaymentFailed(
|
||||
val productId: String,
|
||||
val code: Int,
|
||||
val exception: Throwable? = null
|
||||
) : PaymentResult()
|
||||
}
|
@@ -91,6 +91,8 @@ public class CommonWebViewActivity extends BaseActivity {
|
||||
private static final String POSITION = "position";
|
||||
private int mPosition;
|
||||
|
||||
private JSInterface jsInterface;
|
||||
|
||||
public static void start(Context context, String url) {
|
||||
Intent intent = new Intent(context, CommonWebViewActivity.class);
|
||||
intent.putExtra("url", url);
|
||||
@@ -194,7 +196,7 @@ public class CommonWebViewActivity extends BaseActivity {
|
||||
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
}
|
||||
webView.getSettings().setTextZoom(100);
|
||||
JSInterface jsInterface = new JSInterface(webView, this);
|
||||
jsInterface = new JSInterface(webView, this);
|
||||
jsInterface.setPosition(mPosition);
|
||||
webView.addJavascriptInterface(jsInterface, "androidJsObj");
|
||||
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||
@@ -441,6 +443,9 @@ public class CommonWebViewActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (jsInterface != null) {
|
||||
jsInterface.onCleared();
|
||||
}
|
||||
EventBus.getDefault().unregister(this);
|
||||
|
||||
if (webViewCallBack != null) {
|
||||
|
@@ -1,8 +1,6 @@
|
||||
package com.chwl.app.ui.webview;
|
||||
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Build;
|
||||
import android.text.TextUtils;
|
||||
@@ -16,7 +14,6 @@ import androidx.appcompat.app.AlertDialog;
|
||||
import com.orhanobut.logger.Logger;
|
||||
import com.chwl.app.R;
|
||||
import com.chwl.app.base.BaseBindingFragment;
|
||||
import com.chwl.app.common.widget.dialog.BaseAlertDialogBuilder;
|
||||
import com.chwl.app.databinding.FragmentCommonWebViewBinding;
|
||||
import com.chwl.library.annatation.ActLayoutRes;
|
||||
import com.chwl.library.utils.ResUtil;
|
||||
@@ -26,6 +23,7 @@ public class CommonWebViewFragment extends BaseBindingFragment<FragmentCommonWeb
|
||||
|
||||
private WebView webView;
|
||||
protected String url;
|
||||
private JSInterface jsInterface;
|
||||
|
||||
@Override
|
||||
public void initiate() {
|
||||
@@ -37,7 +35,7 @@ public class CommonWebViewFragment extends BaseBindingFragment<FragmentCommonWeb
|
||||
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
|
||||
}
|
||||
webView.getSettings().setTextZoom(100);
|
||||
JSInterface jsInterface = new JSInterface(webView, getActivity());
|
||||
jsInterface = new JSInterface(webView, getActivity());
|
||||
webView.addJavascriptInterface(jsInterface, "androidJsObj");
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
|
||||
@@ -113,4 +111,12 @@ public class CommonWebViewFragment extends BaseBindingFragment<FragmentCommonWeb
|
||||
ShowWebView(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (jsInterface != null) {
|
||||
jsInterface.onCleared();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -14,13 +14,21 @@ import android.util.Log;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.chwl.app.earn.activity.EarnRecordActivity;
|
||||
import com.chwl.app.ui.invite.InviteImageHelper;
|
||||
import com.chwl.app.ui.invite.ShareInviteDialog;
|
||||
import com.chwl.app.ui.invite.ShareInviteInfo;
|
||||
import com.chwl.app.ui.wallet.payment.GPaymentClient;
|
||||
import com.chwl.app.ui.wallet.payment.IPaymentClient;
|
||||
import com.chwl.app.ui.wallet.payment.PaymentIntent;
|
||||
import com.chwl.app.ui.wallet.payment.PaymentResult;
|
||||
import com.chwl.library.language.LanguageHelper;
|
||||
import com.chwl.library.utils.json.JsonUtils;
|
||||
import com.example.lib_utils.ICleared;
|
||||
import com.google.gson.Gson;
|
||||
import com.netease.nim.uikit.common.util.log.LogUtil;
|
||||
import com.orhanobut.logger.Logger;
|
||||
@@ -66,7 +74,7 @@ import java.util.HashMap;
|
||||
* <p> html js 与webview 交互接口</p>
|
||||
* Created by ${user} on 2017/11/6.
|
||||
*/
|
||||
public class JSInterface {
|
||||
public class JSInterface implements ICleared {
|
||||
private static final String TAG = JSInterface.class.getSimpleName();
|
||||
private WebView mWebView;
|
||||
private CommonWebViewActivity mActivity;
|
||||
@@ -75,6 +83,7 @@ public class JSInterface {
|
||||
private MediaRecorder recorder;
|
||||
private File myRecAudioFile;
|
||||
private ExtAudioRecorder extAudioRecorder;
|
||||
private GPaymentClient paymentClient;
|
||||
|
||||
public JSInterface(WebView webView, CommonWebViewActivity activity) {
|
||||
mWebView = webView;
|
||||
@@ -87,6 +96,68 @@ public class JSInterface {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private void loadUrl(String url) {
|
||||
com.example.lib_utils.log.LogUtil.d("JSInterface", "loadUrl url:" + url, false);
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
if (mWebView != null) {
|
||||
mWebView.loadUrl(url);
|
||||
}
|
||||
} else {
|
||||
if (mActivity != null) {
|
||||
mActivity.runOnUiThread(() -> {
|
||||
if (mWebView != null) {
|
||||
mWebView.loadUrl(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void callJsWithJson(String name, Object params) {
|
||||
if (name == null) {
|
||||
return;
|
||||
}
|
||||
if (params != null) {
|
||||
String jsonStr = JsonUtils.toJson(params);
|
||||
loadUrl("javascript:" + name + "(" + jsonStr + ")");
|
||||
} else {
|
||||
loadUrl("javascript:" + name + "()");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 拉起本地支付
|
||||
*/
|
||||
@JavascriptInterface
|
||||
public void openPayment(String productId) {
|
||||
com.example.lib_utils.log.LogUtil.d("JSInterface", "openPayment productId:" + productId, false);
|
||||
if (mActivity == null || TextUtils.isEmpty(productId)) {
|
||||
return;
|
||||
}
|
||||
mActivity.runOnUiThread(() -> {
|
||||
if (paymentClient == null) {
|
||||
paymentClient = new GPaymentClient(mActivity);
|
||||
}
|
||||
PaymentIntent paymentIntent = new PaymentIntent(productId, new IPaymentClient.Listener() {
|
||||
@Override
|
||||
public void onResponse(@NonNull PaymentResult result) {
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
if (result instanceof PaymentResult.PaymentSuccess) {
|
||||
map.put("orderId", ((PaymentResult.PaymentSuccess) result).getOrderId());
|
||||
map.put("productId", ((PaymentResult.PaymentSuccess) result).getProductId());
|
||||
map.put("code", 200);
|
||||
} else if (result instanceof PaymentResult.PaymentFailed) {
|
||||
map.put("code", ((PaymentResult.PaymentFailed) result).getCode());
|
||||
map.put("productId", ((PaymentResult.PaymentFailed) result).getProductId());
|
||||
}
|
||||
callJsWithJson("openPaymentCallback", map);
|
||||
}
|
||||
});
|
||||
paymentClient.launchPayment(paymentIntent);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 调转个人主页
|
||||
*
|
||||
@@ -122,7 +193,7 @@ public class JSInterface {
|
||||
map.put(IReportConstants.MODULE, IReportConstants.MOLISTAR_PAY);
|
||||
ReportManager.get().reportEvent(IReportConstants.PAYPAGE_SHOW, map);
|
||||
// if (AppMetaDataUtil.getChannelID().equals(Constants.GOOGLE)) {
|
||||
ChargeActivity.start(context);
|
||||
ChargeActivity.start(context);
|
||||
// } else {
|
||||
// CommonWebViewActivity.start(
|
||||
// context, UriProvider.getOfficialPay(
|
||||
@@ -175,7 +246,7 @@ public class JSInterface {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
ShareInviteInfo info = new Gson().fromJson(json,ShareInviteInfo.class);
|
||||
ShareInviteInfo info = new Gson().fromJson(json, ShareInviteInfo.class);
|
||||
if (info.getType() != null) {
|
||||
if (info.getType() == 1) {
|
||||
activity.runOnUiThread(() -> {
|
||||
@@ -556,4 +627,12 @@ public class JSInterface {
|
||||
PraiseModel.get().praise(Long.parseLong(uid), true).subscribe();
|
||||
NimP2PMessageActivity.start(context, uid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCleared() {
|
||||
ICleared.super.onCleared();
|
||||
if (paymentClient != null) {
|
||||
paymentClient.onCleared();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
modules/module_google
Submodule
1
modules/module_google
Submodule
Submodule modules/module_google added at e9dbdb3637
Reference in New Issue
Block a user