Recently, I uploaded simple Radio Application to the Google Play Store. And it has kinda a lot of downloaders. But it was really simple and I want to extend that Radio App to the next level. What it has for now is only ONE radio station to choose. No next, no previous buttons to choose from more Radio Stations. What I really want to do is to extend it so the user can listen for more Radio Stations(not one, but about 6 more or so). So maybe I need to add Previous and Next buttons to the app so the user can actually do that. But there is a problem - I don't know how to do this.
This is MainActivity.java class :
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;
}
};
}
and RadioService.java class:
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;
}
}
}
And this layout:
<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>
I actually didn't write all the code and that's why I can't get my head straight to the problem solution. I just extended given code for my needs but now I don't really now how to implement Previous and Next buttons to navigate through different Radio Stations. What I want from you guys is to maybe give me some ideas or just set me on the road how can I add this functionality to this app. How can I get more than one stream (in this case from SHOUTcast) and add this navigation through them. I hope I didn't breaking the StackOverflow rules of asking this kind of question. Thank you and appreciate any help.
UPDATE:
In the 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
}
});
And the RadioService class:
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();
}
}
Look at your method at 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();
}
}
Here you set the URL to your radio stream, the fast way to change your code without knowing all your code is to alter radioStreamURL variable.
private String radioStreamURL = MainActivity.radioStreamURL;
If you have some static information about the radios you want to use, just change this String to a List and add all the Radio's URL you want.
Add a Next and Preview button to your layout, set the listener to call your RadioService with this function, something like this:
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();
}
This is just an idea, the code isn't the best but with a little work should work...
UPDATE
Try change your code to this:
RadioService
private List<String> radioStreamURL = new ArrayList<String>
private int radioStreamingIndex = 0;
then on your constructor add this
#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();
}
});
I am not too experience in Android development, but you may need a complex algorithm developed if you would like to follow Spotify and Pandora's steps in the sense that the radio stations are created in relation to the listener's genre, etc.
Related
This application is to send a text message through Wi-Fi direct Api. i used build-in API for that. code is running, discovering the devices also but problem while sending message when press send button
I've tried this solution also:
App crash while sending data over a socket using WifiP2p connection
but still application crash whenever press send button.
MainActivity:
public class MainActivity extends AppCompatActivity{
Switch switch1;
Button btnOnOff, btnSend, btnDiscover;
ListView listView;
TextView read_msg_box, connectionStatus;
EditText writeMsg;
WifiManager wifiManager;
WifiP2pManager.Channel mChannel;
WifiP2pManager mManager;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
List <WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
String[] deviceNameArray;
WifiP2pDevice[] deviceArray;
static final int MESSAGE_READ = 1;
ServerClass serverClass;
ClientClass clientClass;
SendReceive sendReceive;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialWork();
exqListner();
}
Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch(msg.what){
case MESSAGE_READ:
byte[] readbuff = (byte[]) msg.obj;
String tempMsg = new String(readbuff, 0, msg.arg1);
read_msg_box.setText(tempMsg);
break;
}
return true;
}
});
private void exqListner() {
btnOnOff.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(wifiManager.isWifiEnabled()){
wifiManager.setWifiEnabled(false);
btnOnOff.setText("ON");
}else{
wifiManager.setWifiEnabled(true);
btnOnOff.setText("OFF");
}
}
});
btnDiscover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
connectionStatus.setText("Discovering started");
}
#Override
public void onFailure(int reason) {
connectionStatus.setText("Discovering starting failed");
}
});
}
});
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String msg = writeMsg.getText().toString();
byte[] bytes =msg.getBytes();
btnSend.setVisibility(View.INVISIBLE);
if(connectionStatus.equals("Host")) {
serverClass.writeData(bytes);
} else {
clientClass.writeData(bytes);
}
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long l) {
final WifiP2pDevice device = deviceArray[i];
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(getApplicationContext(), "Connected to "+device.deviceName, Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_SHORT).show();
}
});
}
});
}
private void initialWork() {
btnDiscover = (Button) findViewById(R.id.discover);
btnOnOff = (Button) findViewById(R.id.onOff);
btnSend = (Button) findViewById(R.id.sendButton);
listView = (ListView) findViewById(R.id.peerListView);
read_msg_box = (TextView) findViewById(R.id.readmsg);
connectionStatus = (TextView) findViewById(R.id.connectionStatus);
writeMsg = (EditText) findViewById(R.id.writeMsg);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(),null);
mReceiver = new WifiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
}
WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
if(!peerList.getDeviceList().equals(peers)){
peers.clear();
peers.addAll(peerList.getDeviceList());
deviceNameArray = new String[peerList.getDeviceList().size()];
deviceArray = new WifiP2pDevice[peerList.getDeviceList().size()];
int index = 0;
for(WifiP2pDevice device : peerList.getDeviceList()){
deviceNameArray[index] = device.deviceName;
deviceArray[index] = device;
index++;
}
ArrayAdapter <String> adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, deviceNameArray);
listView.setAdapter(adapter);
}
if (peers.size() == 0){
Toast.makeText(getApplicationContext(), "No Device Found",Toast.LENGTH_SHORT).show();
return;
}
}
};
WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
#Override
public void onConnectionInfoAvailable(WifiP2pInfo wifiP2pInfo) {
final InetAddress groupOwnerAddress = wifiP2pInfo.groupOwnerAddress;
if(wifiP2pInfo.groupFormed && wifiP2pInfo.isGroupOwner){
connectionStatus.setText("Host");
}
else if (wifiP2pInfo.groupFormed){
connectionStatus.setText("Client");
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
public class ServerClass extends AsyncTask<String, Integer, Boolean> {
Socket socket;
ServerSocket serverSocket;
InputStream inputStream;
OutputStream outputStream;
#Override
protected Boolean doInBackground(String... strings) {
boolean result = true;
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
} catch (IOException e) {
result = false;
e.printStackTrace();
}
return result;
}
public void writeData(final byte[] bytes) {
new Thread(new Runnable() {
#Override
public void run() {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Boolean result) {
if(result) {
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new Runnable(){
public void run() {
byte[] buffer = new byte[1024];
int x;
while (socket!=null) {
try {
x = inputStream.read(buffer);
if(x>0) {
handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
//restart socket assignment process
}
}
}
private class SendReceive extends Thread{
private Socket socket;
private InputStream inputStream;
private OutputStream outputStream;
public SendReceive(Socket skt){
socket = skt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (socket != null){
try {
bytes = inputStream.read(buffer);
if (bytes > 0){
handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void write(byte[] bytes){
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ClientClass extends AsyncTask<String, Integer, Boolean>{
Socket socket;
String hostAdd;
InputStream inputStream;
OutputStream outputStream;
public ClientClass(InetAddress hostAddress) {
hostAdd = hostAddress.getHostAddress();
socket = new Socket();
}
#Override
protected Boolean doInBackground(String... strings) {
boolean result = false;
try {
socket.connect(new InetSocketAddress(hostAdd, 8888), 5000);
result = true;
return result;
} catch (IOException e) {
e.printStackTrace();
result = false;
return result;
}
}
public void writeData(final byte[] bytes) {
new Thread(new Runnable() {
#Override
public void run() {
try {
outputStream.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Boolean result) {
if(result) {
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
new Thread(new Runnable(){
public void run() {
byte[] buffer = new byte[1024];
int x;
while (socket!=null) {
try {
x = inputStream.read(buffer);
if(x>0) {
handler.obtainMessage(MESSAGE_READ,x,-1,buffer).sendToTarget();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
btnSend.setVisibility(View.VISIBLE);
} else {
Toast.makeText(getApplicationContext(),"could not create sockets",Toast.LENGTH_SHORT).show();
}
}
}
}
Broadcast Receiver class:
public class WifiDirectBroadcastReceiver extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
public WifiDirectBroadcastReceiver(WifiP2pManager mManager, WifiP2pManager.Channel mChannel, MainActivity mActivity){
this.mActivity = mActivity;
this.mChannel = mChannel;
this.mManager = mManager;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)){
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE,-1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED){
Toast.makeText(context,"Wifi is on",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "Wifi is off", Toast.LENGTH_SHORT).show();
}
}else if(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)){
if (mManager != null){
mManager.requestPeers(mChannel, mActivity.peerListListener);
}
}else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)){
if(mManager == null){
return;
}
NetworkInfo networkInfo = intent.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()){
mManager.requestConnectionInfo(mChannel, mActivity.connectionInfoListener);
}
else{
mActivity.connectionStatus.setText("Device Disconnected");
}
}else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)){
}
}
}
and the xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"enter code here
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<Button
android:id="#+id/onOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="25dp"
android:layout_marginTop="55dp"
android:text="Wifi On"/>
<Button
android:id="#+id/discover"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/onOff"
android:layout_alignBottom="#+id/onOff"
android:layout_centerHorizontal="true"
android:text="Discover" />
<ListView
android:id="#+id/peerListView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentStart="true"
android:layout_below="#+id/onOff"
android:layout_marginTop="25dp"
android:background="#android:color/holo_blue_light">
</ListView>
<TextView
android:id="#+id/readmsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/peerListView"
android:layout_marginTop="31dp"
android:text="Message"
android:textAlignment="center"
android:textSize="20dp"
android:textStyle="italic"/>
<EditText
android:id="#+id/writeMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:ems="10"
android:inputType="textPersonName"
android:layout_toStartOf="#id/sendButton"/>
<Button
android:id="#+id/sendButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:text="SEND"/>
<TextView
android:id="#+id/connectionStatus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="15dp"
android:textAlignment="center"
android:text="Connection Status"
android:textColor="#color/design_default_color_primary_dark"
android:textSize="15dp"
android:textStyle="italic"/>
</RelativeLayout>
After pressing send button, message should be sent but it crash whole application. please help.enter code here
Im creating an app in android studio where I want 10 clips to be played at the same time side by side. Im having some problems with some lags already at three clips and I wounder if Im better off using threads? In that case how?
Any hint would be very much apreciated
Here is my code so far. I know it is not very efficient and I am better off using an array of a player object for example but Im just testing so far:
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaPlayer mp1, mp2, mp3;
private TextureView tv1, tv2, tv3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = findViewById(R.id.textureView1);
tv2 = findViewById(R.id.textureView2);
tv3 = findViewById(R.id.textureView3);
tv1.setSurfaceTextureListener(this);
tv2.setSurfaceTextureListener(this);
tv3.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Surface surface = new Surface(surfaceTexture);
mp1 = MediaPlayer.create(this, R.raw.a7);
mp1.setSurface(surface);
// mp1.prepareAsync(); //
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp1) {
mp1.start();
}
});
Surface surface2 = new Surface(surfaceTexture);
mp2 = MediaPlayer.create(this, R.raw.a9);
mp2.setSurface(surface2);
// mp1.prepareAsync(); //
mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp2) {
mp2.start();
}
});
Surface surface3 = new Surface(surfaceTexture);
mp3 = MediaPlayer.create(this, R.raw.a10);
mp3.setSurface(surface3);
// mp1.prepareAsync(); //
mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp3) {
mp3.start();
}
});
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
#Override
protected void onPause() {
if (mp1 != null && mp1.isPlaying()) {
mp1.pause();
}
super.onPause();
}
#Override
protected void onResume() {
if (mp1 != null) {
mp1.start();
}
super.onResume();
}
#Override
protected void onDestroy() {
if (mp1 != null) {
mp1.stop();
mp1.release();
mp1 = null;
}
super.onDestroy();
}
}
You should play media in a different non-ui thread. like this:-
public class MediaService extends Service {
private MediaPlayer mp1, mp2, mp3;
private static final String ACTION_START = TAG + ".ACTION_START";
private IBinder mBinder = new MyBinder();
private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "MediaPlayer.onPrepared");
onCommandPlay(mp);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "onBind");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
m1 = MediaPlayer.create(this, R.raw.a1);
m2 = MediaPlayer.create(this, R.raw.a2);
m3 = MediaPlayer.create(this, R.raw.a9);
}
#Override
public void onDestroy() {
super.onDestroy();
if (m1 != null) m1 .release();
if (m2 != null) m2 .release();
if (m3 != null) m3 .release();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
Log.d(TAG, "onStartCommand: " + intent.getAction());
if (ACTION_START.equals(action)) {
onCommandStart();
return START_STICKY;
}
stopSelf();
return Service.START_STICKY_COMPATIBILITY;
}
/**
* Performs actions related to media player when Service onStartCommand method is called
*
*/
private void onCommandStart() {
// Create Notifications with remote views
mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(collapsed)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, mNotification);
startPlaying();
}
private void onCommandPlay(MediaPlayer mp) {
try {
mp.start();
} catch (IllegalStateException e) {
Log.e(TAG, "onCommandPlay", e);
}
}
/**
* Start playing the provided media item
*
*/
private void startPlaying() {
mCurrent = item;
try {
mp1.reset();
mp1.setOnPreparedListener(mMediaPrepared);
mp2.reset();
mp2.setOnPreparedListener(mMediaPrepared);
mp3.reset();
mp3.setOnPreparedListener(mMediaPrepared);
AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
mp1.prepareAsync();
mp2.prepareAsync();
mp3.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "startPlaying", e);
}
}
public class MyBinder extends Binder {
public MediaService getService() {
return MediaService.this;
}
}
}
then start the service from Activity like this:
Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);
You should also handle different media playing use-cases. You can refer this link for more.
So basically, i got a list view that shows a list of bands.
When i press on one of the bands in the list, it creates a band profile page via an adapter.
In this layout, i got a play button, which starts a MediaPlayer service and play a song.
So far, so good.
The problem is, im trying to update the seekBar, located in the band profile page (created by the adapter mentioned above), from the MediaPlayer service Java file, but i'm unable to reach it.
i'm trying to use :
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.activity_singleband, null, false);
seekBar = (SeekBar) layout.findViewById(R.id.seekBarBand);
but it seems that it uses another "instance" of the view, and not the one i'm currently viewing.
Here is the full MusicService Java file:
public class MusicService extends Service {
SeekBar seekBar;
Handler handler;
Runnable runnable;
NotificationManager nMN;
TextView BandName;
String songLink;
String songName;
String bandName;
String SongPlaying="";
String BandPlaying="";
public static MediaPlayer mp;
public static Boolean mpState = true;
public static Boolean mpPause = false;
public static Boolean isPlaying = false;
#Override
public void onCreate() {
super.onCreate();
}
// Play Cycle for seekBar
public void PlayCycle(){
seekBar.setProgress(mp.getCurrentPosition());
if (mp.isPlaying()){
runnable = new Runnable() {
#Override
public void run() {
PlayCycle();
}
};
handler.postDelayed(runnable, 1000);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
songLink = intent.getStringExtra("SongLink");
songName = intent.getStringExtra("SongName");
bandName = intent.getStringExtra("BandName");
LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.activity_singleband, null, false);
seekBar = (SeekBar) layout.findViewById(R.id.seekBarBand);
BandName = (TextView) layout.findViewById(R.id.singleBandNameView);
BandName.setText("Bla Bla");
System.out.print("Band Name : "+ BandName.getText() );
handler = new Handler();
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean input) {
if (input){
mp.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
if (isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName)) {
Stop();
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
Uri songUri = Uri.parse(songLink);
mp.setDataSource(getApplicationContext(), songUri);
SongPlaying = songName;
Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
isPlaying=true;
new prepare().execute();
}
catch (IOException e) {
e.printStackTrace();
}
}
else if (!isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName) ) {
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
Uri songUri = Uri.parse(songLink);
mp.setDataSource(getApplicationContext(), songUri);
SongPlaying = songName;
Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
new prepare().execute();
isPlaying=true;
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
Toast.makeText(getApplicationContext(), "Song is Already Playing", Toast.LENGTH_SHORT).show();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
mp.release();
handler.removeCallbacks(runnable);
}
/// Permanent Notification
private void showNotification() {
nMN = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification n = new Notification.Builder(this)
.setContentTitle(songName)
.setContentText(bandName)
.setSmallIcon(R.drawable.ic_bandcamp)
//.addAction(R.drawable.ic_play_arrow_black_24dp, "button1", new pause())
.setOngoing(true)
.build();
nMN.notify(1, n);
}
/// PREPARE SONG TO PLAY //
public class prepare extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.prepare();
PlayCycle();
seekBar.setMax(mp.getDuration());
mp.start();
SongPlaying = songName;
isPlaying=true;
showNotification(); // show notification
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(getApplicationContext(),"Song Finished", Toast.LENGTH_LONG).show();
new stop().execute();
}
});
} catch (IOException io){ io.printStackTrace(); }
return null; }}
/// STOP PLAYING SONG //
public static void Stop()
{
mp.reset();
mp.release();
isPlaying=false;
}
public static class stop extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.reset();
mp.release();
isPlaying=false;
} catch (Exception io){ io.printStackTrace(); }
return null; }}
/// PAUSE PLAYING SONG//
public static class pause extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.pause(); }
catch (Exception io){ io.printStackTrace(); }
return null; }}
public static class start extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.start(); }
catch (Exception io){ io.printStackTrace(); }
return null; }}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Would love to have some suggestions.
Thanks in advance.
Okey Firstly I suggest you to read more about Android Service classes. Secondly Do NOT place you visual components like a SeekBar or TextView in the Service because it doesn't make any sense. Service is just a background task and do not know about the UI. Since it's executed in the background you don't even need AsyncTask inside this so thirdly remove ALL AsyncTasks in your service and run their task like they don't need to be executed in the background.
So all what you have to do is create a Fragment/Activity for the UI, then bind your Fragment/Acitivity with your Service to communicate and update UI components.
The easiest way is make the Service a Singleton like it's done here:
public class MusicService extends Service {
private static MusicService instance = null;
public static MusicService getInstance() {
return instance;
}
Handler handler;
Runnable runnable;
NotificationManager nMN;
String songLink;
String songName;
String bandName;
String SongPlaying="";
String BandPlaying="";
public static MediaPlayer mp;
public static Boolean mpState = true;
public static Boolean mpPause = false;
public static Boolean isPlaying = false;
#Override
public void onCreate() {
instance = this;
super.onCreate();
}
// Play Cycle for seekBar
public void PlayCycle(){
seekBar.setProgress(mp.getCurrentPosition());
if (mp.isPlaying()){
runnable = new Runnable() {
#Override
public void run() {
PlayCycle();
}
};
handler.postDelayed(runnable, 1000);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
songLink = intent.getStringExtra("SongLink");
songName = intent.getStringExtra("SongName");
bandName = intent.getStringExtra("BandName");
handler = new Handler();
if (isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName)) {
Stop();
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
Uri songUri = Uri.parse(songLink);
mp.setDataSource(getApplicationContext(), songUri);
SongPlaying = songName;
Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
isPlaying=true;
new prepare().execute();
}
catch (IOException e) {
e.printStackTrace();
}
}
else if (!isPlaying && !songName.equals(SongPlaying) && !BandPlaying.equals(bandName) ) {
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
Uri songUri = Uri.parse(songLink);
mp.setDataSource(getApplicationContext(), songUri);
SongPlaying = songName;
Toast.makeText(getApplicationContext(), "Please wait", Toast.LENGTH_SHORT).show();
new prepare().execute();
isPlaying=true;
}
catch (IOException e) {
e.printStackTrace();
}
}
else {
Toast.makeText(getApplicationContext(), "Song is Already Playing", Toast.LENGTH_SHORT).show();
}
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
mp.release();
handler.removeCallbacks(runnable);
}
/// Permanent Notification
private void showNotification() {
nMN = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification n = new Notification.Builder(this)
.setContentTitle(songName)
.setContentText(bandName)
.setSmallIcon(R.drawable.ic_bandcamp)
//.addAction(R.drawable.ic_play_arrow_black_24dp, "button1", new pause())
.setOngoing(true)
.build();
nMN.notify(1, n);
}
/// PREPARE SONG TO PLAY //
public class prepare extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.prepare();
PlayCycle();
seekBar.setMax(mp.getDuration());
mp.start();
SongPlaying = songName;
isPlaying=true;
showNotification(); // show notification
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(getApplicationContext(),"Song Finished", Toast.LENGTH_LONG).show();
new stop().execute();
}
});
} catch (IOException io){ io.printStackTrace(); }
return null; }}
/// STOP PLAYING SONG //
public static void Stop()
{
mp.reset();
mp.release();
isPlaying=false;
}
public static class stop extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.reset();
mp.release();
isPlaying=false;
} catch (Exception io){ io.printStackTrace(); }
return null; }}
/// PAUSE PLAYING SONG//
public static class pause extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.pause(); }
catch (Exception io){ io.printStackTrace(); }
return null; }}
public static class start extends AsyncTask {
#Override
protected Object doInBackground(Object[] objects) {
try {
mp.start(); }
catch (Exception io){ io.printStackTrace(); }
return null; }}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
return null;
}
From what I can tell, the Uri.parse in my code is causing my MediaPlayer to fail on audio files with special characters in the filename, like "#" and others. I cannot figure out how to resolve this issue. I want to be able to use special characters in my filenames. Here is the code that I think is causing the issue:
public void playAudio(int media) {
try {
switch (media) {
case LOCAL_AUDIO:
/**
* TODO: Set the path variable to a local audio file path.
*/
if (path == "") {
// Tell the user to provide an audio file URL.
Toast
.makeText(
MediaPlayerDemo_Audio.mp,
"Please edit MediaPlayer_Audio Activity, "
+ "and set the path variable to your audio file path."
+ " Your audio file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
}
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setLooping(sound_loop);
mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
mMediaPlayer.prepare();
resetTimer();
startTimer();
mMediaPlayer.start();
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
break;
case RESOURCES_AUDIO:
/**
* TODO: Upload a audio file to res/raw folder and provide
* its resid in MediaPlayer.create() method.
*/
// mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
//mMediaPlayer.start();
}
//tx.setText(path);
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
}
I am using MediaPlayerDemo_Audio.java to play sounds. As you can see from the above code, the mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path)); is calling the code to retrieve the file and media player, I think. I am not too skilled with android code yet. Here is the code for MediaPlayerDemo_Audio.java:
public class MediaPlayerDemo_Audio extends Activity {
public static String path;
private String fname;
private static Intent PlayerIntent;
public static String STOPED = "stoped";
public static String PLAY_START = "play_start";
public static String PAUSED = "paused";
public static String UPDATE_SEEKBAR = "update_seekbar";
public static boolean is_loop = false;
private static final int LOCAL_AUDIO=0;
private Button play_pause, stop;
private SeekBar seek_bar;
public static MediaPlayerDemo_Audio mp;
private AudioPlayerService mPlayerService;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.media_player_layout);
//getWindow().setTitle("SoundPlayer");
//getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
// android.R.drawable.ic_media_play);
play_pause = (Button)findViewById(R.id.play_pause);
play_pause.setOnClickListener(play_pause_clk);
stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(stop_clk);
seek_bar = (SeekBar)findViewById(R.id.seekBar1);
seek_bar.setMax(100);
seek_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
if (mPlayerService!=null) {
int seek_pos = (int) ((double)mPlayerService.getduration()*seekBar.getProgress()/100);
mPlayerService.seek(seek_pos);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
}
});
play_pause.setText("Pause");
stop.setText("Stop");
//int idx = path.lastIndexOf("/");
//fname = path.substring(idx+1);
//tx.setText(path);
IntentFilter filter = new IntentFilter();
filter.addAction(STOPED);
filter.addAction(PAUSED);
filter.addAction(PLAY_START);
filter.addAction(UPDATE_SEEKBAR);
registerReceiver(mPlayerReceiver, filter);
PlayerIntent = new Intent(MediaPlayerDemo_Audio.this, AudioPlayerService.class);
if (AudioPlayerService.path=="") AudioPlayerService.path=path;
AudioPlayerService.sound_loop = is_loop;
startService(PlayerIntent);
bindService(PlayerIntent, mConnection, 0);
if (mPlayerService!=null && mPlayerService.is_pause==true) play_pause.setText("Play");
mp = MediaPlayerDemo_Audio.this;
}
private BroadcastReceiver mPlayerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String act = intent.getAction();
if (act.equalsIgnoreCase(UPDATE_SEEKBAR)){
int val = intent.getIntExtra("seek_pos", 0);
seek_bar.setProgress(val);
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime((long) (intent.getLongExtra("time", 0)/16.666)));
//tx.setText(fname);
}
else if (act.equalsIgnoreCase(STOPED)) {
play_pause.setText("Play");
seek_bar.setProgress(0);
stopService(PlayerIntent);
unbindService(mConnection);
mPlayerService = null;
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime(0));
}
else if (act.equalsIgnoreCase(PLAY_START)){
play_pause.setText("Pause");
}
else if (act.equalsIgnoreCase(PAUSED)){
play_pause.setText("Play");
}
}
};
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
mPlayerService = ((AudioPlayerService.LocalBinder)arg1).getService();
if (mPlayerService.is_pause==true) {
play_pause.setText("Play");
seek_bar.setProgress(mPlayerService.seek_pos);
}
if (mPlayerService.mTime!=0) {
TextView counter = (TextView) findViewById(R.id.time_view);
counter.setText(DateUtils.formatElapsedTime((long) (mPlayerService.mTime/16.666)));
}
if (path.equalsIgnoreCase(AudioPlayerService.path)==false){
AudioPlayerService.path = path;
mPlayerService.restart();
}
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
mPlayerService = null;
}
};
private OnClickListener play_pause_clk = new OnClickListener() {
#Override
public void onClick(View arg0) {
if (mPlayerService!=null)
mPlayerService.play_pause();
else{
AudioPlayerService.path=path;
startService(PlayerIntent);
bindService(PlayerIntent, mConnection, 0);
}
}
};
private OnClickListener stop_clk = new OnClickListener() {
#Override
public void onClick(View arg0) {
if (mPlayerService==null) return;
mPlayerService.Stop();
}
};
#Override
protected void onDestroy() {
super.onDestroy();
// TODO Auto-generated method stub
}
}
How can I fix this issue so files can be parsed with special characters and played correctly in MediaPlayer? Am I missing something?
Maybe it would help to show the entire code for my AudioPlayerService:
public class AudioPlayerService extends Service {
public MediaPlayer mMediaPlayer;
protected long mStart;
public long mTime;
public int seek_pos=0;
public static boolean sound_loop = false;
public boolean is_play, is_pause;
public static String path="";
private static final int LOCAL_AUDIO=0;
private static final int RESOURCES_AUDIO=1;
private int not_icon;
private Notification notification;
private NotificationManager nm;
private PendingIntent pendingIntent;
private Intent intent;
#SuppressWarnings("deprecation")
#Override
public void onCreate() {
playAudio(LOCAL_AUDIO);
mTime=0;
is_play = true;
is_pause = false;
CharSequence ticker = "Touch to return to app";
long now = System.currentTimeMillis();
not_icon = R.drawable.play_notification;
notification = new Notification(not_icon, ticker, now);
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Context context = getApplicationContext();
intent = new Intent(this, MediaPlayerDemo_Audio.class);
pendingIntent = PendingIntent.getActivity(context, 0,intent, 0);
PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
//INCOMING call
//do all necessary action to pause the audio
if (is_play==true && is_pause==false){
play_pause();
}
} else if(state == TelephonyManager.CALL_STATE_IDLE) {
//Not IN CALL
//do anything if the phone-state is idle
} else if(state == TelephonyManager.CALL_STATE_OFFHOOK) {
//A call is dialing, active or on hold
//do all necessary action to pause the audio
//do something here
if (is_play==true && is_pause==false){
play_pause();
}
}
super.onCallStateChanged(state, incomingNumber);
}
};//end PhoneStateListener
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if(mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
OnAudioFocusChangeListener myaudiochangelistener = new OnAudioFocusChangeListener(){
#Override
public void onAudioFocusChange(int arg0) {
//if (arg0 ==AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK){
if (is_play==true && is_pause==false){
play_pause();
}
//}
}
};
AudioManager amr = (AudioManager)getSystemService(AUDIO_SERVICE);
amr.requestAudioFocus(myaudiochangelistener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
}
#SuppressWarnings("deprecation")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Context context = getApplicationContext();
String title = "VoiceRecorder App";
CharSequence message = "Playing..";
notification.setLatestEventInfo(context, title, message,pendingIntent);
nm.notify(101, notification);
return START_STICKY;
}
public class LocalBinder extends Binder {
AudioPlayerService getService() {
return AudioPlayerService.this;
}
}
public void restart(){
mMediaPlayer.stop();
playAudio(LOCAL_AUDIO);
mTime=0;
is_play = true;
is_pause = false;
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
public void Stop()
{
mMediaPlayer.stop();
Intent intent1 = new Intent(MediaPlayerDemo_Audio.STOPED);
sendBroadcast(intent1);
resetTimer();
is_play=false;
is_pause=false;
}
public void play_pause()
{
if (is_play==false){
try {
mMediaPlayer.start();
startTimer();
is_play=true;
is_pause = false;
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
}
else{
mMediaPlayer.pause();
stopTimer();
Intent intent1 = new Intent(MediaPlayerDemo_Audio.PAUSED);
sendBroadcast(intent1);
is_play = false;
is_pause = true;
}
}
public int getduration()
{
return mMediaPlayer.getDuration();
}
public void seek(int seek_pos)
{
mMediaPlayer.seekTo(seek_pos);
mTime = seek_pos;
}
public void playAudio(int media) {
try {
switch (media) {
case LOCAL_AUDIO:
/**
* TODO: Set the path variable to a local audio file path.
*/
if (path == "") {
// Tell the user to provide an audio file URL.
Toast
.makeText(
MediaPlayerDemo_Audio.mp,
"Please edit MediaPlayer_Audio Activity, "
+ "and set the path variable to your audio file path."
+ " Your audio file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
}
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setLooping(sound_loop);
mMediaPlayer.setDataSource(MediaPlayerDemo_Audio.mp, Uri.parse(path));
mMediaPlayer.prepare();
resetTimer();
startTimer();
mMediaPlayer.start();
Intent intent = new Intent(MediaPlayerDemo_Audio.PLAY_START);
sendBroadcast(intent);
break;
case RESOURCES_AUDIO:
/**
* TODO: Upload a audio file to res/raw folder and provide
* its resid in MediaPlayer.create() method.
*/
// mMediaPlayer = MediaPlayer.create(this, R.raw.test_cbr);
//mMediaPlayer.start();
}
//tx.setText(path);
} catch (Exception e) {
//Log.e(TAG, "error: " + e.getMessage(), e);
}
}
#SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
long curTime = System.currentTimeMillis();
mTime += curTime-mStart;
mStart = curTime;
int pos = (int) ((double)mMediaPlayer.getCurrentPosition()*100/mMediaPlayer.getDuration());
seek_pos = pos;
Intent intent1 = new Intent(MediaPlayerDemo_Audio.UPDATE_SEEKBAR);
if (mMediaPlayer.isLooping()) intent1.putExtra("time", (long)mMediaPlayer.getCurrentPosition());
else intent1.putExtra("time", mTime);
intent1.putExtra("seek_pos", pos);
sendBroadcast(intent1);
if (mMediaPlayer.isPlaying()==false && mMediaPlayer.isLooping()==false){
mMediaPlayer.stop();
resetTimer();
Intent intent2 = new Intent(MediaPlayerDemo_Audio.STOPED);
sendBroadcast(intent2);
is_play=false;
}
if (mTime > 0) mHandler.sendEmptyMessageDelayed(0, 10);
};
};
private void startTimer() {
mStart = System.currentTimeMillis();
mHandler.removeMessages(0);
mHandler.sendEmptyMessage(0);
}
private void stopTimer() {
mHandler.removeMessages(0);
}
private void resetTimer() {
stopTimer();
mTime = 0;
}
#Override
public void onDestroy() {
super.onDestroy();
// TODO Auto-generated method stub
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
nm.cancel(101);
}
}
For local files, do not use Uri.parse(). Use Uri.fromFile(), passing in a File object pointing to the file in question. This should properly escape special characters like #.
After searching in life cycle I have found that my application needs to use the destroy(); method. However, when I implement this the application doesn't close. I am trying to apply this to the button exitButton. If someone could direct me in the right direction then that would be great.
MainActivity.java
package com.webcraftbd.radio;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
static String radioTitle = "Android Live Radio";
static String radioStreamURL = "http://stream.infowars.com:80";
Button playButton;
Button pauseButton;
Button stopButton;
Button exitbutton;
TextView statusTextView, bufferValueTextView;
NotificationCompat.Builder notifyBuilder;
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);
statusTextView = (TextView) this.findViewById(R.id.StatusDisplayTextView);
notifyMgr=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
showNotification();
// Bind to the service
Intent bindIntent = new Intent(this, RadioService.class);
bindService(bindIntent, radioConnection, Context.BIND_AUTO_CREATE);
startService(new Intent(this, RadioService.class));
}
public void onClickPlayButton(View view) {
radioServiceBinder.play();
}
public void onClickPauseButton(View view) {
radioServiceBinder.pause();
}
public void onClickStopButton(View view) {
radioServiceBinder.stop();
}
public void onClicexitbutton(View view) {
super.finish();
super.onDestroy();
radioServiceBinder.onDestroy();
radioServiceBinder.stop();
radioServiceBinder.stopService(getParentActivityIntent());
}
#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));
}
protected void onDestroy(){
super.onDestroy();
}
/* 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;
}
};
}
enter code here
activity_main.xml
<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: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/exitbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/StatusDisplayTextView"
android:layout_centerHorizontal="true"
android:text="Button" />
</RelativeLayout>
RadioService.java
package com.webcraftbd.radio;
import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
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;
}
}
}
Ok, after developing some pseudo and some logic, I have noticed that Andorid doesn't have an exit method in the way that you're hoping. When first reading the question I didn't realise that it was Android as I was multi-tasking. As you may notice, almost every android application doesn't have an exit button, and there is a reason for this. The reason being that Android is supposedly meant to load and unload applications through the OS, hence why you don't do it. If the user wanted to exit the application, they would do what they do with every other, enter the multi-tasking menu and swipe it off. Please read the following for more information: http://android.nextapp.com/site/fx/doc/exit