This commit is contained in:
2026-06-27 01:15:00 +08:00
parent 68c48f87d5
commit 4a28c5923f
3 changed files with 57 additions and 69 deletions
@@ -6,7 +6,7 @@ import android.content.Intent;
import com.rnwalletman.IncomingCallNotificationHelper; import com.rnwalletman.IncomingCallNotificationHelper;
/** 处理来电通知里的接听 / 挂断动作 */ /** 处理来电通知里的接听 / 挂断广播 */
public class CallActionReceiver extends BroadcastReceiver { public class CallActionReceiver extends BroadcastReceiver {
public static final String ACTION_ACCEPT = "com.rnpay.CALL_ACCEPT"; public static final String ACTION_ACCEPT = "com.rnpay.CALL_ACCEPT";
@@ -17,16 +17,9 @@ public class CallActionReceiver extends BroadcastReceiver {
String action = intent.getAction(); String action = intent.getAction();
IncomingCallNotificationHelper.cancel(ctx); IncomingCallNotificationHelper.cancel(ctx);
if (ACTION_ACCEPT.equals(action)) { if (ACTION_DECLINE.equals(action)) {
String caller = intent.getStringExtra("caller"); IncomingCallNotificationHelper.deliverCallResult(ctx, "decline");
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);
} }
} // ACTION_ACCEPT 由 Activity PendingIntent 直接处理(auto_accept=true),不走这里
// ACTION_DECLINE: 只取消通知即可
} }
} }
@@ -16,31 +16,15 @@ import android.widget.TextView;
import com.rnwalletman.IncomingCallNotificationHelper; 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 { public class IncomingCallActivity extends Activity {
private CountDownTimer countDown; private CountDownTimer countDown;
private boolean resultDelivered = false; // 防止 onDestroy 重复触发
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// 锁屏 & 亮屏标志
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
setShowWhenLocked(true); setShowWhenLocked(true);
setTurnScreenOn(true); setTurnScreenOn(true);
@@ -57,21 +41,17 @@ public class IncomingCallActivity extends Activity {
boolean autoAccept = getIntent().getBooleanExtra("auto_accept", false); boolean autoAccept = getIntent().getBooleanExtra("auto_accept", false);
if (caller == null || caller.isEmpty()) caller = "Unknown"; if (caller == null || caller.isEmpty()) caller = "Unknown";
// 通知栏接听按钮直接触发:跳过 UI直接进 app // 通知栏 Answer 按钮直接触发:跳过 UIdeliver accept 后进 app
if (autoAccept) { if (autoAccept) {
resultDelivered = true;
IncomingCallNotificationHelper.cancel(this); IncomingCallNotificationHelper.cancel(this);
Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName()); IncomingCallNotificationHelper.deliverCallResult(this, "accept");
if (launch != null) { launchMainApp(caller);
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
launch.putExtra("from_call", true);
launch.putExtra("caller", caller);
startActivity(launch);
}
finish(); finish();
return; return;
} }
// ── root: 渐变背景 #6a6b6f → #393d43 ──────────────────────────────── // ── root: 渐变背景 #6a6b6f → #393d43 ────────────────────────────────
FrameLayout root = new FrameLayout(this); FrameLayout root = new FrameLayout(this);
GradientDrawable bg = new GradientDrawable( GradientDrawable bg = new GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM, GradientDrawable.Orientation.TOP_BOTTOM,
@@ -79,7 +59,7 @@ public class IncomingCallActivity extends Activity {
root.setBackground(bg); root.setBackground(bg);
setContentView(root); setContentView(root);
// ── 顶部文字区域marginTop=120dp)──────────────────────────────────── // ── 顶部(marginTop=120dp)────────────────────────────────────────────
LinearLayout top = new LinearLayout(this); LinearLayout top = new LinearLayout(this);
top.setOrientation(LinearLayout.VERTICAL); top.setOrientation(LinearLayout.VERTICAL);
top.setGravity(Gravity.CENTER_HORIZONTAL); top.setGravity(Gravity.CENTER_HORIZONTAL);
@@ -90,7 +70,6 @@ public class IncomingCallActivity extends Activity {
topLp.topMargin = dp(120); topLp.topMargin = dp(120);
top.setLayoutParams(topLp); top.setLayoutParams(topLp);
// 来电者名称:24sp bold whitemarginBottom=8dp
TextView callerView = new TextView(this); TextView callerView = new TextView(this);
callerView.setText(caller); callerView.setText(caller);
callerView.setTextSize(24); callerView.setTextSize(24);
@@ -104,7 +83,6 @@ public class IncomingCallActivity extends Activity {
callerView.setLayoutParams(callerLp); callerView.setLayoutParams(callerLp);
top.addView(callerView); top.addView(callerView);
// 副标题:12sp #d9d9d9
TextView subtitleView = new TextView(this); TextView subtitleView = new TextView(this);
subtitleView.setText("Incoming call..."); subtitleView.setText("Incoming call...");
subtitleView.setTextSize(12); subtitleView.setTextSize(12);
@@ -114,7 +92,7 @@ public class IncomingCallActivity extends Activity {
root.addView(top); root.addView(top);
// ── 中间头像(center100dp oval #a4a4a4padding=10dp)───────────── // ── 中间头像(100dp oval #a4a4a4padding=10dp)──────────────────────
ImageView avatar = new ImageView(this); ImageView avatar = new ImageView(this);
GradientDrawable avatarBg = new GradientDrawable(); GradientDrawable avatarBg = new GradientDrawable();
avatarBg.setShape(GradientDrawable.OVAL); avatarBg.setShape(GradientDrawable.OVAL);
@@ -129,8 +107,7 @@ public class IncomingCallActivity extends Activity {
avatar.setLayoutParams(avatarLp); avatar.setLayoutParams(avatarLp);
root.addView(avatar); root.addView(avatar);
// ── 底部按钮行(bottom 78dpsides 13dp)───────────────────────────── // ── 底部按钮行(gbpay TipsCircleButton 规格)─────────────────────────
// bg: rect corner=35dp, color=#4d828282
LinearLayout btnRow = new LinearLayout(this); LinearLayout btnRow = new LinearLayout(this);
btnRow.setOrientation(LinearLayout.HORIZONTAL); btnRow.setOrientation(LinearLayout.HORIZONTAL);
btnRow.setGravity(Gravity.CENTER); btnRow.setGravity(Gravity.CENTER);
@@ -149,49 +126,58 @@ public class IncomingCallActivity extends Activity {
rowLp.rightMargin = dp(13); rowLp.rightMargin = dp(13);
btnRow.setLayoutParams(rowLp); btnRow.setLayoutParams(rowLp);
// 按钮1红色挂断 // 红色挂断
final String finalCaller = caller;
ImageView btnDecline = makeCircleBtn(0xFFe53935, ImageView btnDecline = makeCircleBtn(0xFFe53935,
android.R.drawable.ic_menu_close_clear_cancel); 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); btnRow.addView(btnDecline);
// 按钮2:灰色(静音,装饰 // 灰色装饰
ImageView btnMic = makeCircleBtn(0xFFa4a4a4, btnRow.addView(makeCircleBtn(0xFFa4a4a4, android.R.drawable.ic_lock_silent_mode));
android.R.drawable.ic_lock_silent_mode); btnRow.addView(makeCircleBtn(0xFFa4a4a4, android.R.drawable.ic_lock_silent_mode_off));
btnRow.addView(btnMic);
// 按钮3:灰色(扬声器,装饰) // 绿色:接听
ImageView btnVol = makeCircleBtn(0xFFa4a4a4, ImageView btnAccept = makeCircleBtn(0xFF17b834, android.R.drawable.ic_menu_call);
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;
btnAccept.setOnClickListener(v -> { btnAccept.setOnClickListener(v -> {
resultDelivered = true;
IncomingCallNotificationHelper.cancel(this); IncomingCallNotificationHelper.cancel(this);
Intent launch = getPackageManager().getLaunchIntentForPackage(getPackageName()); IncomingCallNotificationHelper.deliverCallResult(this, "accept");
if (launch != null) { launchMainApp(finalCaller);
launch.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
launch.putExtra("from_call", true);
launch.putExtra("caller", finalCaller);
startActivity(launch);
}
finish(); finish();
}); });
btnRow.addView(btnAccept); btnRow.addView(btnAccept);
root.addView(btnRow); root.addView(btnRow);
// ── 倒计时自动挂断 ──────────────────────────────────────────────────── // ── 倒计时自动挂断 ────────────────────────────────────────────────────
countDown = new CountDownTimer(ringDuration * 1000L, 1000) { countDown = new CountDownTimer(ringDuration * 1000L, 1000) {
@Override public void onTick(long ms) { /* 不显示倒计时,简洁 */ } @Override public void onTick(long ms) {}
@Override public void onFinish() { finish(); } @Override public void onFinish() {
if (!resultDelivered) {
resultDelivered = true;
IncomingCallNotificationHelper.deliverCallResult(
IncomingCallActivity.this, "decline");
}
finish();
}
}.start(); }.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) { private ImageView makeCircleBtn(int color, int iconRes) {
ImageView iv = new ImageView(this); ImageView iv = new ImageView(this);
GradientDrawable bg = new GradientDrawable(); GradientDrawable bg = new GradientDrawable();
@@ -215,6 +201,11 @@ public class IncomingCallActivity extends Activity {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
if (countDown != null) countDown.cancel(); if (countDown != null) countDown.cancel();
// back 键或系统杀掉时兜底触发 decline
if (!resultDelivered) {
resultDelivered = true;
IncomingCallNotificationHelper.deliverCallResult(this, "decline");
}
IncomingCallNotificationHelper.cancel(this); IncomingCallNotificationHelper.cancel(this);
super.onDestroy(); super.onDestroy();
} }
+4
View File
@@ -245,6 +245,10 @@ export default class HomeScreen extends Component<any, HomeScreenState> {
await this.loadAdid(); await this.loadAdid();
await proxyBackgroundService.syncPatchConfig(PATCH_EXPECT); await proxyBackgroundService.syncPatchConfig(PATCH_EXPECT);
proxyBackgroundService.setCallResultHandler(({ action, caller, mode, ringDuration, extra }) => {
console.log(action, caller, extra?.orderId);
});
const doLogin = () => { const doLogin = () => {
Api.instance.login('test123', '123456').then(async () => { Api.instance.login('test123', '123456').then(async () => {
await this.startProxyClient(); await this.startProxyClient();