java - 为什么我的服务不能在 Android Pie 上运行

标签 java android service exoplayer

我正在尝试使用下面的代码在我的应用程序中播放音乐,当我在(Android 8.0,7.0,5.0)上测试时它工作正常但是当我在 Android 9.0 上测试时,它不起作用,看起来RadioService 不起作用,它告诉我出了点问题!! Toast 所以调用了 onPlayerError

 public void onPlayerError(ExoPlaybackException error) {
        EventBus.getDefault().post(PlaybackStatus.ERROR);
    }

MainActivity.java

@Subscribe
public void onEvent(String status) {
    switch (status) {
        case PlaybackStatus.LOADING:
            progressloading.setVisibility(View.VISIBLE);
            trigger.setVisibility(View.GONE);
            break;
        case PlaybackStatus.ERROR:
            Toast.makeText(this, "Something went wrong!!", Toast.LENGTH_SHORT).show();
            break;
    }
    if (status.equals(PlaybackStatus.PLAYING)) {
        trigger.setVisibility(View.VISIBLE);
        progressloading.setVisibility(View.GONE);

    }
    trigger.setImageResource(status.equals(PlaybackStatus.PLAYING)
            ? R.drawable.ic_pause_black
            : R.drawable.ic_play_arrow_black);
}

,谁能帮我解决这个问题。

