MediaPlayer Streaming Hanging App and Crashing on Slow Connections - android-studio

I'm building a radio streaming app. Everything works great when I have a good internet connection, even when multitasking. The problem is without or with a poor internet connection.
The moment you tap the play button the app freezes and only resumes when the audio stream starts. With slow connections this can take a few seconds, hanging the app. Without Internet, the app eventually crashes after a while.
public class SoundService extends Service {
MediaPlayer mp;
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onCreate() {
mp = new MediaPlayer();
try {
mp.setDataSource("stream_url");
} catch (IllegalArgumentException e) {
e.printStackTrace();
Log.v(TAG, "Error 1");
onDestroy();
} catch (IllegalStateException e) {
e.printStackTrace();
Log.v(TAG, "Error 2");
onDestroy();
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, "Error 3");
onDestroy();
}
try {
mp.prepare();
mp.start();
} catch (IllegalStateException e) {
e.printStackTrace();
Log.v(TAG, "Error 4");
onDestroy();
} catch (IOException e) {
e.printStackTrace();
Log.v(TAG, "Error 5");
onDestroy();
}
}
public int onStartCommand(Intent intent, int flags, int startId) {
mp.start();
return Service.START_NOT_STICKY;
}
public void onDestroy() {
mp.stop();
mp.release();
stopSelf();
super.onDestroy();
}
}
This is how I start the stream (play button):
startService(new Intent(MainActivity.this, SoundService.class));
Without connection the app eventually gets the error number 5, but this occurs only when crashes, so it's too late do stop the player. Before that I don't get any "catch".
As a temporary workaround, I'm checking for internet connection before starting the stream. This way I can prevent the crash, but I still have a problem with the app hanging on slow connections.
Any ideas? Thanks!

use this code which might help you
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});

Related

Go to another activity not main activity after splash screen

