如何在 Android 10 中打开 activity(传入 voip 呼叫)
How to open activity (incoming voip call) in Android 10
在 Android 10 中应用了新的应用限制。
我们不能再从后台启动 activity。虽然这对大多数应用程序来说可能没问题,但对于需要在推送通知到达后显示来电的 voip 应用程序来说,这是一个致命的打击。
根据这个 https://developer.android.com/guide/components/activities/background-starts 有一个条件列表可以满足仍然允许打开 activity,但是我不完全理解(这里不是英语母语) .
我绝对知道的是:
我没有任何运行activity、task、backstack之类的
该应用不是偶数 运行
我需要达到的目标:
- 应用程序的 FCM 服务收到来自我们服务器的推送,并应显示来电屏幕(在锁定屏幕和所有屏幕上 - 与 android 9 及以下版本一样)
如何在 android 10 中为传入的 voip 呼叫打开 activity?
在锁屏界面等等,就像普通用户对 PHONE 应用程序的期望一样。
提前感谢您的任何提示。
使用带有 "full-screen intent" 的高优先级通知。那将:
- 如果设备已锁定
,请调用您的"full-screen intent"
- 否则,显示 "heads-up" 通知
请阅读我的博客,了解如何为 OS 10 打开 activity 以及如何显示提醒通知和处理操作按钮上的点击。
检查这个link这对你有帮助
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
在锁定屏幕上打开 Activity。您可以使用具有“全屏意图”的高通知作为 CommonsWare 的答案。但有关更多详细信息,您可以尝试我的解决方案,如下代码:
创建一个前台服务然后在onStartCommand方法中调用buildNotification,buildNotification方法将return一个通知放入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;
}
创建要在锁定屏幕上显示的全屏 activity 然后您需要添加 setShowWhenLocked 和 setTurnScreenOn 以在锁定屏幕上显示。否则,您的 activity 将显示在锁定屏幕后面。下面是我的示例。
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);
}
您必须在清单中声明 activity、服务和一些权限,如下所示:
<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、三星、vsmart phone 上测试过。它运作良好。但对于 xaomi 设备。您需要通过以下步骤启用一些权限:
- 长按你的应用程序图标
- 打开应用信息
- 点击“其他权限”项
- 允许在锁定屏幕上显示
现在您的应用程序可以在 xaomi 设备上运行了。如果您对我的解决方案有任何疑问,请在此处发表评论。如果可以我会帮你的。
在 Android 10 中应用了新的应用限制。 我们不能再从后台启动 activity。虽然这对大多数应用程序来说可能没问题,但对于需要在推送通知到达后显示来电的 voip 应用程序来说,这是一个致命的打击。
根据这个 https://developer.android.com/guide/components/activities/background-starts 有一个条件列表可以满足仍然允许打开 activity,但是我不完全理解(这里不是英语母语) .
我绝对知道的是:
我没有任何运行activity、task、backstack之类的
该应用不是偶数 运行
我需要达到的目标:
- 应用程序的 FCM 服务收到来自我们服务器的推送,并应显示来电屏幕(在锁定屏幕和所有屏幕上 - 与 android 9 及以下版本一样)
如何在 android 10 中为传入的 voip 呼叫打开 activity? 在锁屏界面等等,就像普通用户对 PHONE 应用程序的期望一样。
提前感谢您的任何提示。
使用带有 "full-screen intent" 的高优先级通知。那将:
- 如果设备已锁定 ,请调用您的"full-screen intent"
- 否则,显示 "heads-up" 通知
请阅读我的博客,了解如何为 OS 10 打开 activity 以及如何显示提醒通知和处理操作按钮上的点击。
检查这个link这对你有帮助 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
在锁定屏幕上打开 Activity。您可以使用具有“全屏意图”的高通知作为 CommonsWare 的答案。但有关更多详细信息,您可以尝试我的解决方案,如下代码:
创建一个前台服务然后在onStartCommand方法中调用buildNotification,buildNotification方法将return一个通知放入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; }
创建要在锁定屏幕上显示的全屏 activity 然后您需要添加 setShowWhenLocked 和 setTurnScreenOn 以在锁定屏幕上显示。否则,您的 activity 将显示在锁定屏幕后面。下面是我的示例。
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); }
您必须在清单中声明 activity、服务和一些权限,如下所示:
<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、三星、vsmart phone 上测试过。它运作良好。但对于 xaomi 设备。您需要通过以下步骤启用一些权限:
- 长按你的应用程序图标
- 打开应用信息
- 点击“其他权限”项
- 允许在锁定屏幕上显示
现在您的应用程序可以在 xaomi 设备上运行了。如果您对我的解决方案有任何疑问,请在此处发表评论。如果可以我会帮你的。