4
4
5
5
import android .app .Activity ;
6
6
import android .app .AlertDialog ;
7
- import android .app .Instrumentation ;
8
7
import android .content .Context ;
9
8
import android .content .res .ColorStateList ;
10
9
import android .graphics .Color ;
11
10
import android .graphics .Rect ;
11
+ import android .os .Build ;
12
12
import android .os .Bundle ;
13
13
import android .text .TextUtils ;
14
14
import android .util .TypedValue ;
15
15
import android .view .Gravity ;
16
- import android .view .KeyEvent ;
17
16
import android .view .View ;
18
17
import android .view .ViewGroup ;
18
+ import android .view .ViewTreeObserver ;
19
19
import android .widget .AbsListView ;
20
20
import android .widget .FrameLayout ;
21
21
import android .widget .LinearLayout ;
34
34
import com .surcumference .fingerprint .plugin .inf .IMockCurrentUser ;
35
35
import com .surcumference .fingerprint .plugin .inf .OnFingerprintVerificationOKListener ;
36
36
import com .surcumference .fingerprint .util .ActivityViewObserver ;
37
+ import com .surcumference .fingerprint .util .ActivityViewObserverHolder ;
37
38
import com .surcumference .fingerprint .util .ApplicationUtils ;
38
39
import com .surcumference .fingerprint .util .BizBiometricIdentify ;
39
40
import com .surcumference .fingerprint .util .BlackListUtils ;
54
55
public class UnionPayBasePlugin implements IAppPlugin , IMockCurrentUser {
55
56
56
57
private AlertDialog mFingerPrintAlertDialog ;
57
- private boolean mPwdActivityDontShowFlag ;
58
- private int mPwdActivityReShowDelayTimeMsec ;
59
-
60
- private ActivityViewObserver mActivityViewObserver ;
61
58
private WeakHashMap <View , View .OnAttachStateChangeListener > mView2OnAttachStateChangeListenerMap = new WeakHashMap <>();
62
59
protected boolean mMockCurrentUser = false ;
63
60
protected XBiometricIdentify mFingerprintIdentify ;
@@ -114,13 +111,41 @@ public void onFailed(BizBiometricIdentify target, FingerprintIdentifyFailInfo fa
114
111
});
115
112
}
116
113
117
- public synchronized void showFingerPrintDialog (@ Nullable Activity activity , View rootView ) {
114
+ public synchronized void showFingerPrintDialog (@ Nullable Activity activity , View targetView ) {
115
+ View rootView = targetView .getRootView ();
118
116
final Context context = rootView .getContext ();
119
117
final Config config = Config .from (context );
120
118
try {
119
+ if ("true" .equals (rootView .getTag (R .id .unionpay_payview_shown ))) {
120
+ L .d ("payview already shown, skip." );
121
+ return ;
122
+ }
123
+ ViewTreeObserver .OnGlobalLayoutListener paymentMethodListener = new ViewTreeObserver .OnGlobalLayoutListener () {
124
+ @ Override
125
+ public void onGlobalLayout () {
126
+ View selectPaymentMethodView = ViewUtils .findViewByText (rootView , "选择付款方式" );
127
+ L .d ("selectPaymentMethodView" , ViewUtils .getViewInfo (selectPaymentMethodView ));
128
+ if (selectPaymentMethodView == null ) {
129
+ showFingerPrintDialog (activity , targetView );
130
+ }
131
+ }
132
+ };
133
+
134
+ //监视选择付款页面, 并保证只有一个listener
135
+ ViewTreeObserver .OnGlobalLayoutListener lastPaymentMethodListener = (ViewTreeObserver .OnGlobalLayoutListener )targetView .getTag (R .id .unionpay_payment_method_listener );
136
+ if (lastPaymentMethodListener != null ) {
137
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .JELLY_BEAN ) {
138
+ targetView .getViewTreeObserver ().removeOnGlobalLayoutListener (lastPaymentMethodListener );
139
+ }
140
+ }
141
+ targetView .getViewTreeObserver ().addOnGlobalLayoutListener (paymentMethodListener );
142
+ targetView .setTag (R .id .unionpay_payment_method_listener , paymentMethodListener );
143
+
144
+ rootView .setTag (R .id .unionpay_payview_shown , "true" );
121
145
String passwordEncrypted = config .getPasswordEncrypted ();
122
146
if (TextUtils .isEmpty (passwordEncrypted ) || TextUtils .isEmpty (config .getPasswordIV ())) {
123
147
Toaster .showLong (Lang .getString (R .id .toast_password_not_set_generic ));
148
+ rootView .setTag (R .id .unionpay_payview_shown , null );
124
149
return ;
125
150
}
126
151
hidePreviousPayDialog ();
@@ -133,22 +158,15 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
133
158
dialogMode = true ;
134
159
}
135
160
L .d ("payRootLayout" , payRootLayout );
136
- View finalPayRootLayout = payRootLayout ;
137
- payRootLayout .setAlpha (0 );
138
- //for hidePreviousPayDialog
139
- Task .onMain (100 , () -> finalPayRootLayout .setAlpha (0 ));
140
-
141
- mPwdActivityDontShowFlag = false ;
142
- mPwdActivityReShowDelayTimeMsec = 0 ;
143
161
boolean finalDialogMode = dialogMode ;
144
- AlipayPayView payView = new AlipayPayView (context ).withOnCloseImageClickListener ((target , v ) -> {
145
- mPwdActivityDontShowFlag = true ;
146
- target .getDialog ().dismiss ();
147
-
162
+ AlipayPayView payView = new AlipayPayView (context )
163
+ .withOnCancelButtonClickListener (target -> {
164
+ AlertDialog dialog = target .getDialog ();
165
+ if (dialog != null ) {
166
+ dialog .dismiss ();
167
+ }
148
168
if (finalDialogMode ) {
149
169
Task .onBackground (100 , () -> {
150
- Instrumentation inst = new Instrumentation ();
151
- inst .sendKeyDownUpSync (KeyEvent .KEYCODE_BACK );
152
170
Task .onMain (500 , () -> {
153
171
//窗口消失了
154
172
if (ViewUtils .isViewVisibleInScreen (rootView ) == false ) {
@@ -157,22 +175,14 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
157
175
retryWatchPayViewIfPossible (activity , rootView , 10 , 500 );
158
176
});
159
177
});
160
- Task .onMain (300 , () -> finalPayRootLayout .setAlpha (1 ));
161
- } else {
162
- if (activity != null ) {
163
- activity .onBackPressed ();
164
- }
165
- Task .onMain (300 , () -> finalPayRootLayout .setAlpha (1 ));
166
178
}
167
179
}).withOnDismissListener (v -> {
168
180
XBiometricIdentify fingerprintIdentify = mFingerprintIdentify ;
169
181
if (fingerprintIdentify != null ) {
170
182
fingerprintIdentify .cancelIdentify ();
171
183
L .d ("指纹识别取消1" );
172
184
}
173
- if (!mPwdActivityDontShowFlag ) {
174
- Task .onMain (mPwdActivityReShowDelayTimeMsec , () -> finalPayRootLayout .setAlpha (1 ));
175
- }
185
+ rootView .setTag (R .id .unionpay_payview_shown , null );
176
186
}).withOnShowListener (target -> {
177
187
ViewUtils .setAlpha (target .getDialog (), 0 );
178
188
ViewUtils .setDimAmount (target .getDialog (), 0 );
@@ -188,7 +198,6 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
188
198
BlackListUtils .applyIfNeeded (context );
189
199
190
200
Runnable onCompleteRunnable = () -> {
191
- mPwdActivityReShowDelayTimeMsec = 2000 ;
192
201
AlertDialog dialog = mFingerPrintAlertDialog ;
193
202
if (dialog != null ) {
194
203
dialog .dismiss ();
@@ -224,17 +233,16 @@ public synchronized void showFingerPrintDialog(@Nullable Activity activity, View
224
233
}
225
234
);
226
235
});
227
- Task .onMain (100 , () -> {
228
- L .d ("ViewUtils.isViewVisibleInScreen(rootView) " ,ViewUtils .isViewVisibleInScreen (rootView ) );
229
- //窗口消失了
230
- if (ViewUtils .isViewVisibleInScreen (rootView ) == false ) {
231
- return ;
232
- }
233
- AlertDialog fingerPrintAlertDialog = payView .showInDialog ();
234
- ViewUtils .setAlpha (fingerPrintAlertDialog , 0 );
235
- ViewUtils .setDimAmount (fingerPrintAlertDialog , 0 );
236
- mFingerPrintAlertDialog = fingerPrintAlertDialog ;
237
- });
236
+ L .d ("ViewUtils.isViewVisibleInScreen(rootView) " ,ViewUtils .isViewVisibleInScreen (rootView ) );
237
+ //窗口消失了
238
+ if (ViewUtils .isViewVisibleInScreen (rootView ) == false ) {
239
+ rootView .setTag (R .id .unionpay_payview_shown , null );
240
+ return ;
241
+ }
242
+ AlertDialog fingerPrintAlertDialog = payView .showInDialog ();
243
+ ViewUtils .setAlpha (fingerPrintAlertDialog , 0 );
244
+ ViewUtils .setDimAmount (fingerPrintAlertDialog , 0 );
245
+ mFingerPrintAlertDialog = fingerPrintAlertDialog ;
238
246
} catch (OutOfMemoryError e ) {
239
247
}
240
248
}
@@ -341,7 +349,7 @@ public void onActivityPaused(Activity activity) {
341
349
} else if (activityClzName .contains (".PayWalletActivity" )) {
342
350
hidePreviousPayDialog ();
343
351
}
344
- stopAndRemoveTargetActivityViewObserver ( activity );
352
+ ActivityViewObserverHolder . stop ( ActivityViewObserverHolder . Key . UnionPayPasswordView );
345
353
}
346
354
347
355
@ Override
@@ -371,11 +379,11 @@ public void setMockCurrentUser(boolean mock) {
371
379
}
372
380
373
381
private void watchPayView (Activity activity ) {
374
- stopAndRemoveCurrentActivityViewObserver ();
375
382
ActivityViewObserver activityViewObserver = new ActivityViewObserver (activity );
376
383
activityViewObserver .setViewIdentifyText ("请输入支付密码" );
377
384
activityViewObserver .setWatchActivityViewOnly (true );
378
- activityViewObserver .start (100 , new ActivityViewObserver .IActivityViewListener () {
385
+ ActivityViewObserverHolder .start (ActivityViewObserverHolder .Key .UnionPayPasswordView , activityViewObserver ,
386
+ 100 , new ActivityViewObserver .IActivityViewListener () {
379
387
@ Override
380
388
public void onViewFounded (ActivityViewObserver observer , View view ) {
381
389
//跳过没有显示的view, 云闪付专属
@@ -400,7 +408,7 @@ public void onViewFounded(ActivityViewObserver observer, View view) {
400
408
return ;
401
409
}
402
410
403
- onPayDialogShown (observer .getTargetActivity (), ( ViewGroup ) rootView );
411
+ onPayDialogShown (observer .getTargetActivity (), view );
404
412
View .OnAttachStateChangeListener listener = mView2OnAttachStateChangeListenerMap .get (view );
405
413
if (listener != null ) {
406
414
view .removeOnAttachStateChangeListener (listener );
@@ -424,12 +432,11 @@ public void onViewDetachedFromWindow(View v) {
424
432
mView2OnAttachStateChangeListenerMap .put (view , listener );
425
433
}
426
434
});
427
- mActivityViewObserver = activityViewObserver ;
428
435
}
429
436
430
- protected void onPayDialogShown (@ Nullable Activity activity , ViewGroup rootView ) {
437
+ protected void onPayDialogShown (@ Nullable Activity activity , View targetView ) {
431
438
L .d ("PayDialog show" );
432
- showFingerPrintDialog (activity , rootView );
439
+ showFingerPrintDialog (activity , targetView );
433
440
}
434
441
435
442
protected void onPayDialogDismiss (Context context ) {
@@ -444,24 +451,6 @@ protected void onPayDialogDismiss(Context context) {
444
451
}
445
452
}
446
453
447
- protected void stopAndRemoveCurrentActivityViewObserver () {
448
- ActivityViewObserver activityViewObserver = mActivityViewObserver ;
449
- if (activityViewObserver != null ) {
450
- activityViewObserver .stop ();
451
- mActivityViewObserver = null ;
452
- }
453
- }
454
-
455
- protected void stopAndRemoveTargetActivityViewObserver (Activity activity ) {
456
- ActivityViewObserver activityViewObserver = mActivityViewObserver ;
457
- if (activityViewObserver != null ) {
458
- if (activity == activityViewObserver .getTargetActivity ()) {
459
- activityViewObserver .stop ();
460
- mActivityViewObserver = null ;
461
- }
462
- }
463
- }
464
-
465
454
protected void doSettingsMenuInject (final Activity activity ) {
466
455
467
456
View rootView = activity .getWindow ().getDecorView ();
0 commit comments