应用程序运行时如何在状态栏中显示图标,包括在后台?

Posted

技术标签:

【中文标题】应用程序运行时如何在状态栏中显示图标,包括在后台?【英文标题】:How to show an icon in the status bar when application is running, including in the background? 【发布时间】:2011-04-27 18:09:29 【问题描述】:

我想在我的应用程序运行时在状态栏中放置一个图标,包括在后台运行时。我该怎么做?

【问题讨论】:

【参考方案1】:

您应该可以使用 Notification 和 NotificationManager 来执行此操作。然而,获得有保证的方法来了解您的应用程序何时未运行是困难的部分。

您可以通过执行以下操作来获得所需的基本功能:

Notification notification = new Notification(R.drawable.your_app_icon,
                                             R.string.name_of_your_app, 
                                             System.currentTimeMillis());
notification.flags |= Notification.FLAG_NO_CLEAR
                   | Notification.FLAG_ONGOING_EVENT;
NotificationManager notifier = (NotificationManager)
     context.getSystemService(Context.NOTIFICATION_SERVICE);
notifier.notify(1, notification);

此代码必须位于您确定应用程序启动时会被触发的位置。可能在您应用程序的自定义应用程序对象的 onCreate() 方法中。

但之后事情就变得棘手了。应用程序的终止可能随时发生。所以你也可以尝试在 Application 类的 onTerminate() 中放一些东西,但不保证会被调用。

((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE)).cancel(1);

将是删除图标所需要的。

【讨论】:

Notification 在 API 级别 11 中已弃用。请改用 Notification.Builder。 如果您还使用Service,则不必手动删除通知。当服务停止时,通知将自动删除。 (“但是,如果您在服务仍在前台运行时停止服务,则通知也会被删除。”developer.android.com/guide/components/services.html#Foreground)【参考方案2】:

对于新的 API,您可以使用 NotificationCompat.Builder -

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.mipmap.ic_launcher)
    .setContentTitle("Title");
Intent resultIntent = new Intent(this, MyActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;

mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(NOTIFICATION_ID, notification);

只要您的应用程序正在运行并且有人手动关闭您的应用程序,它就会显示。您可以随时致电取消通知 -

mNotifyMgr.cancel(NOTIFICATION_ID);

【讨论】:

MyActivity.class 的内容是什么? @mjosh @Sarahcartenz 任何你想要的东西 如果我不定义这样的类怎么办?或保持为空。例如,一旦按下通知,我就不想采取行动。 删除此行mBuilder.setContentIntent(resultPendingIntent);【参考方案3】:

查看开发指南“Creating Status Bar Notifications”。

实现仅在应用程序运行时保留图标的目标的一种方法是在onCreate() 中初始化通知,并仅在isFinishing() 返回true 时在onPause() 方法中调用cancel(int)

一个例子:

private static final int NOTIFICATION_EX = 1;
private NotificationManager notificationManager;

@Override
public void onCreate() 
    super.onCreate();

    notificationManager = (NotificationManager) 
        getSystemService(Context.NOTIFICATION_SERVICE);

    int icon = R.drawable.notification_icon;
    CharSequence tickerText = "Hello";
    long when = System.currentTimeMillis();

    Notification notification = new Notification(icon, tickerText, when);

    Context context = getApplicationContext();
    CharSequence contentTitle = "My notification";
    CharSequence contentText = "Hello World!";
    Intent notificationIntent = new Intent(this, MyClass.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 
        0, notificationIntent, 0);

    notification.setLatestEventInfo(context, contentTitle, 
        contentText, contentIntent);

    notificationManager.notify(NOTIFICATION_EX, notification);


@Override
protected void onPause() 
    super.onPause();
    if (isFinishing()) 
        notificationManager.cancel(NOTIFICATION_EX);
    

【讨论】:

这只会显示给定活动是否正在运行。如果应用程序仍在运行,则不会。 @Greg:是的,此示例代码仅正确处理单活动应用程序。确定系统何时终止应用程序要困难得多。正如您所提到的,自定义 Application 类可能是代码的最佳位置,因为它会在应用程序的整个生命周期中持续存在。清除通知会很困难,因为系统可能会在内存不足的情况下任意决定终止应用程序的进程。您可以尝试创建一个服务来监控状态,因为系统稍后会在有更多可用内存时尝试重新启动该服务。 如果您从onPause 中删除notificationManager.cancel(NOTIFICATION_EX);,通知将保留在通知栏中,直到应用程序完全停止。【参考方案4】:

确实有效。 我根据上面的示例创建了一个方法:

private void applyStatusBar(String iconTitle, int notificationId) 
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(iconTitle);
Intent resultIntent = new Intent(this, ActMain.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_NO_CLEAR|Notification.FLAG_ONGOING_EVENT;

NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(notificationId, notification);

应该这样调用:applyStatusBar("Statusbar Test", 10);

【讨论】:

如果我可以问,ActMain.class 的内容是什么?

以上是关于应用程序运行时如何在状态栏中显示图标,包括在后台?的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 iPhone / iPad 的状态栏中显示播放图标

CoreLocation 图标停留在状态栏中

Blackberry - 如何在状态栏中使用通知图标

为啥我的 phongap 应用程序在 android 状态栏中显示一个汉堡包图标?

FCM 推送通知在返回应用程序时打开,而不是在 iOS 的状态栏中显示

如何使定位服务图标从状态栏中消失?