扩展我的Android Radio应用程序

时间:2013-11-27 19:41:34

标签: java android audio-streaming streaming-radio

最近,我将简单的广播应用程序上传到Google Play商店。它有很多下载者。但它真的很简单,我想将该无线电应用程序扩展到一个新的水平。它现在拥有的只有一个广播电台可供选择。没有下一个,没有以前的按钮可以选择更多的电台。我真正想做的是扩展它,以便用户可以收听更多的无线电台(不是一个,而是大约6个左右)。所以我可能需要在应用程序中添加PreviousNext按钮,这样用户才能真正做到这一点。但是有一个问题 - 我不知道该怎么做。

这是MainActivity.java类:

public class MainActivity extends Activity {

    static String radioTitle = "RadioLink1";
    static String radioStreamURL = "http://108.61.73.117:8124";

    Button playButton;
    Button pauseButton;
    Button stopButton;
    TextView statusTextView, bufferValueTextView;
    NotificationCompat.Builder notifyBuilder;

    private SeekBar volumeSeekbar;
    private AudioManager audioManager = null;

    private RadioUpdateReceiver radioUpdateReceiver;
    private RadioService radioServiceBinder;

    // Notification
    private static final int NOTIFY_ME_ID = 12345;
    private NotificationManager notifyMgr = null;

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

        TextView titleTextView = (TextView) this
                .findViewById(R.id.titleTextView);
        titleTextView.setText(radioTitle);

        playButton = (Button) this.findViewById(R.id.PlayButton);
        pauseButton = (Button) this.findViewById(R.id.PauseButton);
        stopButton = (Button) this.findViewById(R.id.StopButton);
        playButton.setEnabled(true);
        pauseButton.setEnabled(false);
        stopButton.setEnabled(false);
        pauseButton.setVisibility(View.INVISIBLE);

        initControls();

        statusTextView = (TextView) this
                .findViewById(R.id.StatusDisplayTextView);

        notifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        showNotification();

        setFont();