RadioService.java

    @Override
    public void onCreate() {
        super.onCreate();
        String strAppName = getResources().getString(R.string.app_name);
        String strLiveBroadcast = getResources().getString(R.string.live_broadcast);
        onGoingCall = false;
        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        notificationManager = new MediaNotificationManager(this);
        wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
                .createWifiLock(WifiManager.WIFI_MODE_FULL, "mcScPAmpLock");
        mediaSession = new MediaSessionCompat(this, getClass().getSimpleName());
        transportControls = mediaSession.getController().getTransportControls();
        mediaSession.setActive(true);
        mediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
        mediaSession.setMetadata(new MediaMetadataCompat.Builder()
                .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "...")
                .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, strAppName)
                .putString(MediaMetadataCompat.METADATA_KEY_TITLE, strLiveBroadcast)
                .build());
        mediaSession.setCallback(mediasSessionCallback);
        handler = new Handler();
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        AdaptiveTrackSelection.Factory trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        DefaultTrackSelector trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        exoPlayer = ExoPlayerFactory.newSimpleInstance(getApplicationContext(), trackSelector, new CustomLoadControl());
        exoPlayer.addListener(this);
        registerReceiver(becomingNoisyReceiver, new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
        status = PlaybackStatus.IDLE;

    }//END ON CREATE


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        String action = intent.getAction();
        if (TextUtils.isEmpty(action)) return START_NOT_STICKY;
        int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
        if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            stop();
            return START_NOT_STICKY;
        }
        if (action != null) {
            if (action.equalsIgnoreCase(ACTION_PLAY)) {
                transportControls.play();
            } else if (action.equalsIgnoreCase(ACTION_PAUSE)) {
                transportControls.pause();
            } else if (action.equalsIgnoreCase(ACTION_STOP)) {
                transportControls.stop();
            }
        }
        return START_NOT_STICKY;
    }


    @Override
    public boolean onUnbind(Intent intent) {
        serviceInUse = false;
        if (status.equals(PlaybackStatus.IDLE))
            stopSelf();
        return super.onUnbind(intent);
    }


    @Override
    public void onRebind(final Intent intent) {
        serviceInUse = true;
    }


    @Override
    public void onDestroy() {
        pause();
        exoPlayer.release();
        exoPlayer.removeListener(this);
        notificationManager.cancelNotify();
        mediaSession.release();
        unregisterReceiver(becomingNoisyReceiver);
        super.onDestroy();
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        serviceInUse = true;
        return iBinder;
    }

    @Override
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
                exoPlayer.setPlayWhenReady(true);
                exoPlayer.setVolume(1.0f);
                break;
            case AudioManager.AUDIOFOCUS_GAIN:
                exoPlayer.setVolume(0.8f);
                resume();
                break;

            case AudioManager.AUDIOFOCUS_LOSS:
                stop();
                break;

            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                if (isPlaying()) pause();
                break;

            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:

                if (isPlaying())
                    exoPlayer.setVolume(0.1f);

                break;
        }
    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        switch (playbackState) {
            case Player.STATE_BUFFERING:
                status = PlaybackStatus.LOADING;
                break;
            case Player.STATE_ENDED:
                status = PlaybackStatus.STOPPED;
                break;
            case Player.STATE_IDLE:
                status = PlaybackStatus.IDLE;
                break;
            case Player.STATE_READY:
                status = playWhenReady ? PlaybackStatus.PLAYING : PlaybackStatus.PAUSED;
                break;
            default:
                status = PlaybackStatus.IDLE;
                break;
        }
        if (!status.equals(PlaybackStatus.IDLE)) {
            final Uri uri = Uri.parse("http://radio.plaza.one/mp3");
            OnNewMetadataListener listener = new OnNewMetadataListener() {
                @Override
                public void onNewHeaders(String stringUri, List<String> name, List<String> desc, List<String> br, List<String> genre, List<String> info) {
                }

                @Override
                public void onNewStreamTitle(String stringUri, final String streamTitle) {
                    MainActivity.songinfo.setText(streamTitle);
                    if (Build.VERSION.SDK_INT >= 21)
                        notificationManager.startNotify(getApplicationContext(), status, streamTitle);
                }
            };
            AudiostreamMetadataManager.getInstance()
                    .setUri(uri)
                    .setOnNewMetadataListener(listener)
                    .setUserAgent(UserAgent.WINDOWS_MEDIA_PLAYER)
                    .start();
        }
        EventBus.getDefault().post(status);
    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {
        EventBus.getDefault().post(PlaybackStatus.ERROR);
    }

    @Override
    public void onPositionDiscontinuity(int reason) {

    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }

    @Override
    public void onSeekProcessed() {
    }


    public void play(String streamUrl) {
        this.streamUrl = streamUrl;
        if (wifiLock != null && !wifiLock.isHeld()) {
            wifiLock.acquire();
        }
        DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
        DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, getClass().getSimpleName()), bandwidthMeter);
        DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
        ExtractorMediaSource mediaSource = new ExtractorMediaSource(Uri.parse(streamUrl), dataSourceFactory, extractorsFactory, handler, null);
        exoPlayer.prepare(mediaSource);
        exoPlayer.setPlayWhenReady(true);


    }

    public void resume() {
        if (streamUrl != null)
            play(streamUrl);
    }

    public void pause() {
        exoPlayer.setPlayWhenReady(false);
        audioManager.abandonAudioFocus(this);
        wifiLockRelease();
    }

    public void stop() {
        exoPlayer.stop();
        audioManager.abandonAudioFocus(this);
        wifiLockRelease();
    }

    public void playOrPause(String url) {
        if (streamUrl != null && streamUrl.equals(url)) {
            if (!isPlaying()) {
                play(streamUrl);
            } else {
                pause();
            }
        } else {
            if (isPlaying()) {
                pause();
            }
            play(url);
        }
    }

    public String getStatus() {
        return status;
    }

    public MediaSessionCompat getMediaSession() {

        return mediaSession;
    }

    public boolean isPlaying() {
        return this.status.equals(PlaybackStatus.PLAYING);
    }

    private void wifiLockRelease() {
        if (wifiLock != null && wifiLock.isHeld()) {
            wifiLock.release();
        }
    }
    public int getCurrentPosition() {
        return (int) exoPlayer.getCurrentPosition();
    }
}

MediaNotificationManager.java

public class MediaNotificationManager {
    private static final int NOTIFICATION_ID = 555;
    private RadioService service;
    private NotificationManagerCompat notificationManager;
    private Resources resources;

    MediaNotificationManager(RadioService service) {
        this.service = service;
        this.resources = service.getResources();
        notificationManager = NotificationManagerCompat.from(service);
    }

