全屏意图在Android 10上没有启动活动,但会显示通知

15

我尝试使用下面的代码通过广播接收器启动活动:

 Intent i = new Intent(context, AlarmNotification.class);
 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // This is at least android 10...

                NotificationManager mgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

                if (mgr.getNotificationChannel(CHANNEL_WHATEVER)==null) {
                    mgr.createNotificationChannel(new NotificationChannel(CHANNEL_WHATEVER,
                            "Whatever", NotificationManager.IMPORTANCE_HIGH));
                }

                mgr.notify(NOTIFY_ID, buildNormal(context, i).build());

            }

private NotificationCompat.Builder buildNormal(Context context, Intent intent) {

    NotificationCompat.Builder b=
            new NotificationCompat.Builder(context, CHANNEL_WHATEVER);

    b.setAutoCancel(true)
            .setDefaults(Notification.DEFAULT_ALL)
            .setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText(TEXT)
            .setContentText(TEXT)
            .setFullScreenIntent(buildPendingIntent(context, intent), true);

    return(b);

}

private PendingIntent buildPendingIntent(Context context, Intent intent) {

    return(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
在开始时,一切都能完美地运行。但是如果我进入应用程序设置,关闭CHANNEL_WHATEVER的通知频道,然后再次打开它。稍后,当我调用NotificationManager.notify时,它会在通知抽屉中显示通知,但不会启动活动。如果我删除应用并重新安装,它又可以正常工作了。这是Android 10的一个错误吗?我应该报告它,还是有什么我可以做的?

在你禁用然后启用该频道之后,该频道上的所有其他选项是否与设置中的相同?如果由于禁用/启用循环而失去了该频道上的IMPORTANCE_HIGH,则您的症状匹配。 - CommonsWare
@CommonsWare 我怎样才能知道我是否失去了IMPORTANCE_HIGH?如果是这种情况,我该怎么办? - Simple UX Apps
1
"如果是这种情况,我能做些什么呢?"-- 除了可能提交错误报告之外,没有别的办法了。 "如何判断我是否丢失了IMPORTANCE_HIGH?"-- 在编程上,您应该能够查看mgr.getNotificationChannel(CHANNEL_WHATEVER)的结果,当它不为null时。调用getImportance()并记录您看到的值。 - CommonsWare
@CommonsWare 你说得对。重要性从IMPORTANCE_HIGH变成了IMPORTANCE_LOW。我会报告它。 - Simple UX Apps
@SimpleUXApps 我也遇到了同样的问题。你是如何成功解决它的呢?请发布或接受答案。 - Balasubramanian
8个回答

24

在Android 10中,我们需要在应用程序的清单文件中添加USE_FULL_SCREEN_INTENT权限。

全屏意图的权限更改

  • 针对 Android 10 或更高版本、并使用带有全屏意图的通知的应用程序必须在其应用程序的清单文件中请求USE_FULL_SCREEN_INTENT权限。

  • 这是一项普通权限,因此系统会自动将其授予请求的应用程序。

请确保已在清单文件中添加权限。

示例代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.nilu.demo">

    <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

1
大家好, 我正在使用这个权限但是却不能展示全屏意图。请帮忙解决一下,谢谢! - Tarun
@Tarun,你找到解决方案了吗?因为我现在也面临同样的问题 :/ - Kristiyan Varbanov
@KristiyanVarbanov 嘿...是的,我已经解决了,但全屏意图只会在一些手机上出现,因为它取决于操作系统...所以您必须添加一个后备的悬浮通知...你可以在红米手机上尝试,它将显示全屏意图。 - Tarun
针对我的特定需求,我添加了获取锁 - PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE。 - Dmitrijs
@Dmitrijs 你是从哪里获取这些锁的? - Dibzmania
显示剩余3条评论

4

即使您使用全屏意图,Android也不能保证显示活动:

在某些平台上,当用户正在使用设备时,系统 UI 可能选择显示一个悬浮通知,而不是启动该意图。


1
那么我们应该如何在Android 10上启动警报呢?据我所知,全屏意图是唯一的选择。 - Simple UX Apps
你是对的,这是唯一的选择,但正如我所说,系统可以决定不显示活动,而只显示一个悬浮通知。 - greywolf82
2
当屏幕打开且我的应用关闭时,系统会显示悬浮通知。之后我熄屏并查看全屏活动,为什么?这是一个错误吗? - Fereshteh Naji
@FereshtehNaji 不是这样。例如,当我们接到电话时,如果我们在使用手机,电话不会劫持整个屏幕。当手机没有被使用时,电话才会占据整个屏幕。这是类似的。 - Manish S
我也遇到了类似的问题。当你说使用Alarm时,是对通知或其他活动进行修改吗?如果有关于Alarm的参考资料,请提供。 - Ramesh

2

如果您想在锁屏界面上显示自己的活动,则需要在清单文件中启用showOnLockScreen。

<activity android:name="NewActivity" android:showOnLockScreen="true" /> 

并在您的活动类中设置showWhenLocked标志:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        setShowWhenLocked(true);
        setTurnScreenOn(true);
    }
}