        // Bind to the service
        Intent bindIntent = new Intent(this, RadioService.class);
        bindService(bindIntent, radioConnection, Context.BIND_AUTO_CREATE);
        startService(new Intent(this, RadioService.class));
    }

    private void initControls() {
        try {

            audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            volumeSeekbar.setMax(audioManager
                    .getStreamMaxVolume(AudioManager.STREAM_MUSIC));
            volumeSeekbar.setProgress(audioManager
                    .getStreamVolume(AudioManager.STREAM_MUSIC));

            volumeSeekbar
                    .setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                        @Override
                        public void onStopTrackingTouch(SeekBar arg0) {
                        }

                        @Override
                        public void onStartTrackingTouch(SeekBar arg0) {
                        }

                        @Override
                        public void onProgressChanged(SeekBar arg0,
                                int progress, boolean arg2) {
                            audioManager.setStreamVolume(
                                    AudioManager.STREAM_MUSIC, progress, 0);
                        }
                    });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setFont() {
        // Font path
        String fontPath = "fonts/Christmas Card.ttf";

        // text view label
        TextView txtGhost = (TextView) findViewById(R.id.titleTextView);

        // Loading Font Face
        Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);

        // Applying font
        txtGhost.setTypeface(tf);
    }

    public void onClickPlayButton(View view) {
        radioServiceBinder.play();
    }

    public void onClickPauseButton(View view) {
        radioServiceBinder.pause();
    }

    public void onClickStopButton(View view) {
        radioServiceBinder.stop();
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (radioUpdateReceiver != null)
            unregisterReceiver(radioUpdateReceiver);
    }

    @Override
    protected void onResume() {
        super.onResume();

        /* Register for receiving broadcast messages */
        if (radioUpdateReceiver == null)
            radioUpdateReceiver = new RadioUpdateReceiver();
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_CREATED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_DESTROYED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_STARTED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_PREPARED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_PLAYING));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_PAUSED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_STOPPED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_COMPLETED));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_ERROR));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_BUFFERING_START));
        registerReceiver(radioUpdateReceiver, new IntentFilter(
                RadioService.MODE_BUFFERING_END));
    }

    /* Receive Broadcast Messages from RadioService */
    private class RadioUpdateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {

            if (intent.getAction().equals(RadioService.MODE_CREATED)) {
                showNotification();
            } else if (intent.getAction().equals(RadioService.MODE_DESTROYED)) {
                clearNotification();
            } else if (intent.getAction().equals(RadioService.MODE_STARTED)) {
                playButton.setEnabled(false);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(true);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Buffering...");
            } else if (intent.getAction().equals(RadioService.MODE_PREPARED)) {
                playButton.setEnabled(true);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(false);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Rady");
            } else if (intent.getAction().equals(
                    RadioService.MODE_BUFFERING_START)) {
                updateStatus("Buffering...");
            } else if (intent.getAction().equals(
                    RadioService.MODE_BUFFERING_END)) {
                updateStatus("Playing");
            } else if (intent.getAction().equals(RadioService.MODE_PLAYING)) {
                playButton.setEnabled(false);
                pauseButton.setEnabled(true);
                stopButton.setEnabled(true);
                playButton.setVisibility(View.INVISIBLE);
                pauseButton.setVisibility(View.VISIBLE);
                showNotification();
                updateStatus("Playing");
            } else if (intent.getAction().equals(RadioService.MODE_PAUSED)) {
                playButton.setEnabled(true);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(true);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Paused");
            } else if (intent.getAction().equals(RadioService.MODE_STOPPED)) {
                playButton.setEnabled(true);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(false);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Stopped");
                clearNotification();
            } else if (intent.getAction().equals(RadioService.MODE_COMPLETED)) {
                playButton.setEnabled(true);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(false);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Stopped");
            } else if (intent.getAction().equals(RadioService.MODE_ERROR)) {
                playButton.setEnabled(true);
                pauseButton.setEnabled(false);
                stopButton.setEnabled(false);
                playButton.setVisibility(View.VISIBLE);
                pauseButton.setVisibility(View.INVISIBLE);
                updateStatus("Error");
            }
        }
    }

    public void updateStatus(String status) {
        try {
            if (notifyBuilder != null && notifyMgr != null) {
                notifyBuilder.setContentText(status).setWhen(0);
                notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
            }
            statusTextView.setText(status);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void showNotification() {
        notifyBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(radioTitle).setContentText("");
        Intent resultIntent = new Intent(this, MainActivity.class);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(resultIntent);

        PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);

        notifyBuilder.setContentIntent(resultPendingIntent);
        notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notifyMgr.notify(NOTIFY_ME_ID, notifyBuilder.build());
    }

    public void clearNotification() {
        notifyMgr.cancel(NOTIFY_ME_ID);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.about:
            Intent i = new Intent(this, AboutActivity.class);
            startActivity(i);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    // Handles the connection between the service and activity
    private ServiceConnection radioConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            radioServiceBinder = ((RadioService.RadioBinder) service)
                    .getService();
        }

        public void onServiceDisconnected(ComponentName className) {
            radioServiceBinder = null;
        }
    };
}

和RadioService.java类:

public class RadioService extends Service implements OnErrorListener, OnCompletionListener, OnPreparedListener, OnInfoListener {

    private MediaPlayer mediaPlayer;
    private String radioStreamURL = MainActivity.radioStreamURL;

    public static final String MODE_CREATED = "CREATED";
    public static final String MODE_DESTROYED = "DESTROYED";
    public static final String MODE_PREPARED = "PREPARED";
    public static final String MODE_STARTED = "STARTED";
    public static final String MODE_PLAYING = "PLAYING";
    public static final String MODE_PAUSED = "PAUSED";
    public static final String MODE_STOPPED = "STOPPED";
    public static final String MODE_COMPLETED = "COMPLETED";
    public static final String MODE_ERROR = "ERROR";
    public static final String MODE_BUFFERING_START = "BUFFERING_START";
    public static final String MODE_BUFFERING_END = "BUFFERING_END";

    private boolean isPrepared = false;

    private final IBinder binder = new RadioBinder();

