如何在 Android 10 中打开活动(来电)
Posted
技术标签:
【中文标题】如何在 Android 10 中打开活动(来电)【英文标题】:How to open activity (incoming voip call) in Android 10 【发布时间】:2020-03-08 04:42:42 【问题描述】:在 android 10 中,对应用应用了新的限制。 我们不能再从后台启动活动。虽然这对大多数应用程序来说可能没问题,但对于需要在推送通知到达后显示来电的 voip 应用程序来说,这是一个致命的打击。
根据这个https://developer.android.com/guide/components/activities/background-starts,有一个条件列表可以满足仍然允许打开活动,但我不完全理解(此处为非英语母语)。
我绝对知道的是:
我没有任何正在运行的activity、task、backstack之类的东西
应用甚至没有运行
我需要达到的目标:
应用程序的 FCM 服务从我们的服务器接收推送,并应显示来电屏幕(锁定屏幕和所有 - 就像它在 android 9 及更低版本中所做的那样)如何在 android 10 中为传入的 voip 呼叫打开活动? 就像普通用户对 PHONE 应用程序所期望的一样,在锁屏界面上进行操作。
提前感谢任何提示。
【问题讨论】:
你可以给你这个代码link @Grisgram 你能解决这个问题吗? 【参考方案1】:在锁定屏幕上打开 Activity。您可以使用具有“全屏意图”的高通知作为 CommonsWare 的答案。但要了解更多细节,您可以尝试我的解决方案,如下代码:
创建一个前台服务,然后在onStartCommand方法中调用buildNotification,buildNotification方法会返回一个通知,放入startForeground方法参数中。
public class IncomingCallService extends Service
public int onStartCommand(Intent intent, int flags, int startId)
Notification notification = buildNotification();
startForeground(1, notification);
return START_NOT_STICKY;
在 buildNotification 方法中,我们将创建具有高优先级、调用类别和全屏意图的通知。
private Notification buildNotification()
Intent fullScreenIntent = new Intent(this, IncomingCallActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(this, 0, fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_notification_icon)
.setContentTitle("Incoming call")
.setContentText("(919) 555-1234")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
// Use a full-screen intent only for the highest-priority alerts where you
// have an associated activity that you would like to launch after the user
// interacts with the notification. Also, if your app targets Android 10
// or higher, you need to request the USE_FULL_SCREEN_INTENT permission in
// order for the platform to invoke this notification.
.setFullScreenIntent(fullScreenPendingIntent, true);
notificationBuilder.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
notificationManager.createNotificationChannel(new NotificationChannel("123", "123", NotificationManager.IMPORTANCE_HIGH));
notificationBuilder.setChannelId("123");
Notification incomingCallNotification = notificationBuilder.build();
return incomingCallNotification;
在 onStartCommand 中,添加一行代码发送 ACTION_CLOSE_SYSTEM_DIALOGS 广播动作。此验证对于启动全屏挂起意图很重要。
public int onStartCommand(Intent intent, int flags, int startId)
Notification notification = buildNotification();
startForeground(1, notification);
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
return START_NOT_STICKY;
创建要在锁定屏幕上显示的全屏活动,然后您需要添加 setShowWhenLocked 和 setTurnScreenOn 以在锁定屏幕上显示。如果没有,您的活动将显示在锁定屏幕后面。以下是我的示例。
public class IncomingCallActivity extends AppCompatActivity
protected void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_explore);
setShowWhenLocked(true);
setTurnScreenOn(true);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON);
现在,当您收到来自您的逻辑的呼叫时,您必须启动 IncomingCallService。
public void startCallService()
Intent intent = new Intent(context, IncomingCallService.class);
startForegroundService(intent);
您必须在清单中声明活动、服务和一些权限,如下所示:
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
...>
<activity android:name=".IncomingCallActivity" />
<service
android:name=".IncomingCallService"
android:enabled="true"
android:exported="true" />
</application>
我在 google、samsung、vsmart 手机上测试过。它运作良好。但是对于小米设备。您需要通过以下步骤启用一些权限:
-
长按您的应用图标
打开应用信息
点击“其他权限”项
允许在锁定屏幕上显示
现在您的应用可以在 xaomi 设备上运行。如果您对我的解决方案有任何问题,请在此处发表评论。如果可以的话,我会帮助你。
【讨论】:
感谢您抽出宝贵时间提供如此详细的答案 - 我会调查一下 我的解决方案已上传到github。你可以看看github.com/doanpt/PhoneActivity 进行测试。安装应用程序后。打开 cmd 或终端然后运行命令: adb shell am start-foreground-service com.ddona.call/.IncomingCallService 小心 - getWindow().addFlags() 应该在 SetContentView 之前调用。在 API >= 27 上设置这些标志可能不太好 - 但不确定 @MichalDobrodenka, 1) 实际上,我的示例可能在不添加标志的情况下工作。但我将它添加到 27 以下的 API 上工作。2)对于 addFlags 方法,Google 说它应该在 setContentView 之前设置一些标志,而不是所有标志,然后最好,我同意我们应该在调用 setContentView 【参考方案2】:查看此链接,这将对您有所帮助 here
或
您需要请求“绘制其他应用程序”的权限,然后您才能将其设为以前的版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
if (!Settings.canDrawOverlays(this))
RequestPermission();
private void RequestPermission()
// Check if Android P or higher
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + BuildConfig.APPLICATION_ID));
startActivityForResult(intent,
ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
或者你可以使用我的这个answer
https://***.com/a/63699960/7108113
【讨论】:
【参考方案3】:请浏览我的博客,了解如何为 OS 10 打开活动,以及如何显示抬头通知和处理对操作按钮的点击。
https://medium.com/@dcostalloyd90/show-incoming-voip-call-notification-and-open-activity-for-android-os-10-5aada2d4c1e4
【讨论】:
我完全按照您的示例进行操作,但没有像您显示的那样工作。通知仍然是正常的通知 - 没有大的弹出窗口,也没有全屏意图。 @YazidEF 创建通知通道时将优先级设置为高。 @LloydDcosta 我也查看了您的示例,但是单击按钮后,没有调用 HeadsUpNotificationActionReceiver。知道为什么吗?【参考方案4】:使用具有“全屏意图”的高优先级通知。那将:
如果设备被锁定,调用您的“全屏意图” 否则,显示“提醒”通知【讨论】:
谢谢。它为我指明了正确的方向。我认为这将与带有自定义布局的扩展通知一起工作,以防应用程序当前处于前台(使用前台服务)。 一个很好的教程可以在这里找到:developer.android.com/training/notify-user/time-sensitive 用于记录。包含解决此问题所需的一切。 使用这种方法是否可以只显示全屏意图而不显示通知?我实现了这个解决方案,但是当我的全屏意图出现时它会发出通知声音。 setFullScreenIntent 的描述说:“意图启动而不是将通知发布到状态栏。”。我不认为这是真的。它为全屏意图加注星标并创建通知。 @Mitulátbáti:“是否可以只显示全屏意图而不显示通知?” - 不。 “它为全屏意图加注星标并创建通知”——这就是报价所说的。引用说它用于“而不是将通知发布到状态栏”(强调添加)。据推测,其他效果,如铃声和振动,仍然是合格的。如果用户不想要这些效果,用户应该能够在“设置”应用中为您的频道禁用它们。 @CommonsWare 你能不能提一下我们如何为通知操作设置不同的颜色(比如红色表示拒绝,绿色表示回答)以上是关于如何在 Android 10 中打开活动(来电)的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 原生来电屏幕上弹出窗口,如真正的来电者 Android 应用程序