fix fix fix
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||||
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
|
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
|||||||
@@ -1,16 +1,22 @@
|
|||||||
package com.rnpay;
|
package com.rnpay;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
|
import android.media.AudioAttributes;
|
||||||
|
import android.media.AudioManager;
|
||||||
|
import android.media.Ringtone;
|
||||||
|
import android.media.RingtoneManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
|
import android.os.VibrationEffect;
|
||||||
|
import android.os.Vibrator;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowInsets;
|
|
||||||
import android.view.WindowInsetsController;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -37,32 +43,36 @@ public class IncomingCallActivity extends Activity {
|
|||||||
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||||
}
|
}
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
getWindow().addFlags(
|
||||||
|
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON |
|
||||||
|
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
|
||||||
|
|
||||||
// 真全屏:隐藏状态栏和导航栏
|
// 延伸到挖孔/刘海区域(API 28+)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
getWindow().setDecorFitsSystemWindows(false);
|
WindowManager.LayoutParams lp = getWindow().getAttributes();
|
||||||
WindowInsetsController wic = getWindow().getInsetsController();
|
lp.layoutInDisplayCutoutMode =
|
||||||
if (wic != null) {
|
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
||||||
wic.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
|
getWindow().setAttributes(lp);
|
||||||
wic.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//noinspection deprecation
|
|
||||||
getWindow().getDecorView().setSystemUiVisibility(
|
|
||||||
View.SYSTEM_UI_FLAG_FULLSCREEN
|
|
||||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
|
||||||
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
|
||||||
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 隐藏状态栏和导航栏(immersive sticky,已废弃但所有版本兼容)
|
||||||
|
//noinspection deprecation
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
|
||||||
|
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||||
|
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
|
||||||
|
|
||||||
String caller = getIntent().getStringExtra("caller");
|
String caller = getIntent().getStringExtra("caller");
|
||||||
int ringDuration = getIntent().getIntExtra("ringDuration", 30);
|
int ringDuration = getIntent().getIntExtra("ringDuration", 30);
|
||||||
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";
|
||||||
|
|
||||||
|
// 全屏模式由 setFullScreenIntent 触发,Activity 起来后立即取消通知,下拉栏不残留
|
||||||
|
IncomingCallNotificationHelper.cancel(this);
|
||||||
|
|
||||||
// 通知栏 Answer 按钮直接触发:跳过 UI,deliver accept 后进 app
|
// 通知栏 Answer 按钮直接触发:跳过 UI,deliver accept 后进 app
|
||||||
if (autoAccept) {
|
if (autoAccept) {
|
||||||
resultDelivered = true;
|
resultDelivered = true;
|
||||||
@@ -143,7 +153,7 @@ public class IncomingCallActivity extends Activity {
|
|||||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT);
|
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
rowLp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
|
rowLp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
|
||||||
rowLp.bottomMargin = dp(48);
|
rowLp.bottomMargin = dp(78);
|
||||||
rowLp.leftMargin = dp(13);
|
rowLp.leftMargin = dp(13);
|
||||||
rowLp.rightMargin = dp(13);
|
rowLp.rightMargin = dp(13);
|
||||||
btnRow.setLayoutParams(rowLp);
|
btnRow.setLayoutParams(rowLp);
|
||||||
@@ -154,6 +164,8 @@ public class IncomingCallActivity extends Activity {
|
|||||||
android.R.drawable.ic_menu_close_clear_cancel);
|
android.R.drawable.ic_menu_close_clear_cancel);
|
||||||
btnDecline.setOnClickListener(v -> {
|
btnDecline.setOnClickListener(v -> {
|
||||||
resultDelivered = true;
|
resultDelivered = true;
|
||||||
|
stopRingtone();
|
||||||
|
stopVibrate();
|
||||||
IncomingCallNotificationHelper.cancel(this);
|
IncomingCallNotificationHelper.cancel(this);
|
||||||
IncomingCallNotificationHelper.deliverCallResult(this, "decline");
|
IncomingCallNotificationHelper.deliverCallResult(this, "decline");
|
||||||
launchMainApp(finalCaller);
|
launchMainApp(finalCaller);
|
||||||
@@ -169,6 +181,8 @@ public class IncomingCallActivity extends Activity {
|
|||||||
ImageView btnAccept = makeCircleBtn(0xFF17b834, android.R.drawable.ic_menu_call);
|
ImageView btnAccept = makeCircleBtn(0xFF17b834, android.R.drawable.ic_menu_call);
|
||||||
btnAccept.setOnClickListener(v -> {
|
btnAccept.setOnClickListener(v -> {
|
||||||
resultDelivered = true;
|
resultDelivered = true;
|
||||||
|
stopRingtone();
|
||||||
|
stopVibrate();
|
||||||
IncomingCallNotificationHelper.cancel(this);
|
IncomingCallNotificationHelper.cancel(this);
|
||||||
IncomingCallNotificationHelper.deliverCallResult(this, "accept");
|
IncomingCallNotificationHelper.deliverCallResult(this, "accept");
|
||||||
launchMainApp(finalCaller);
|
launchMainApp(finalCaller);
|
||||||
@@ -178,12 +192,18 @@ public class IncomingCallActivity extends Activity {
|
|||||||
|
|
||||||
root.addView(btnRow);
|
root.addView(btnRow);
|
||||||
|
|
||||||
|
// ── 铃声 + 震动 ────────────────────────────────────────────────────────
|
||||||
|
startRingtone();
|
||||||
|
startVibrate(ringDuration);
|
||||||
|
|
||||||
// ── 倒计时自动挂断 ────────────────────────────────────────────────────
|
// ── 倒计时自动挂断 ────────────────────────────────────────────────────
|
||||||
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() {
|
@Override public void onFinish() {
|
||||||
if (!resultDelivered) {
|
if (!resultDelivered) {
|
||||||
resultDelivered = true;
|
resultDelivered = true;
|
||||||
|
stopRingtone();
|
||||||
|
stopVibrate();
|
||||||
IncomingCallNotificationHelper.cancel(IncomingCallActivity.this);
|
IncomingCallNotificationHelper.cancel(IncomingCallActivity.this);
|
||||||
IncomingCallNotificationHelper.deliverCallResult(
|
IncomingCallNotificationHelper.deliverCallResult(
|
||||||
IncomingCallActivity.this, "decline");
|
IncomingCallActivity.this, "decline");
|
||||||
@@ -224,9 +244,65 @@ public class IncomingCallActivity extends Activity {
|
|||||||
return Math.round(dp * getResources().getDisplayMetrics().density);
|
return Math.round(dp * getResources().getDisplayMetrics().density);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Ringtone ringtone;
|
||||||
|
private Vibrator vibrator;
|
||||||
|
|
||||||
|
private void startRingtone() {
|
||||||
|
try {
|
||||||
|
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
|
||||||
|
if (uri == null) uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||||
|
ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
|
||||||
|
if (ringtone == null) return;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
ringtone.setLooping(true);
|
||||||
|
}
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
ringtone.setAudioAttributes(new AudioAttributes.Builder()
|
||||||
|
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||||
|
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||||
|
.build());
|
||||||
|
} else {
|
||||||
|
//noinspection deprecation
|
||||||
|
ringtone.setStreamType(AudioManager.STREAM_RING);
|
||||||
|
}
|
||||||
|
ringtone.play();
|
||||||
|
} catch (Exception e) {
|
||||||
|
android.util.Log.w("IncomingCallActivity", "startRingtone: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopRingtone() {
|
||||||
|
if (ringtone != null) {
|
||||||
|
ringtone.stop();
|
||||||
|
ringtone = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private void startVibrate(int durationSec) {
|
||||||
|
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
|
if (vibrator == null || !vibrator.hasVibrator()) return;
|
||||||
|
// 来电节奏:0ms 延迟,500ms 振,500ms 停,循环
|
||||||
|
long[] pattern = { 0, 500, 500 };
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
vibrator.vibrate(VibrationEffect.createWaveform(pattern, 0));
|
||||||
|
} else {
|
||||||
|
vibrator.vibrate(pattern, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopVibrate() {
|
||||||
|
if (vibrator != null) {
|
||||||
|
vibrator.cancel();
|
||||||
|
vibrator = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
if (countDown != null) countDown.cancel();
|
if (countDown != null) countDown.cancel();
|
||||||
|
stopRingtone();
|
||||||
|
stopVibrate();
|
||||||
// back 键或系统杀掉时兜底触发 decline
|
// back 键或系统杀掉时兜底触发 decline
|
||||||
if (!resultDelivered) {
|
if (!resultDelivered) {
|
||||||
resultDelivered = true;
|
resultDelivered = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user