0

如何在奥利奥后台运行服务?此服务类在 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 中自动调用。我该如何处理?

4

1 回答 1

0

由于 Oreo 限制了后台服务的使用,您需要启动前台服务。这是有关奥利奥服务限制的文档。引用它:

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

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

service.startForeground(NOTIFICATION_ID, notification);

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

于 2018-03-13T21:37:08.933 回答