android - Lollipop 通知 setVisibility() 不起作用?

标签 android android-notifications android-5.0-lollipop

我正在尝试编写一个演示,使用 setVisibility() 来控制 Android 5.0 锁屏上显示的 Notification 内容。但是,似乎没有效果:

  • 默认的 VISIBILITY_PRIVATE 仍然显示私有(private) Notification,而不是其公开对应项

  • VISIBILITY_SECRET 通知仍显示在锁屏上

IOW,所有的行为都好像 VISIBILITY_PUBLIC 生效了,至少当我在运行 Android 5.0 镜像的 Nexus 7 上进行测试时,我们在 Android 5.0 发布后不久(构建 LPX13D)就得到了我们。所以我不知道问题是否与我的代码、此设备或 Android 中的错误有关。

我有两个版本的相同示例应用程序:

  • One使用 NotificationCompatNotificationManagerCompat

  • The other使用 NotificationNotificationManagerminSdkVersion 为 21,targetSdkVersion 为 21

(请注意,这些项目主要在 Android Studio 中使用;Eclipse 用户可以导入这些项目,但可能需要进行一些小的修复,特别是对于第一个示例对 support-v13 库的引用)

示例使用 AlarmManager 来触发 Notification 工作,主要是让您有机会返回锁屏查看结果。这是由 AlarmManager 触发的 BroadcastReceiver(显示 NotificationCompat 版本):

/***
 Copyright (c) 2014 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 From _The Busy Coder's Guide to Android Development_
 http://commonsware.com/Android
 */

package com.commonsware.android.lollipopnotify;

import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;

public class AlarmReceiver extends BroadcastReceiver {
  private static final int NOTIFY_ID=1337;
  static final String EXTRA_TYPE="type";

  @Override
  public void onReceive(Context ctxt, Intent i) {
    NotificationManagerCompat mgr=NotificationManagerCompat.from(ctxt);

    switch (i.getIntExtra(EXTRA_TYPE, -1)) {
      case 0:
        notifyPrivate(ctxt, mgr);
        break;

      case 1:
        notifyPublic(ctxt, mgr);
        break;

      case 2:
        notifySecret(ctxt, mgr);
        break;

      case 3:
        notifyHeadsUp(ctxt, mgr);
        break;
    }
  }

  private void notifyPrivate(Context ctxt, NotificationManagerCompat mgr) {
    Notification pub=buildPublic(ctxt).build();

    mgr.notify(NOTIFY_ID, buildNormal(ctxt).setPublicVersion(pub).build());
  }

  private void notifyPublic(Context ctxt, NotificationManagerCompat mgr) {
    mgr.notify(NOTIFY_ID,
        buildNormal(ctxt)
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
            .build());
  }

  private void notifySecret(Context ctxt, NotificationManagerCompat mgr) {
    mgr.notify(NOTIFY_ID,
        buildNormal(ctxt)
            .setVisibility(NotificationCompat.VISIBILITY_SECRET)
            .build());
  }

  private void notifyHeadsUp(Context ctxt, NotificationManagerCompat mgr) {
    mgr.notify(NOTIFY_ID,
        buildNormal(ctxt)
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .build());
  }

  private NotificationCompat.Builder buildNormal(Context ctxt) {
    NotificationCompat.Builder b=new NotificationCompat.Builder(ctxt);

    b.setAutoCancel(true)
        .setDefaults(Notification.DEFAULT_ALL)
        .setContentTitle(ctxt.getString(R.string.download_complete))
        .setContentText(ctxt.getString(R.string.fun))
        .setContentIntent(buildPendingIntent(ctxt, Settings.ACTION_SECURITY_SETTINGS))
        .setSmallIcon(android.R.drawable.stat_sys_download_done)
        .setTicker(ctxt.getString(R.string.download_complete))
        .addAction(android.R.drawable.ic_media_play,
            ctxt.getString(R.string.play),
            buildPendingIntent(ctxt, Settings.ACTION_SETTINGS));

    return(b);
  }

  private NotificationCompat.Builder buildPublic(Context ctxt) {
    NotificationCompat.Builder b=new NotificationCompat.Builder(ctxt);

    b.setAutoCancel(true)
        .setDefaults(Notification.DEFAULT_ALL)
        .setContentTitle(ctxt.getString(R.string.public_title))
        .setContentText(ctxt.getString(R.string.public_text))
        .setContentIntent(buildPendingIntent(ctxt, Settings.ACTION_SECURITY_SETTINGS))
        .setSmallIcon(android.R.drawable.stat_sys_download_done)
        .addAction(android.R.drawable.ic_media_play,
            ctxt.getString(R.string.play),
            buildPendingIntent(ctxt, Settings.ACTION_SETTINGS));

    return(b);
  }

  private PendingIntent buildPendingIntent(Context ctxt, String action) {
    Intent i=new Intent(action);

    return(PendingIntent.getActivity(ctxt, 0, i, 0));
  }
}

EXTRA_TYPE 是从 Activity 中的 Spinner 设置的。这个逻辑似乎没问题,因为单挑 Notification 场景工作得很好。如果我单步执行代码(例如,onReceive() 中的断点),我会看到它通过正确的路径(例如,调用 setVisibility(NotificationCompat.VISIBILITY_SECRET) notifySecret() 当我选择提出一个 secret Notification).

因此,我不知道为什么我在 Android 5.0 锁屏上没有获得可见性效果。

有什么建议吗?

最佳答案

您描述的行为与我将锁屏通知首选项设置为“显示所有通知内容”时遇到的行为一致。

此设置有三个选项:

  • 显示所有通知内容使所有通知(无论是否可见)有效地公开。

  • 隐藏敏感通知内容尊重新的可见性类型。

  • 根本不显示通知将使所有通知有效地保密。

更改锁屏通知可见性的选项位于设备设置中的声音和通知>“设备锁定时”下,如下所示。

作为 Selvin noted in his answer ,隐藏敏感内容的选项仅在您设置了某种设备锁定(例如 PIN 或图案锁定)时可用。如果您可以通过简单地滑动锁定屏幕来解锁您的设备,则此选项不可用。

关于android - Lollipop 通知 setVisibility() 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26932457/

相关文章:

android - 未看到 Fragment 的进入和退出转换

android - 如何为用户选择从不的应用重新启用位置权限?

java - Android 随机数 llegalArgumentException : n <= 0: 0

android - 在bar中绘制bar的值

android - 在android上使用OpenGL绘制文字

android - 从 Notification Intent 开始时保持 Activity 状态

android - 蜂窝通知 - 如何将 largeIcon 设置为正确的大小?

java - 如何在其他 Activity 中发送从二维码扫描仪读取的字符串

java - 半展开折叠工具栏

Android 按钮通知,如消息按钮