【问题标题】:Android run service as long as App is in use只要 App 在使用中,Android 就会运行服务
【发布时间】:2015-01-17 17:28:14
【问题描述】:

我正在开发一个应用程序,我正在使用一项服务来播放背景音乐。 音乐仅在应用程序正在使用时播放,即在前台。 当我使用主页按钮或返回按钮离开应用程序时,音乐将停止(应用程序可能会留在后台但不可见 -> 没有音乐)。 当我重新进入应用程序(使用主页按钮并切换回应用程序)时,音乐也会恢复。

我的服务:

public class MusicService extends Service {

MediaPlayer myPlayer;
private final IBinder localBinder = new LocalBinder();

public class LocalBinder extends Binder {

    MusicService getService() {
        return MusicService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return localBinder;
}

public boolean onUnbind(Intent intent) {
    return true;
    // called when the last Activity is unbound from this service
    // stop your timed operations here
}


@Override
public void onCreate() {
    Toast.makeText(this, "Music Service Created", Toast.LENGTH_LONG).show();
    myPlayer = MediaPlayer.create(this, R.raw.ost);
    myPlayer.setLooping(true); // Set looping
}

@Override
public void onDestroy() {
    Toast.makeText(this, "Music Service Stopped", Toast.LENGTH_LONG).show();
    myPlayer.stop();
}

@Override
public void onStart(Intent intent, int startid) {
    Toast.makeText(this, "Music Service Started", Toast.LENGTH_LONG).show();
    if(!myPlayer.isPlaying())
        myPlayer.start();
}

}

我还在为所有活动使用父类。在那个父类中,我想在方法 onPause() 和 onStop() 上停止服务:

ComponentName topActivity = taskInfo.get(0).topActivity; 
      if(!topActivity.getPackageName().equals(getApplicationContext().getPackageName())) {
          stopService(new Intent(this, MusicService.class));

我在启动器活动中启动服务

startService(new Intent(this, MusicService.class));
        Intent intent = new Intent(this, MusicService.class);
        bindService(intent, this, 0);

现在我的问题:当我按下主页按钮时服务不会停止,当我离开应用程序时服务不会停止(返回按钮)。 当我杀死应用程序的任务时,服务会在几秒钟后再次启动,音乐将一直播放,直到我在设置中强制应用程序停止服务或卸载应用程序。

那么,当应用程序处于不可见背景或关闭时,如何完全关闭服务?我在这里经历了几个线程,youtube视频,教程并尝试了很多。我也尝试了非服务解决方案,但我无法解决问题。

谢谢!

【问题讨论】:

  • Service只在你想做一些后台任务时使用,因为你不需要后台任务,所以你不应该使用Service,而应该在Application级别使用MediaPlayer控件
  • 然后我必须在启动新 Activity 时停止媒体播放器并在新 Activity 上再次启动播放器。
  • 否,在应用层创建 MediaPlayer 对象时,您可以在任何屏幕中导航到任何屏幕,播放器将一直播放直到您停止/暂停它
  • 你只播放一首歌吗?或更改某些活动的歌曲?
  • 这只是一首 20 秒的歌曲,永远重复。

标签: android service


【解决方案1】:

实现此功能的替代方式在这里,但是使用服务实现是标准方式

创建一个如下所示的 ApplicationContextHolder 类

public class ApplicationContextHolder extends Application {

    public static ApplicationContextHolder instance;

    public MediaPlayer mediaPlayerHome = new MediaPlayer();

    public static ApplicationContextHolder getAppInstance() {

        return instance;
    }

    public ApplicationContextHolder() {
        instance = this;
    }

    public void saveLastPlayingSongPath(String filePath) {
        songHolder = this.getSharedPreferences("songPath", 0);
        Editor editor = songHolder.edit();
        editor.putString("path", filePath);
        editor.commit();
    }


    public MediaPlayer getMediaPlayerForHome(Context ctx, int id) {
        return mediaPlayerHome = MediaPlayer.create(ctx, id);
    }

    public void stopMediaPlayerHome()

    {
        if (mediaPlayerHome != null && mediaPlayerHome.isPlaying()) {
            mediaPlayerHome.stop();
            mediaPlayerHome.reset();

        }
    }

    public void pauseMediaPlayerHome() {
        if (mediaPlayerHome != null && mediaPlayerHome.isPlaying()) {
            mediaPlayerHome.pause();

        }
    }

    public void startMediaPlayerHome() {
        if (mediaPlayerHome != null)
            mediaPlayerHome.start();
    }


}

现在,如何使用这个类 1) 在您拥有媒体播放器的 Activity/Fragment 中创建此类的对象和 MediaPlayer 本地对象,或者您可以在 MainActivity 中创建它

private ApplicationContextHolder App;
private MediaPlayer mMediaPlayer;

2)在 OnCreate 中初始化对象

App = ApplicationContextHolder.getAppInstance();
mMediaPlayer = App.getMediaPlayerForHome(getActivity(),
                R.raw.new_introduction);

3) 最后如果你想播放音乐播放器

App.startMediaPlayerHome();

4) 并覆盖最后一个 Activity 的 OnDestory(),如果按下后退按钮,应用程序将关闭

public void onDestroy() {

        try {
            App.stopMediaPlayerHome();

        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }

这只是基本原理,但是您可以使用 setLooping() / Pause();以及所有需要的方法

最后一步是在你的 Manifest.xml 中的 Application Tag 的第一行中注册这个类,如下所示

  <application
        android:name="yourpackagename.ApplicationContextHolder"

这是一个实时应用的工作代码,所以请试一试

对于主页按钮事件,您必须在每个活动中使用以下代码 编辑:此代码现在在您按 Home 时暂停媒体播放器,

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_HOME)) {
            System.out.println("KEYCODE_HOME");
             try {
        App.pauseMediaPlayerHome();

    } catch (IllegalStateException e) {
        e.printStackTrace();
    }
            return true;
        }
    return false;
}

假设如果您想在应用程序恢复时恢复音乐,您必须检查特定活动中的布尔值

if (mediaplayerPaused)
App.startMediaPlayerHome();

【讨论】:

  • 非常感谢您的付出。我会尽快尝试的。
  • 好的,我测试了一下,遇到了以下问题。按下主页按钮时音乐继续播放。当我切换到另一个活动并按下后退按钮直到应用关闭时音乐继续播放(但我在上一个活动中使用了像你一样的 onDestroy 方法)。
  • @AlcuPala ,更新了我的答案,没有得到你的第二点..!
  • 尝试了 onKeyDown。没有改变任何东西。通过设备上的主页按钮离开应用程序时仍会播放音乐。 Activity_1=启动器活动:这里我启动音乐播放器并播放音乐。我切换到 Activity_2。音乐仍在播放。然后我按设备上的后退按钮。音乐仍在播放(应该如此)。然后我再按一次后退按钮。应用关闭,音乐继续播放。
  • 谢谢。我将尝试在 onPause() 处使用 isFinished。非常感谢您的宝贵时间!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多