最后使用您的活动类创建一个fullScreenIntent,并将其附加到通知中。
Intent fullScreenIntent = new Intent(applicationContext, NewActivity.class);
PendingIntent fullScreenPendingIntent = PendingIntent.getActivity(applicationContext, 0,
    fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(applicationContext, channel)
    .setSmallIcon(R.drawable.ic_small)
    .setContentTitle(textTitle)
    .setContentText(textContent)
    .setContentIntent(pendingIntent)
    .setPriority(NotificationCompat.PRIORITY_MAX)
    .setCategory(NotificationCompat.CATEGORY_ALARM)
    .setFullScreenIntent(fullScreenPendingIntent, true)
    .setAutoCancel(true);

在全屏活动的onCreate方法中添加setShowWhenLocked(true)和setTurnScreenOn(true)最终解决了我的问题。 - Rvb84
@Rvb84 你应该在super.onCreate()之前还是之后添加它? - Tamim Attafi
不应该有影响,我想。 - Rvb84

1

1
如果设备被锁定,全屏意图是否有效? - Dibzmania
@Bojke 请参考我的文章 https://medium.com/@dcostalloyd90/show-incoming-voip-call-notification-and-open-activity-for-android-os-10-5aada2d4c1e4 - Lloyd Dcosta
1
在你的文章中没有看到任何关于锁定屏幕上通知显示的相关内容。 - Dibzmania
无法正常工作。我已经拥有全屏意图权限,并且通知也完全按照文章中的方式设置。我可以接收广播,但是活动并没有启动。 - Alex

1

我不确定这个问题是否已经得到解答。除了之前提到的权限之外...我发现使它工作的唯一方法是使用“NotificationManager.IMPORTANCE_HIGH”通道和通知。设置为HIGH后,如果屏幕关闭,fullScreenIntent将会被打开。似乎稍后更改通道需要卸载并重新安装。

在发送通知之前设置通知通道(参见):

private static void createNotificationChannel(Context context) {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = **"YOUR CHANNEL"**;
            String description = "YOUR CHANNEL DESCRIPTION";
            int importance = **NotificationManager.IMPORTANCE_HIGH**;
            NotificationChannel channel = new NotificationChannel( "YOUR CHANNEL ID", name, importance);
            channel.setDescription(description);
            // Register the channel with the system; you can't change the importance
            // or other notification behaviors after this
            NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        }
    }

我设置了两个意图,不确定是否需要同时设置:

createNotificationChannel((context));
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, **"YOUR CHANNEL**");
    builder.setContentIntent(pendingIntent);
    builder.setFullScreenIntent(pendingIntent,true);

0

在显示通知之前,应唤醒Android屏幕:

fun asquireWake() {
    val mPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
    val mWakeLock: PowerManager.WakeLock = mPowerManager.newWakeLock(
        PowerManager.SCREEN_DIM_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP,
        "YourApp:Whatever"
    )
    mWakeLock.acquire()
}

0
在我的情况下,问题出在通知 ID 上,该 ID 用于显示全屏意图通知。
如果我们有先前使用相同通知 ID 的通知,则不会启动全屏意图活动,而是会在锁定屏幕上显示 Heads Up 通知。
因此,请尝试为全屏意图通知使用唯一的通知 ID。 有关如何设置全屏意图通知的更多信息,请参见:显示时间敏感通知

-1

对于那些遇到以下问题的人:

builder.setFullScreenIntent(pendingIntent,true)

请尝试改用:

builder.setContentIntent(pendingIntent)


setContentIntent 是用于在通知上点击的功能,而 setfullscreenintent 则是自动打开活动而无需点击的特性。 - Rahman Rezaee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接