【问题标题】:Show just small icon in status bar without showing notification在状态栏中仅显示小图标而不显示通知
【发布时间】:2016-09-18 03:11:02
【问题描述】:

我想在status bar 中不断显示小图标,而不在系统的notification 托盘上显示通知本身。

我尝试使用自定义layout 并将根元素的可见性设置为View.GONE 或View.INVISIBLE,但对于两者,系统都会忽略它。

我也尝试设置根元素的高度,但系统也忽略了这一点。

这是我的代码:

R.layout.custom_notification:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/custom_notification"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/notif_background"
    android:orientation="horizontal"
    android:baselineAligned="false"/>

以及显示Notification的代码:

 NotificationManager nm = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
 NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(ctx);
 mBuilder
         .setSmallIcon(drawableId)
         .setAutoCancel(false)
         .setOngoing(true)
         .setPriority(Notification.PRIORITY_MAX);
 Intent resultIntent = new Intent(ctx, SettingsActivity.class);
 PendingIntent resultPendingIntent = PendingIntent.getActivity(ctx, 0, resultIntent, 0);
 mBuilder.setContentIntent(resultPendingIntent);
 int layout =  R.layout.custom_notification ;
 RemoteViews contentView = new RemoteViews(ctx.getPackageName(), layout);
 contentView.setViewVisibility(R.id.custom_notification, View.INVISIBLE);
 mBuilder.setContent(contentView);
 nm.notify(NOTIFICATION_ID, mBuilder.build());

我很清楚,为了实现我的目标,我不需要记录解决方案。而且我也知道用户体验指南强烈建议不要做这样的事情。所以没有必要给我写这个作为答案。

【问题讨论】:

  • 您想在应用启动时设置这个小图标并保持不变?
  • Afaik 你在寻找什么它不可能在通知区域中没有永久通知。这只有在定制的安卓系统上才有可能,所以对你没有用处
  • @mwisnicki 是的,完全正确。它已经很好用了,我只是在寻找一种方法来摆脱托盘中的通知并只显示小图标。
  • @Tazz 我很清楚这不是一件容易解决的事情,因为我花了半年多的时间寻找绕过这个限制的方法。
  • @yshahak 您不能为此使用通知,它们不是这样设计的,唯一想到的解决方案是在屏幕上绘制一个图标并将其放在通知托盘区域并计算如何您通过 NotificationListener 收到的许多通知(您需要用户的权限)因此您将图标向右移动,否则它将与该图标重叠。您还需要用户的权限才能在屏幕上绘制。在这里查看如何在其他应用上绘图:stackoverflow.com/questions/20461979/…

标签: android android-layout notifications


【解决方案1】:

根据开发人员文档,在不显示任何相关通知的情况下显示图标并不是一个好主意,

状态栏通知需要以下所有条件:

  • 状态栏图标(您感兴趣的)
  • 展开视图的标题和展开消息(除非您定义了自定义展开视图)
  • PendingIntent,当点击通知显示相关信息时触发。

因此,如果您不想破坏用户体验,那么强烈建议您遵循 UX 指南,

逻辑上:状态栏有两个部分——用户(通知)和系统(其他)。如果系统允许在系统部分放一些东西——会有很多无用的图标(由其他应用程序发布),并且没有一致性,可能会破坏所有的使用体验。

找到一个答案,它为您提供访问警报默认状态栏图标的方法,它是here。在 Root 你的手机之后你就可以做到了。youtube上有一些技巧,关于同一主题的一些答案建议使用通知显示图标,但将通知文本留空,以便用户只能看到图标,但它又不是方式。

This is code 用于描述左右图标(即系统图标)的系统中的状态栏实现,您可以从那里获得一些线索。描述它的答案是here。

【讨论】:

  • 谢谢,我很清楚您写的关于需要遵循 UX 指南的内容。如果我没有充分的理由这样做,我不会寻求解决方案。我在这个应用程序上工作了 6 个多月。无论如何,涉及植根手机的解决方案不是我想要的。也不是将空通知放在托盘上的解决方案。
  • 是的,我知道,所以我在最后一句中添加了“但这又不是一种方法。”我认为它应该是粗体.. :) @yshahak
  • 再次感谢。我仔细阅读了你提到的问题和答案,虽然很有趣,但这不是我需要的方向,因为我的应用程序不是system app,而且我无权访问源代码。
  • 好吧,据我所知,我已经尽力了,有一些可以自定义状态栏的应用程序,您应该寻找它们。也许你可以引导正确的方向。 ?
【解决方案2】:

我建议不要将其用于通常的 Google Play 应用程序。 有几个原因:

  1. 如果您发现一个有助于显示不可见通知的错误,它似乎什么都没有。该错误仅适用于具有特定 Android 版本的部分设备。请记住:要在大多数使用开放 API 的设备中正确执行常规代码是非常非常困难的。隐藏的 API 并不适用于所有设备。

    1. 源代码中没有这样的行为:http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/app/NotificationManager.java#NotificationManager.notify%28int%2Candroid.app.Notification%29。你找不到这样的行为。

    2. 为了可预测的行为,请使用 Android 的 *Compat 类。也就是说,仅用于通知NotificationCompat 类!只有使用 wrapper 才能帮助您的应用显示通知。

    3. 这是非常丑陋的 UI/UX。

    4. 通知的工作流程很大程度上取决于 Android 版本。

【讨论】:

    【解决方案3】:

    您可以使用InputMethodService.showStatusIcon() 执行此操作。但我建议你显示正常的通知并向用户解释你的应用现在在做什么。

    【讨论】:

    • 我不想让通知出现在托盘上是有原因的,基本上是因为小图标意味着 24/7 都呆在那里(例如系统电池图标)。跨度>
    • 您能解释一下如何使用InputMethodService.showStatusIcon() 完成它吗?显然,我目前与 InputMethodService 无关
    【解决方案4】:

    您可以使用 RemoteViews 隐藏标题和文本

    R.id.notification_layout.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:layout_marginRight="10dp"
            android:layout_marginLeft="7dp"
            android:src="@drawable/icon_battery" />
    </RelativeLayout>
    

    在 MainActivity 中:

    RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification_layout);
    Context application = getApplicationContext();
    
    Intent resultIntent = new Intent(application, MainActivity.class);
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    PendingIntent resultPendingIntent = PendingIntent.getActivity(application, 0, resultIntent, 0);
    NotificationManager nmgr = (NotificationManager) application.getSystemService(Context.NOTIFICATION_SERVICE);
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(application)
                .setSmallIcon(R.drawable.icon_battery);
    
    mBuilder.setContent(contentView);
    Notification mNotification = mBuilder.build();
    
    //  mNotification.flags |= FLAG_NO_CLEAR;
    nmgr.notify(0, mNotification);
    

    【讨论】:

      【解决方案5】:

      迟到但可能对其他人有用。

      在我的情况下,它非常简单,只需在您的主要自定义布局中使用高度 0dp,例如

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout" android:layout_width="fill_parent" android:layout_height="0dp">

      wrap_content 在这里不起作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-10
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多