    @Override
    public void onCreate() {
        /* Create MediaPlayer when it starts for first time */
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnCompletionListener(this);
        mediaPlayer.setOnErrorListener(this);
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnInfoListener(this);

        sendBroadcast(new Intent(MODE_CREATED));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
        mediaPlayer.reset();
        isPrepared = false;
        sendBroadcast(new Intent(MODE_DESTROYED));
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {  
        sendBroadcast(new Intent(MODE_STARTED));

        /* Starts playback at first time or resumes if it is restarted */
        if(mediaPlayer.isPlaying())
            sendBroadcast(new Intent(MODE_PLAYING));
        else if(isPrepared) {
            sendBroadcast(new Intent(MODE_PAUSED));
        }
        else
            prepare();

        return Service.START_STICKY;
    }


    @Override
    public void onPrepared(MediaPlayer _mediaPlayer) {
        /* If radio is prepared then start playback */
        sendBroadcast(new Intent(MODE_PREPARED));
        isPrepared = true;
        play();
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) { 
        /* When no stream found then complete the playback */
        mediaPlayer.stop();
        mediaPlayer.reset();
        isPrepared = false;
        sendBroadcast(new Intent(MODE_COMPLETED));
    }

    public void prepare() {     
        /* Prepare Async Task - starts buffering */
        try {           
            mediaPlayer.setDataSource(radioStreamURL);
            mediaPlayer.prepareAsync();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void play() {
        if(isPrepared) {
            mediaPlayer.start();
            System.out.println("RadioService: play");
            sendBroadcast(new Intent(MODE_PLAYING));
        }
        else
        {
            sendBroadcast(new Intent(MODE_STARTED));
            prepare();
        }
    }

    public void pause() {
        mediaPlayer.pause();
        System.out.println("RadioService: pause");
        sendBroadcast(new Intent(MODE_PAUSED));
    }

    public void stop() {
        mediaPlayer.stop();
        mediaPlayer.reset();
        isPrepared = false;
        System.out.println("RadioService: stop");
        sendBroadcast(new Intent(MODE_STOPPED));
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        /* Check when buffering is started or ended */
        if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START) {
            sendBroadcast(new Intent(MODE_BUFFERING_START));
        }
        else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END) {
            sendBroadcast(new Intent(MODE_BUFFERING_END));
        }

        return false;
    }


    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        sendBroadcast(new Intent(MODE_ERROR));
        switch (what) {
            case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
                Log.v("ERROR","MEDIA ERROR NOT VALID FOR PROGRESSIVE PLAYBACK " + extra);
                break;
            case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
                Log.v("ERROR","MEDIA ERROR SERVER DIED " + extra);
                break;
            case MediaPlayer.MEDIA_ERROR_UNKNOWN:
                Log.v("ERROR","MEDIA ERROR UNKNOWN " + extra);
                break;
        }
        return false;
    }


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

    /* Allowing activity to access all methods of RadioService */
    public class RadioBinder extends Binder {
        RadioService getService() {
            return RadioService.this;
        }
    }

}

这个布局:

  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#4a4a4a"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/player_header_bg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true" >

        <TextView
            android:id="@+id/titleTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="48dp"
            android:background="@color/bgcolor"
            android:gravity="center"
            android:text="Classic Christmas Radio"
            android:textAlignment="center"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:textColor="#c0413b"
            android:textSize="40sp" />
    </LinearLayout>

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"
        android:layout_marginBottom="120dp"
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_marginTop="110dp"
        android:src="@drawable/cover" />

    <TextView
        android:id="@+id/StatusDisplayTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/PauseButton"
        android:layout_alignLeft="@+id/imageView1"
        android:layout_alignRight="@+id/imageView1"
        android:gravity="center"
        android:text="Unknown" />

    <Button
        android:id="@+id/PauseButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/StatusDisplayTextView"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="0.0dip"
        android:background="@drawable/btn_pause"
        android:onClick="onClickPauseButton" />

    <Button
        android:id="@+id/PlayButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@id/StatusDisplayTextView"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="0.0dip"
        android:background="@drawable/btn_play"
        android:onClick="onClickPlayButton" />

    <Button
        android:id="@+id/StopButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignRight="@id/StatusDisplayTextView"
        android:layout_marginBottom="0.0dip"
        android:background="@drawable/btn_stop"
        android:onClick="onClickStopButton" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toRightOf="@+id/PauseButton"
        android:background="@drawable/btn_previous" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_toRightOf="@+id/button1"
        android:background="@drawable/btn_next" />