I have a splash screen in which i am checking user is logged in or not if logged in go to dashboard otherwise go to login activity. I am using sharedpref. Issue is (which I am unable to resolve) after splash screen login screen appears for a brief moment than dashboard. Splash > Login > Dash what i Want is Splash > Dash (if user logged in). Login is the main activity of my project. Here is the code:
public class SplashScreen extends AppCompatActivity {
private SessionManager sessionManager;
private BroadcastReceiver broadcastReceiver;
private SharedPreferences prefs;
private boolean isLogin;
private int accessID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionManager = new SessionManager(this);
broadcastReceiver = new CheckNetStatus();
broadcastIntent();
}
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onResume(){
super.onResume();
new CheckNetStatus().onReceive(SplashScreen.this,new
Intent(ConnectivityManager.CONNECTIVITY_ACTION));
try {
prefs = getSharedPreferences(SessionManager.PREF_NAME, 0); // Declare
SharedPreferences
accessID = prefs.getInt(SessionManager.KEY_ACCESSID, 0); // get Access Id from
SharedPreferences
isLogin = Utils.getLoginStatus(SplashScreen.this); // Check Login is true or false
} catch (Exception e) {
e.printStackTrace();
}
Thread splashTread = new Thread() {
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
public void run() { // run thread
try {
synchronized (this) {
Thread.sleep(3000); // Screen stay for 3 sec.
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (isLogin)
{
// if (accessID == 0) { // access Id is ZERO open AddMoneyActivity.class
// try {
// } catch (Exception e) {
// e.printStackTrace();
// }
// } else if (accessID == 1) {// access Id is ONE open
ProfileStepOneActivity.class
try {
Intent intent = new Intent(SplashScreen.this, Dashboard.class);
startActivity(intent);
finishAffinity(); // Finish stack
} catch (Exception e) {
e.printStackTrace();
}
} else {// Login is False goto Login Activity
try {
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
finish();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
};
splashTread.start();
}
public void broadcastIntent() {
registerReceiver(broadcastReceiver, new
IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
#Override
protected void onPause() {
super.onPause();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
//unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onStop(){
super.onStop();
try {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
// unregisterReceiver(broadcastReceiver);
} catch (Exception e) {
e.printStackTrace();
}
}
}
My mistake....i was redirecting to main activity ie login activity in netstats class(where i was checking the net connection) ie why it was showing login screen for a moment issue resolved now

I get an error when I try to play a sound file

I have the following code that I copied from the package playsound because I would like to ask you what is the problem:
public class Playsound extends JFrame {
public Playsound() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Test Sound Clip");
this.setSize(300, 200);
this.setVisible(true);
try {
URL url = this.getClass().getClassLoader().getResource("waterdrop.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Playsound();
}
}
But when I try to run it, I get:
Exception in thread "main" java.lang.NullPointerException
at com.sun.media.sound.StandardMidiFileReader.getSequence(StandardMidiFileReader.java:207)
at javax.sound.midi.MidiSystem.getSequence(MidiSystem.java:841)
at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(SoftMidiAudioFileReader.java:178)
at javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1147)
at playsound.Playsound.<init>(Playsound.java:18)
at playsound.Playsound.main(Playsound.java:32)
It dies at this row:
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
I have this setup in the folder Image
So I would like to ask that why is it not working? Maybe it is me, maybe it is not but it does not work and it is not nice.

how to stop MediaPlayer correctly?

I can stop the Audio but if I check my Android-Studio Debug windows, i see that the MediaPlayer works in Background !!!
I play the Sound like that :
try {
myMediaPlayer1 = new MediaPlayer();
myMediaPlayer1.setAudioStreamType(AudioManager.STREAM_MUSIC);
myMediaPlayer1.setDataSource("http://myweb.com/audios/1.mp3");
myMediaPlayer1.prepare();
myMediaPlayer1.start();
} catch (Exception e) {
// TODO: handle exception
}
I stop the MediaPlayer via a click on a Button or OnDestry like that :
#Override
protected void onDestroy() {
super.onDestroy();
myMediaPlayer1.stop();
}
I debug via USB Connection. After Stop the Sound I see the MediaPlay works in Background :
You need to release media player using mediaPlayer.release(). If MediaPlayer is not playing any song/audio you shouldn't stop MediaPlayer. See below code for more help.
private void releaseMediaPlayer() {
try {
if (mediaPlayer != null) {
if (mediaPlayer.isPlaying())
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}

How do i make an android app that can record and listen at the same time

I have trouble making an app that can record and listen at the same time. I have create a recorder that is able to record and play at the moment,but i would really appreciate if someone could give suggestion on how to get started with android studio so that i can make the app to record and listen at the same time.
stop.setEnabled(false);
play.setEnabled(false);
outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/myrec.3gp";
myAudioRecorder = new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myAudioRecorder.setOutputFile(outputFile);
}
public void start(View v) {
try {
myAudioRecorder.prepare();
myAudioRecorder.start();
}catch (IllegalStateException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
start.setEnabled(false);
stop.setEnabled(true);
Toast.makeText(this,"Recording started",Toast.LENGTH_SHORT).show();
}
public void stop(View v) {
myAudioRecorder.stop();
myAudioRecorder.release();
myAudioRecorder=null;
stop.setEnabled(false);
play.setEnabled(true);
Toast.makeText(this,"Audio successfully recorded",Toast.LENGTH_SHORT).show();
}
public void play(View v) throws IOException {
MediaPlayer m=new MediaPlayer();
m.setDataSource(outputFile);
m.prepare();
m.start();
Toast.makeText(this,"Playing audio", Toast.LENGTH_SHORT).show();
}
}

Implement a MIDlet that gets invoked when a SMS is sent to port 50000

I want to create a MIDlet which automatically starts using push registry function
PushRegistry.RegisterConnection("sms://:50000", this.getclass().getname(),"*");
Following is the code which I have come up with, and cannot find the problem with it as it is not responding in any way to any message.
P.S. I am aware of the fact that dynamic registration requires me to first run the app once.
public class Midlet extends MIDlet implements CommandListener,Runnable {
private Display disp;
Form form = new Form("Welcome");
Command ok,exit;
public void startApp() {
String conn[];
exit= new Command("exit",Command.CANCEL,2);
ok= new Command("ok",Command.OK,2);
form.addCommand(ok);
form.addCommand(exit);
form.setCommandListener(this);
conn = PushRegistry.listConnections(true);
disp=Display.getDisplay(this);
disp.setCurrent(form);
form.append("Midlet");
form.append("Press OK to register sms connection");
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
public void commandAction(Command c, Displayable d) {
if(c.getLabel().equals("exit"))
{
System.out.println("exit pressed");
destroyApp(true);
}
if(c.getLabel().equals("ok"))
{
String[] cn;
cn=PushRegistry.listConnections(true);
form.append(""+cn.length);
for(int i=0;i<cn.length;i++)
{
form.append(cn[i]);
}
Thread t = new Thread(this);
t.start();
}
}
public void run() {
try {
PushRegistry.registerConnection("sms://:50000",this.getclass().getname, "*");
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
}
Your code worked when I replaced this line PushRegistry.registerConnection("sms://:50000",this.getclass().getname, "*");
with PushRegistry.registerConnection("sms://:50000",<actual name of the class>, "*");

Resources