java - 扩展我的 Android 广播应用程序

标签 java android audio-streaming streaming-radio

最近,我将简单的广播应用程序上传到了 Google Play 商店。而且它有很多下载者。但这真的很简单,我想将 radio 应用程序扩展到下一个级别。目前它只能选择一个广播电台。没有下一个、没有上一个按钮可以从更多广播电台中进行选择。我真正想做的是扩展它,以便用户可以收听更多广播电台(不是一个,而是大约 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 提出此类问题的规则。谢谢并感谢任何帮助。

更新:

在主 Activity 中:

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();
        }
    }

最佳答案

查看 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();
        }
    }

在这里,您设置了广播流的 URL,在不知道所有代码的情况下更改代码的快速方法是更改​​ radioStreamURL 变量。

private String radioStreamURL = MainActivity.radioStreamURL;

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

在布局中添加“下一步”和“预览”按钮,设置监听器以使用此函数调用 RadioService,如下所示:

主要 Activity

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

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

radio 服务

public static final String MODE_STATION_CHANGE = "STATION_CHANGE";

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

这只是一个想法,代码不是最好的,但只要做一点工作就应该可以...

更新

尝试将代码更改为:

radio 服务

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();
  }
}

主要 Activity

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

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

关于java - 扩展我的 Android 广播应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20251609/

相关文章:

java - 如何在Eclipse中安装tomcat插件

java - ServletRegistrationBean 是否为每个注册的子 WebApplicationContext 使用不同的类加载器

java - 使用 Volley 预填充房间数据库

android - 通过音乐流媒体服务中的歌曲进行节拍跟踪

iphone - 确定 AVPlayer 比特率

java - 什么时候适合使用 IllegalAccessException?

java - Jackson 和文件编码的奇怪错误

android - 将 JAR 添加到 Android 项目的/libs 文件夹中

java - 布局中的元素被裁剪

android - 在 Android 中使用 HTML5 流式传输