将后台音频服务作为对象访问

时间:2019-01-23 10:36:07

标签: java android android-studio

我有一个可以播放单个实时mp3广播流的应用。它将音频作为服务播放,以便可以在后台运行。该应用程序只有一个按钮可以打开/关闭流。

如何在主要活动运行时从其访问服务对象,以便确定播放/暂停按钮应执行的操作。

基本上我想做if service.isPlaying -> stopService (and be a Play button) -> else -> startService (and be a pause button)

到目前为止,每当我尝试访问该服务以检查service.isplaying()时,我只会返回空错误。如果我尝试if (service != null),它也总是返回null。

这是我的服务

public class StreamService extends Service implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener {
    public static final String ACTION_PLAY = "com.example.action.PLAY";
    private static final String TEST_URL = "https://www.nasa.gov/mp3/586447main_JFKwechoosemoonspeech.mp3";

    MainActivity mainActivity;
    MediaPlayer mediaPlayer = null;
    WifiManager.WifiLock wifiLock;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    public class LocalBinder extends Binder {
        public StreamService getServiceInstance() {
            return StreamService.this;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getAction().equals(ACTION_PLAY)) {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            mediaPlayer.setOnErrorListener(this);
            mediaPlayer.setOnPreparedListener(this);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            wifiLock = ((WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE))
                    .createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "mylock");
            wifiLock.acquire();
            try {
                // Set the stream URL location
                mediaPlayer.setDataSource(TEST_URL);
                // prepareAsync must be called after setAudioStreamType and setOnPreparedListener
                mediaPlayer.prepareAsync();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return START_STICKY;
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // ... react appropriately ...
        // The MediaPlayer has moved to the Error state, must be reset!
        return false;
    }

    void switchButton() {
        mainActivity.checkPlaying(!mediaPlayer.isPlaying());
    }

    public boolean play() {
        if (mediaPlayer != null) {
            //switchButton();
            if (mediaPlayer.isPlaying()) {
                mediaPlayer.pause();
                return false;
            } else {
                mediaPlayer.start();
                return true;
            }
        }
        return false;
    }

    public void stop() {
        try {
            if (mediaPlayer != null) {
                mediaPlayer.release();
                mediaPlayer = null;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /** Called when MediaPlayer is ready */
    public void onPrepared(MediaPlayer player) {
        player.start();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if( wifiLock != null) wifiLock.release();
        if (mediaPlayer != null) mediaPlayer.release();
    }

    public void registerClient(MainActivity activity) {
        mainActivity = activity;
    }

    public boolean isplaying() {

        return mediaPlayer == null ? false : mediaPlayer.isPlaying();
    }
}

和我的ActivityMain

public class MainActivity extends AppCompatActivity {

    private ImageButton btn;    // Play | Pause toggle button
    private ImageView img;      // Radio tower image that alternates between on and off
    StreamService service;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Bind the view buttons to local variables
        btn = findViewById(R.id.playPause);
        img = findViewById(R.id.radioTower);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startStream();
                checkPlaying(true);

            }
        });
    }

    public void startStream() {
        Intent serviceIntent = new Intent(MainActivity.this, StreamService.class);
        serviceIntent.setAction(StreamService.ACTION_PLAY);
        startService(serviceIntent);
        bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
    }

    public void stopStream() {
        if (service != null) {
            try {
                service.stop();
                unbindService(mConnection);
                stopService(new Intent(MainActivity.this, service.getClass()));
                service = null;
            } catch (IllegalArgumentException ex) {
                stopService(new Intent(MainActivity.this, service.getClass()));
                service = null;
                ex.printStackTrace();
            }
        }
    }

    public void checkPlaying(Boolean isPlaying) {
        if (isPlaying) {
            btn.setBackgroundResource(R.drawable.ic_rounded_pause_button);
            img.setImageResource(R.drawable.ic_toweron);
            img.setAlpha(1.0f);
        } else {
            btn.setBackgroundResource(R.drawable.ic_play_button);
            img.setImageResource(R.drawable.ic_toweroff);
            img.setAlpha(0.3f);
        }
    }

    private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                                       IBinder _service) {

            StreamService.LocalBinder binder = (StreamService.LocalBinder) _service;
            service = binder.getServiceInstance(); //Get instance of your service!
            service.registerClient(MainActivity.this); //Activity register in the service as client for callabcks!
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

        }
    };
}

0 个答案:

没有答案