最近、シンプルなラジオアプリを Google Play ストアにアップロードしました。そして、ダウンローダがたくさんあります。しかし、それは本当にシンプルで、そのラジオ アプリを次のレベルに拡張したいと考えています。今のところ、選択できるラジオ局は 1 つだけです。次のボタンも前のボタンもありません。より多くのラジオ局から選択できます。私が本当にやりたいことは、ユーザーがより多くのラジオ局 (1 つではなく、約 6 つ以上) を聞くことができるように拡張することです。そのため、ユーザーが実際にそれを実行できるように、アプリにボタンPrevious
を追加する必要があるかもしれません。Next
しかし、問題があります。これを行う方法がわかりません。
これは 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>
私は実際にすべてのコードを書いたわけではありません。そのため、問題の解決策に頭を悩ませることができません。 必要に応じて特定のコードを拡張しただけですが、さまざまなラジオ局をナビゲートするためのボタンを実装する方法Previous
とボタンが実際にはわかりません。Next
皆さんにお願いしたいのは、アイデアを教えていただくか、このアプリにこの機能を追加する方法を教えていただくことです。複数のストリーム (この場合は 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();
}
}