</RelativeLayout>

我实际上并没有编写所有代码,这就是我无法直接解决问题的原因。我只是为我的需求扩展了代码,但现在我现在还不知道如何实现PreviousNext按钮来浏览不同的广播电台。我想要你们的意思是给我一些想法或者只是让我在路上如何将此功能添加到这个应用程序。如何获得多个流(在本例中来自SHOUTcast)并通过它们添加此导航。我希望我没有违反StackOverflow提出这类问题的规则。谢谢你,感谢任何帮助。

更新

在MainActivity中:

static String radioTitle = "RadioStation1";
    static String radioStreamURL = "http://108.61.73.117:8124";

    static String radioTitle2 = "RadioStation2";
    static String radioStreamURL2 = "http://108.61.73.117:8124";

    static String radioTitle3 = "RadioStation3";
    static String radioStreamURL3 = "http://108.61.73.117:8124";

...........

nextButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

        prevButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

RadioService类:

private String radioStreamURL = MainActivity.radioStreamURL;
    private String radioStreamURL2 = MainActivity.radioStreamURL2;
    private String radioStreamURL3 = MainActivity.radioStreamURL3;

...............

public void prepare() {     
        /* Prepare Async Task - starts buffering */
        try {           
            mediaPlayer.setDataSource(radioStreamURL);
            mediaPlayer.setDataSource(radioStreamURL2);
            mediaPlayer.setDataSource(radioStreamURL3);
            mediaPlayer.prepareAsync();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

2 个答案:

答案 0 :(得分:3)

RadioService.java

中查看您的方法
public void prepare() {     
        /* Prepare Async Task - starts buffering */
        try {           
            mediaPlayer.setDataSource(radioStreamURL);
            mediaPlayer.prepareAsync();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

在此设置广播流的网址,在不知道所有代码的情况下更改代码的快速方法是更改​​radioStreamURL变量。

private String radioStreamURL = MainActivity.radioStreamURL;

如果您有关于要使用的无线电的静态信息,只需将此字符串更改为列表并添加所需的所有无线电URL。

为你的布局添加一个Next和Preview按钮,设置监听器用这个函数调用你的RadioService,如下所示:

<强> MainActivity

private static int station = 0;//Not right, just to show

public void onNextStationClicked(){
    radioServiceBinder.changeStation(++station);
}

<强> RadioService

public static final String MODE_STATION_CHANGE = "STATION_CHANGE";

public void changeStation(int stationIndex){
  radioStreamURL = MainActivity.radioStreamURL.get(stationIndex);
  stop();
  play();
}

这只是一个想法,代码不是最好的,但有一点工作应该工作......

更新

尝试将代码更改为:

<强> RadioService

private List<String> radioStreamURL = new ArrayList<String>
private int radioStreamingIndex = 0;

然后在你的构造函数中添加这个

@Override
    public void onCreate() {
    radioStreamURL.add(radioStreamURL);
    radioStreamURL.add(radioStreamURL2);
    radioStreamURL.add(radioStreamURL3);
    // etc
}
 public void prepare() {     
        /* Prepare Async Task - starts buffering */
        try {           
            mediaPlayer.setDataSource(radioStreamURL.get(radioStreamingIndex));
            mediaPlayer.prepareAsync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

public void nextStation(){
  changeStation(radioStreamingIndex+1);
}

public void prevStation(){
  changeStation(radioStreamingIndex-1);
}

private void changeStation(int stationIndex){
  if(stationIndex > 0 && stationIndex < radioStreamURL.size()){
  radioStreamingIndex = stationIndex;
  stop();
  play();
  }
}

<强> MainActivity

nextButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        radioServiceBinder.nextStation();
    }
});

prevButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        radioServiceBinder.prevStation();
    }
});

答案 1 :(得分:0)

我在Android开发方面没有太多经验,但如果你想跟随Spotify和Pandora的步骤,你可能需要开发一个复杂的算法,因为无线电台是根据听众的类型创建的。