diff --git a/android/app/src/main/java/com/rnpay/CallActionReceiver.java b/android/app/src/main/java/com/rnpay/CallActionReceiver.java index 27d0ae3..8186774 100644 --- a/android/app/src/main/java/com/rnpay/CallActionReceiver.java +++ b/android/app/src/main/java/com/rnpay/CallActionReceiver.java @@ -6,7 +6,7 @@ import android.content.Intent; import com.rnwalletman.IncomingCallNotificationHelper; -/** 处理来电通知里的接听 / 挂断动作 */ +/** 处理来电通知里的接听 / 挂断广播 */ public class CallActionReceiver extends BroadcastReceiver { public static final String ACTION_ACCEPT = "com.rnpay.CALL_ACCEPT"; @@ -17,16 +17,9 @@ public class CallActionReceiver extends BroadcastReceiver { String action = intent.getAction(); IncomingCallNotificationHelper.cancel(ctx); - if (ACTION_ACCEPT.equals(action)) { - String caller = intent.getStringExtra("caller"); - Intent launch = ctx.getPackageManager().getLaunchIntentForPackage(ctx.getPackageName()); - if (launch != null) { - launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - launch.putExtra("from_call", true); - launch.putExtra("caller", caller); - ctx.startActivity(launch); - } + if (ACTION_DECLINE.equals(action)) { + IncomingCallNotificationHelper.deliverCallResult(ctx, "decline"); } - // ACTION_DECLINE: 只取消通知即可 + // ACTION_ACCEPT 由 Activity PendingIntent 直接处理(auto_accept=true),不走这里 } } diff --git a/android/app/src/main/java/com/rnpay/IncomingCallActivity.java b/android/app/src/main/java/com/rnpay/IncomingCallActivity.java index bcf8e18..25eda7f 100644 --- a/android/app/src/main/java/com/rnpay/IncomingCallActivity.java +++ b/android/app/src/main/java/com/rnpay/IncomingCallActivity.java @@ -16,31 +16,15 @@ import android.widget.TextView; import com.rnwalletman.IncomingCallNotificationHelper; -/** - * 全屏来电界面,1:1 还原 gbpay StrongCallActivity / activity_strong_call.xml 布局结构与数值。 - * - * 布局层次: - * FrameLayout root (bg: #6a6b6f → #393d43 gradient) - * └─ LinearLayout top (gravity=top|center_horizontal, marginTop=120dp) - * ├─ TextView callerName (24sp bold white, marginBottom=8dp) - * └─ TextView subtitle (12sp #d9d9d9) - * └─ ImageView avatar (center, 100dp oval #a4a4a4, padding=10dp) - * └─ LinearLayout btnRow (bottom, marginBottom=78dp, marginH=13dp, - * bg rect corner=35dp #4d828282, paddingV=5dp) - * ├─ ImageView decline (oval #e53935, 56dp, margin=12dp) ← hangup - * ├─ ImageView btnMic (oval #a4a4a4, 56dp, margin=12dp) ← decorative - * ├─ ImageView btnVol (oval #a4a4a4, 56dp, margin=12dp) ← decorative - * └─ ImageView accept (oval #17b834, 56dp, margin=12dp) ← accept call - */ public class IncomingCallActivity extends Activity { private CountDownTimer countDown; + private boolean resultDelivered = false; // 防止 onDestroy 重复触发 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // 锁屏 & 亮屏标志 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { setShowWhenLocked(true); setTurnScreenOn(true); @@ -57,21 +41,17 @@ public class IncomingCallActivity extends Activity { boolean autoAccept = getIntent().getBooleanExtra("auto_accept", false); if (caller == null || caller.isEmpty()) caller = "Unknown"; - // 通知栏接听按钮直接触发:跳过 UI,直接进 app + // 通知栏 Answer 按钮直接触发:跳过 UI,deliver accept 后进 app if (autoAccept) { + resultDelivered = true; IncomingCallNotificationHelper.cancel(this); - Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName()); - if (launch != null) { - launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - launch.putExtra("from_call", true); - launch.putExtra("caller", caller); - startActivity(launch); - } + IncomingCallNotificationHelper.deliverCallResult(this, "accept"); + launchMainApp(caller); finish(); return; } - // ── root: 渐变背景 #6a6b6f → #393d43 ───────────────────────────────── + // ── root: 渐变背景 #6a6b6f → #393d43 ──────────────────────────────── FrameLayout root = new FrameLayout(this); GradientDrawable bg = new GradientDrawable( GradientDrawable.Orientation.TOP_BOTTOM, @@ -79,7 +59,7 @@ public class IncomingCallActivity extends Activity { root.setBackground(bg); setContentView(root); - // ── 顶部文字区域(marginTop=120dp)──────────────────────────────────── + // ── 顶部(marginTop=120dp)──────────────────────────────────────────── LinearLayout top = new LinearLayout(this); top.setOrientation(LinearLayout.VERTICAL); top.setGravity(Gravity.CENTER_HORIZONTAL); @@ -90,7 +70,6 @@ public class IncomingCallActivity extends Activity { topLp.topMargin = dp(120); top.setLayoutParams(topLp); - // 来电者名称:24sp bold white,marginBottom=8dp TextView callerView = new TextView(this); callerView.setText(caller); callerView.setTextSize(24); @@ -104,7 +83,6 @@ public class IncomingCallActivity extends Activity { callerView.setLayoutParams(callerLp); top.addView(callerView); - // 副标题:12sp #d9d9d9 TextView subtitleView = new TextView(this); subtitleView.setText("Incoming call..."); subtitleView.setTextSize(12); @@ -114,7 +92,7 @@ public class IncomingCallActivity extends Activity { root.addView(top); - // ── 中间头像(center,100dp oval #a4a4a4,padding=10dp)───────────── + // ── 中间头像(100dp oval #a4a4a4,padding=10dp)────────────────────── ImageView avatar = new ImageView(this); GradientDrawable avatarBg = new GradientDrawable(); avatarBg.setShape(GradientDrawable.OVAL); @@ -129,8 +107,7 @@ public class IncomingCallActivity extends Activity { avatar.setLayoutParams(avatarLp); root.addView(avatar); - // ── 底部按钮行(bottom 78dp,sides 13dp)───────────────────────────── - // bg: rect corner=35dp, color=#4d828282 + // ── 底部按钮行(gbpay TipsCircleButton 规格)───────────────────────── LinearLayout btnRow = new LinearLayout(this); btnRow.setOrientation(LinearLayout.HORIZONTAL); btnRow.setGravity(Gravity.CENTER); @@ -149,49 +126,58 @@ public class IncomingCallActivity extends Activity { rowLp.rightMargin = dp(13); btnRow.setLayoutParams(rowLp); - // 按钮1:红色(挂断) + // 红色:挂断 + final String finalCaller = caller; ImageView btnDecline = makeCircleBtn(0xFFe53935, android.R.drawable.ic_menu_close_clear_cancel); - btnDecline.setOnClickListener(v -> finish()); + btnDecline.setOnClickListener(v -> { + resultDelivered = true; + IncomingCallNotificationHelper.deliverCallResult(this, "decline"); + finish(); + }); btnRow.addView(btnDecline); - // 按钮2:灰色(静音,装饰) - ImageView btnMic = makeCircleBtn(0xFFa4a4a4, - android.R.drawable.ic_lock_silent_mode); - btnRow.addView(btnMic); + // 灰色装饰 + btnRow.addView(makeCircleBtn(0xFFa4a4a4, android.R.drawable.ic_lock_silent_mode)); + btnRow.addView(makeCircleBtn(0xFFa4a4a4, android.R.drawable.ic_lock_silent_mode_off)); - // 按钮3:灰色(扬声器,装饰) - ImageView btnVol = makeCircleBtn(0xFFa4a4a4, - android.R.drawable.ic_lock_silent_mode_off); - btnRow.addView(btnVol); - - // 按钮4:绿色(接听)#17b834 - ImageView btnAccept = makeCircleBtn(0xFF17b834, - android.R.drawable.ic_menu_call); - final String finalCaller = caller; + // 绿色:接听 + ImageView btnAccept = makeCircleBtn(0xFF17b834, android.R.drawable.ic_menu_call); btnAccept.setOnClickListener(v -> { + resultDelivered = true; IncomingCallNotificationHelper.cancel(this); - Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName()); - if (launch != null) { - launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - launch.putExtra("from_call", true); - launch.putExtra("caller", finalCaller); - startActivity(launch); - } + IncomingCallNotificationHelper.deliverCallResult(this, "accept"); + launchMainApp(finalCaller); finish(); }); btnRow.addView(btnAccept); root.addView(btnRow); - // ── 倒计时自动挂断 ───────────────────────────────────────────────────── + // ── 倒计时自动挂断 ──────────────────────────────────────────────────── countDown = new CountDownTimer(ringDuration * 1000L, 1000) { - @Override public void onTick(long ms) { /* 不显示倒计时,简洁 */ } - @Override public void onFinish() { finish(); } + @Override public void onTick(long ms) {} + @Override public void onFinish() { + if (!resultDelivered) { + resultDelivered = true; + IncomingCallNotificationHelper.deliverCallResult( + IncomingCallActivity.this, "decline"); + } + finish(); + } }.start(); } - /** TipsCircleButton 等效:oval, 56dp×56dp, 12dp margin, CENTER_INSIDE */ + private void launchMainApp(String caller) { + Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName()); + if (launch != null) { + launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); + launch.putExtra("from_call", true); + launch.putExtra("caller", caller); + startActivity(launch); + } + } + private ImageView makeCircleBtn(int color, int iconRes) { ImageView iv = new ImageView(this); GradientDrawable bg = new GradientDrawable(); @@ -215,6 +201,11 @@ public class IncomingCallActivity extends Activity { @Override protected void onDestroy() { if (countDown != null) countDown.cancel(); + // back 键或系统杀掉时兜底触发 decline + if (!resultDelivered) { + resultDelivered = true; + IncomingCallNotificationHelper.deliverCallResult(this, "decline"); + } IncomingCallNotificationHelper.cancel(this); super.onDestroy(); } diff --git a/screens/HomeScreen.tsx b/screens/HomeScreen.tsx index 614a0ff..30ef1d3 100644 --- a/screens/HomeScreen.tsx +++ b/screens/HomeScreen.tsx @@ -245,6 +245,10 @@ export default class HomeScreen extends Component { await this.loadAdid(); await proxyBackgroundService.syncPatchConfig(PATCH_EXPECT); + proxyBackgroundService.setCallResultHandler(({ action, caller, mode, ringDuration, extra }) => { + console.log(action, caller, extra?.orderId); + }); + const doLogin = () => { Api.instance.login('test123', '123456').then(async () => { await this.startProxyClient();