棒棒糖通知setVisibility()不起作用?

时间:2014-11-14 14:40:55

标签: android android-notifications android-5.0-lollipop

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

  • 默认VISIBILITY_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工作,主要是因为您有机会返回锁定屏幕以查看结果。以下是由BroadcastReceiver触发的AlarmManager(显示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是根据活动中的Spinner设置的。这个逻辑似乎没问题,因为单挑Notification场景效果很好。如果我单步执行代码(例如,onReceive()中的断点),我会看到它通过正确的路径(例如,当我选择提出一个秘密时,在setVisibility(NotificationCompat.VISIBILITY_SECRET)中调用notifySecret() { {1}})。

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

有什么建议吗?

3 个答案:

答案 0 :(得分:8)

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

此设置有三个选项:

  • 显示所有通知内容有效公开所有通知(无论公开程度如何)。

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

  • 根本不显示通知会使所有通知都有效保密。

更改锁屏通知可见性的选项位于声音和放大器的设备设置中。通知> "设备被锁定",如下所示。

作为Selvin noted in his answer,隐藏敏感内容的选项仅在您设置了某种设备锁定(例如PIN或模式锁定)时才可用。如果您只需轻扫一下锁屏就可以解锁设备,则此选项不可用。

答案 1 :(得分:0)

设置 using (var logReader = new EventLogReader(query, EventBookmark)) 还可以防止在锁定屏幕上显示通知。

令人惊讶,但至少它有很好的记录。

答案 2 :(得分:-4)

除了Tanis.7x的回答:你必须选择除了滑动以外的任何锁屏保护到"隐藏敏感通知内容"选项出现在Sound&通知