【问题标题】:Music service not working after some second when app in background in Oreo当应用程序在奥利奥后台运行时,音乐服务在几秒钟后无法正常工作
【发布时间】:2018-03-12 07:22:54
【问题描述】:

如何在奥利奥后台运行服务?此服务类在 Oreo 以下的所有 Android 版本中运行良好,我在清单中声明了此服务。在我的活动课程中,我使用startservice(getApplicationContext,ExoService.class) 启动。

public class ExoService extends Service {
private static Context context;
private static ItemRadio station;
private static ExoService service;
public static SimpleExoPlayer exoPlayer;
private static Uri uri;
private WifiManager.WifiLock wifiLock;
static ProgressTask task;

/*binder return null*/

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    task = new ProgressTask();
    task.execute();
    return START_STICKY;
/*Alrady set Start Sticky*/

 }

/*here is initilize service class*/

static public void initialize(Context context, ItemRadio station) {
    ExoService.context = context;
    ExoService.station = station;
    Log.e("inwhich", "");
}

/*this is my service instance*/

static public ExoService getInstance() {
    if (service == null) {
        service = new ExoService();
    }
    return service;
}

/*Oncreate method */

@Override
public void onCreate() {
    super.onCreate();
    try {
        TrackSelector trackSelector = new DefaultTrackSelector();
        LoadControl loadControl = new DefaultLoadControl();
        exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector, loadControl);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
}

/*public void stop() {
    if (exoPlayer != null && exoPlayer.getPlayWhenReady()) {
        exoPlayer.stop();
        exoPlayer.release();
        exoPlayer = null;
        this.wifiLock.release();
        this.stopForeground(true);
    }
}*/

public void start() {
    if (exoPlayer != null) {
        exoPlayer.setPlayWhenReady(true);
    }
}

/*after some second ondstroy method call in oreo.*/

public void onDestroy() {
    if (exoPlayer != null) {
        exoPlayer.stop();
    }
    Log.e("Destroyed", "Called");

}

/*public void pause() {
    if (exoPlayer != null) {
        exoPlayer.stop();
        // exoPlayer.setPlayWhenReady(false);
    }
}*/

public ItemRadio getPlayingRadioStation() {
    return station;
}

解码歌曲url的异步任务:

@SuppressLint("StaticFieldLeak")
private class ProgressTask extends AsyncTask<String, Void, Boolean> {

    protected void onPreExecute() {
    }

    protected Boolean doInBackground(final String... args) {

        /*boolean bool = true;*/

        try {
            uri = Uri.parse(station.getRadiourl());

            DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();
            DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context, Util.getUserAgent(context, getString(R.string.app_name)), bandwidthMeterA);

            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
            MediaSource audioSource = new ExtractorMediaSource(uri, dataSourceFactory, extractorsFactory, null, null);
            /* exoPlayer.addListener(eventListener);
            MediaSource videoSource = new HlsMediaSource(uri, dataSourceFactory, 1, null, null);*/

            final LoopingMediaSource loopingSource = new LoopingMediaSource(videoSource);

            if (station.getRadiourl().endsWith(".m3u8")) {
                exoPlayer.prepare(loopingSource);
            } else {
                exoPlayer.prepare(audioSource);
            }
            /*exoPlayer.setPlayWhenReady(true);*/

        } catch (IllegalArgumentException | IllegalStateException | SecurityException | NullPointerException e1) {
            e1.printStackTrace();
        }
        return true;
    }

    @SuppressLint("WifiManagerPotentialLeak")
    @Override
    protected void onPostExecute(final Boolean success) {

        try {
            if (success) {
                wifiLock = ((WifiManager) context.getSystemService(Context.WIFI_SERVICE))
                        .createWifiLock(WifiManager.WIFI_MODE_FULL, "RadiophonyLock");
                wifiLock.acquire();

                exoPlayer.setPlayWhenReady(true);

            } else {
                /*Toast.makeText(context, context.getString(R.string.internet_disabled), Toast.LENGTH_SHORT).show();*/
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
        /* dialog.dismiss();*/

    }
}
}`

一段时间后,ondestroy 方法会在 oreo 中自动调用。我该如何处理?

【问题讨论】:

  • 您需要使用Foreground Service
  • Oreo 中的后台服务已受到限制。您可以在this 帖子中查看讨论。另请查看this 教程
  • 请阅读Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers? - 总结是这不是解决志愿者的理想方式,并且可能会适得其反。请不要将此添加到您的问题中。
  • 另外,请不要提出“请为我编写代码”请求。 Stack Overflow 不是宣传免费工作请求的地方。人们很乐意在这里帮助初学者,但要求免费劳动力太多了。
  • 我是android的初学者。我试图从上个月开始修复这个错误,但我无法得到任何解决方案。我已经阅读了很多教程。请任何人帮助我...

标签: java android android-8.0-oreo exoplayer2.x


【解决方案1】:

由于 Oreo 限制使用后台服务,您需要启动前台服务。这是the documentation关于奥利奥服务限制的信息。引用它:

Android 8.0 引入了新方法startForegroundService() 在前台启动新服务。系统创建后 服务,应用程序有五秒钟的时间调用服务的 startForeground() 方法显示新服务的用户可见 通知。如果应用程序没有在 时限,系统停止服务并声明应用为 ANR。

将服务置于前台基本上涉及将服务附加到用户可见的通知:

service.startForeground(NOTIFICATION_ID, notification);

startForeground 服务从 API 5 开始可用,而 startForegroundService 是 Oreo 自带的,因此您需要检查设备的 API 级别并相应地启动服务。

【讨论】:

  • 我更改了目标版本 25。现在它在 Oreo 的后台运行良好。
  • 这不是解决方案,因为 Play 商店很快就会强制执行目标 API 26 进行更新。请阅读这篇博文:android-developers.googleblog.com/2017/12/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 2019-05-30
  • 2018-08-14
  • 2017-04-03
  • 1970-01-01
相关资源
最近更新 更多