可绑定(bind)的Android前台服务

标签 android service android-activity

做前台服务的正确方法是什么,我可以稍后绑定(bind)到它? 我遵循了 Android API 演示,其中包括一个如何创建前台服务的示例。 没有同时绑定(bind)到它的启动服务的例子。

我想看一个“绑定(bind)” Activity 的音乐播放器服务的好例子。

有没有?

我想做这样的事情:

  • 当一个程序第一次启动时(首先意味着服务还没有启动)我想启动前台服务来完成所有的工作。用户界面( Activity )只是为了控制那个工作
  • 如果用户按下主页按钮,服务必须保持运行(并且栏中的通知必须存在)
  • 现在,如果用户点击通知栏中的通知,activity 应该启动并绑定(bind)到服务(或类似的东西,正确的方式),用户将控制该工作。
  • 如果 Activity 处于 Activity 状态并且用户按下后退按钮 Activity 应该被销毁,服务也应该被销毁。

我必须覆盖哪些方法才能完成此任务? Android 的做法是什么?

最佳答案

在 froyo 之前,Service 中有 setForeground(true),这很简单,但也很容易被滥用。

现在有需要激活通知的 startForeGround 服务(这样用户就可以看到正在运行的前台服务)。

我做了这个类来控制它:

public class NotificationUpdater {
    public static void turnOnForeground(Service srv,int notifID,NotificationManager mNotificationManager,Notification notif) {
        try {
            Method m = Service.class.getMethod("startForeground", new Class[] {int.class, Notification.class});
            m.invoke(srv, notifID, notif);
        } catch (Exception e) {
            srv.setForeground(true);
            mNotificationManager.notify(notifID, notif);
        }
    } 

    public static void turnOffForeground(Service srv,int notifID,NotificationManager mNotificationManager) {
        try {
            Method m = Service.class.getMethod("stopForeground", new Class[] {boolean.class});
            m.invoke(srv, true);
        } catch (Exception e) {
            srv.setForeground(false);
            mNotificationManager.cancel(notifID);
        }
    }
}

然后对于我的媒体播放器,此更新通知 - 请注意,只有在播放媒体时才需要前台服务,并且应该在媒体播放停止后保持打开状态,这是一种不好的做法。

private void updateNotification(){
    boolean playing = ((mFGPlayerBean.getState()==MediaPlayerWrapper.STATE_PLAYING) || 
                        (mBGPlayerBean.getState()==MediaPlayerWrapper.STATE_PLAYING));
    if (playing) {
        Notification notification = getNotification();
        NotificationUpdater.turnOnForeground(this,Globals.NOTIFICATION_ID_MP,mNotificationManager,notification);
    } else {
        NotificationUpdater.turnOffForeground(this,Globals.NOTIFICATION_ID_MP,mNotificationManager);
    }
}

至于绑定(bind)——您只需在您的 Activity onStart 中以正常方式进行绑定(bind),您只需调用 bindService 调用,就像您绑定(bind)到任何服务一样(它是否在前台并不重要)

MediaPlayerService mpService=null;
@Override
protected void onEWCreate(Bundle savedInstanceState) {
     Intent intent = new Intent(this, MediaPlayerService.class);
     startService(intent);
}

@Override
protected void onStart() {
    // assume startService has been called already
    if (mpService==null) {
        Intent intentBind = new Intent(this, MediaPlayerService.class);
        bindService(intentBind, mConnection, 0);
    }
}

private ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        mpService = ((MediaPlayerService.MediaBinder)service).getService();
    }

    public void onServiceDisconnected(ComponentName className) {
        mpService = null;
    }
};

关于可绑定(bind)的Android前台服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5383300/

相关文章:

android - ionic - 错误 : No resource found that matches the given name (at ‘dialogCornerRadius’ with value ‘?android:attr/dialogCornerRadius’ )

android - 如何将静态处理程序与服务/Activity 一起使用?

android - 使用 MediaRecorder 录制屏幕特定 View

android - onPause() 是否保证被调用,即使在强制关闭应用程序进程时也是如此?

android - 使用长按 Home 键时,android 2.1 中 ActivityManger 中的错误

java - 让文本到语音 Activity 在点击时同时工作转到新的 xml

android - Gradle 在尝试集成 Sentry 时抛出 API 警告

android - 如何在不同进程中建立Activity和Service之间的双向通信?

java - Android Activity 上下文 NullPointerException

android - 获取正在运行的进程列表并终止其后台服务