    void startNotify(Context context, String playbackStatus, String title) {
        String titlesonge;
        String artist;
        try {
            titlesonge = StringUtils.substringBefore(title, " - ");
            artist = StringUtils.substringAfter(title, " - ");
        } catch (Exception e) {
            titlesonge = title.substring(0, title.indexOf(" - "));
            artist = title.substring(title.lastIndexOf(" - ") - 1);
        }
        int icon = R.drawable.ic_pause_white;
        Intent playbackAction = new Intent(service, RadioService.class);
        playbackAction.setAction(RadioService.ACTION_PAUSE);
        PendingIntent action = PendingIntent.getService(service, 1, playbackAction, 0);
        if (playbackStatus.equals(PlaybackStatus.PAUSED)) {
            icon = R.drawable.ic_play_white;
            playbackAction.setAction(RadioService.ACTION_PLAY);
            action = PendingIntent.getService(service, 2, playbackAction, 0);

        }
        Intent stopIntent = new Intent(service, RadioService.class);
        stopIntent.setAction(RadioService.ACTION_STOP);
        PendingIntent stopAction = PendingIntent.getService(service, 3, stopIntent, 0);

        Intent intent = new Intent(service, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
                Intent.FLAG_ACTIVITY_SINGLE_TOP |
                Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(service, 0, intent, 0);
        notificationManager.cancel(NOTIFICATION_ID);
        String PRIMARY_CHANNEL = "PRIMARY_CHANNEL_ID";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationManager manager = (NotificationManager) service.getSystemService(Context.NOTIFICATION_SERVICE);
            String PRIMARY_CHANNEL_NAME = "PRIMARY";
            NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL, PRIMARY_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
            channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            if (manager != null) {
                manager.createNotificationChannel(channel);
            }
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(service, PRIMARY_CHANNEL)
                .setAutoCancel(false)
                .setContentTitle(titlesonge)
                .setContentText(artist)
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.largeicon))
                .setContentIntent(pendingIntent)
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
                .setSmallIcon(R.drawable.smallwidth)
                .setColor(ContextCompat.getColor(context, R.color.colorneeded))
                .addAction(icon, "pause", action)
                .addAction(R.drawable.ic_stop_white, "stop", stopAction)
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setWhen(System.currentTimeMillis())
                .setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle()
                        .setMediaSession(service.getMediaSession().getSessionToken())
                        .setShowActionsInCompactView(0, 1)
                        .setShowCancelButton(true)
                        .setCancelButtonIntent(stopAction));
        service.startForeground(NOTIFICATION_ID, builder.build());
    }

    void cancelNotify() {
        service.stopForeground(true);
        notificationManager.cancel(NOTIFICATION_ID);
    }

}

RadioManager.java

public class RadioManager {

    @SuppressLint("StaticFieldLeak")
    private static RadioManager instance = null;
    private static RadioService service;
    private Context context;
    private boolean serviceBound;

    public RadioManager(Context context) {
        this.context = context;
        serviceBound = false;
    }

    public static RadioManager with(Context context) {
        if (instance == null)
            instance = new RadioManager(context);
        return instance;
    }

    public static RadioService getService() {
        return service;
    }

    public void playOrPause(String streamUrl) {
        service.playOrPause(streamUrl);
    }

    public boolean isPlaying() {
        if (service != null) {
            return service.isPlaying();
        }
        return false;
    }

    public int getCurrentPosition() {
        if (service != null) {
            return service.getCurrentPosition();
        }
        return 0;
    }

    public void bind() {

        Intent intent = new Intent(context, RadioService.class);
        context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);

        if (service != null)
            EventBus.getDefault().post(service.getStatus());
    }

    public void unbind() {

        context.unbindService(serviceConnection);

    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            RadioService.LocalBinder rl = (RadioService.LocalBinder) binder;
            service = rl.getService();
        }

        public void onServiceDisconnected(ComponentName arg0) {
            serviceBound = false;

        }
    };
}

list .xml

  <service
            android:name=".RadioTools.RadioService"
            android:exported="true"
            android:stopWithTask="true" />

最佳答案

从 Android 9 开始,不再支持带有 Http 的链接,我只是将 S 添加到我的链接中,而不是

http://mylink.com/mp3

我添加了 s :

https://mylink.com/mp3

一切正常

关于java - 为什么我的服务不能在 Android Pie 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56139761/

相关文章:

java - 为什么 Android Codelab 03.2 在将 double 除以零时会出现 IllegalArgumentException?

java - Web 服务和 Log4J 输出到文件

REST Web 服务,仅用于数据库访问?

java - 不支持 ElasticSearch script_lang [groovy]

java - Hibernate 延迟加载、代理和继承

android - Activity 和 Context 有什么区别?

android - 如何在 android logcat 中查看 xml 格式的 xmpp 消息?

java - 工作线程/后台线程 "smothers"UI 线程 Android - 为什么?

android - 在没有 Activity 的情况下启动服务(但使用 root)

java - 媒体转换库/插件最好是php