【问题标题】:Hide notification of foreground service while activity is visible活动可见时隐藏前台服务通知
【发布时间】:2014-03-30 18:21:56
【问题描述】:

他们是否可以将服务作为前台服务启动并在活动可见时隐藏通知?

考虑一个音乐播放器,当应用程序打开时,您不需要通知(即按钮),但只要音乐播放器在后台,就应该显示通知。

我知道该怎么做,如果我不在前台运行我的服务...但是在前台运行时,服务本身需要通知并显示它,我无法自己管理通知。 ..

我该如何解决这个问题?

【问题讨论】:

    标签: android service notifications foreground


    【解决方案1】:

    你可以这样做。此方法的一个先决条件是,您的活动必须绑定服务。

    首先你启动服务前台。

    private Notification mNotification;
    
    public void onCreate() {
       ...
       startForeground(1, mNotification);
    }
    

    然后在您的活动中绑定和取消绑定服务,如下所示。 BIND_ADJUST_WITH_ACTIVITY 对于在绑定到可见活动时保持服务活动非常重要。

    public void onStart() {
        ...
        Intent intent = new Intent(this, PlayerService.class);
        bindService(intent, mConnection, BIND_ADJUST_WITH_ACTIVITY);
    }
    
    public void onStop() {
        ...
        unbindService(mConnection);
    }
    

    现在这是最后的过去。当至少一个客户端连接到服务时,您停止前台,当最后一个客户端断开连接时,您启动前台。

    @Override
    public void onRebind(Intent intent) {
        stopForeground(true); // <- remove notification
    }
    
    @Override
    public IBinder onBind(Intent intent) {
        stopForeground(true); // <- remove notification
        return mBinder;
    }
    
    @Override
    public boolean onUnbind(Intent intent) {
        startForeground(1, mNotification); // <- show notification again
        return true; // <- important to trigger future onRebind()
    }
    

    绑定服务时,您必须考虑 Android 应用的规则。如果绑定一个未启动的服务,服务将不会自动启动,除非您在BIND_ADJUST_WITH_ACTIVITY 标志之外指定BIND_AUTO_CREATE 标志。

        Intent intent = new Intent(this, PlayerService.class);
        bindService(intent, mConnection, BIND_AUTO_CREATE 
                | BIND_ADJUST_WITH_ACTIVITY);
    

    如果服务是在开启自动创建标志的情况下启动的,并且最后一个客户端取消绑定,那么服务将自动停止。如果您想保持服务运行,您必须使用startService() 方法启动它。基本上,您的代码将如下所示。

        Intent intent = new Intent(this, PlayerService.class);
        startService(intent);
        bindService(intent, mConnection, BIND_ADJUST_WITH_ACTIVITY);
    

    为已启动的服务调用startService() 对其没有影响,因为我们不会覆盖onCommand() 方法。

    【讨论】:

    • 似乎做我想做的...只有一个缺点,我必须在我真正需要它之前启动服务...
    • 刚刚完成实施。它应该运作良好。答案已更新。
    • 我之前试过了,效果不理想...我会检查更改并再次查看...顺便说一下,不绑定服务并在活动 onPause/onResume 更改服务的前台状态将不起作用,因为服务可能会在活动处于活动状态时被杀死?这真的会发生吗?还是这样也行?
    • 我的项目中也需要它,所以我让它工作了。 onUnbind() 返回 true,onRebind() 隐藏通知。关于你的问题。绑定服务是必须的。如果它没有被束缚,它可以以更高的概率被杀死。这确实发生在容量或 RAM 较小的设备上。
    • 还有一个问题...... startService 说,它将覆盖由 onBind 管理的默认服务生命周期......但你说,onBind THOUGH 是必要的,以保持服务活着?
    【解决方案2】:

    使用以下步骤:

    1.使用ActivityManager获取当前包名(即上面运行的Activity)。

    2.检查它是否是您的应用程序然后不显示通知

    3.else 如果不是您的应用程序,则显示通知。

    ActivityManager manager =(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                                List<ActivityManager.RunningTaskInfo> tasks = manager.getRunningTasks(1);
                                String topActivityName = tasks.get(0).topActivity.getPackageName();
                                if(!(topActivityName.equalsIgnoreCase("your package name"))){
     //enter notification code here
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-03
      • 1970-01-01
      相关资源
      最近更新 更多