I am trying to play 5 SoundPool one after the other on Background using AsyncTask for it. But I wanna click an ImageView while sounds are running. The problem begins when SoundPool uses getBaseContext() that blocks my ImageView while doInBackground is running.
Does anyone know whats happening?
Thxs a lot!
Here is my code:
public class SensoriomotoraActivity extends Activity {
private boolean playing = false ;
private ImageView image ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sensoriomotora);
image = (ImageView) findViewById(R.id.img_sensoriomotora_pandereta);
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (playing){
Log.v("onClick","clicked while playing");
}
else {
Log.v("onClick","clicked while !playing");
}
}
});
new Thread (
new Runnable(){
#Override
public void run(){
// Waiting 2.5 secs before playing the beeps
try {
Thread.sleep(2500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
new PlaySoundBackground().execute();
}
});
}
}
).start();
}
private class PlaySoundBackground extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
playing = true ;
}
#Override
protected Void doInBackground(Void... params) {
SoundPool sound;
sound = new SoundPool(1, AudioManager.STREAM_MUSIC,0);
sound.load(getBaseContext(), R.raw.beep, 1);
sound.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
for (int i=0 ; i<5; i++){
soundPool.play(sampleId, 1, 1, 1, 0, 1);
try {
Thread.sleep(2000); // Waits 2 secs before next beep
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
playing = false ;
}
}
}
Related
I have a background class named "TCP client" that sets a boolean to true whenever a state change is detected in hardware. And runOnUIThread in main activity detects this and updates UI which are switch buttons, in order not to trigger the OncheckedChangeListener I set the listener to null, change state, then set the listener to its original one. But during runtime OncheckedChangeListener is still triggering. I guess this is a synchronization problem.
mainActivity.java
public class MainActivity extends AppCompatActivity {
public SwitchButton.OnCheckedChangeListener switchListener;
public com.suke.widget.SwitchButton switch;
public static boolean switchflag=false;
int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
setContentView(R.layout.activity_main);
switch = findViewById(R.id.lightSwitch);
runThread();
switchListener = new SwitchButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(SwitchButton view, boolean bChecked) {
if (bChecked) {
Log.d("button", "light is on");
connection.tcpClient.sendMessage("li1_1");
} else {
Log.d("Button", "light is off");
connection.tcpClient.sendMessage("li1_0");
}
}
};
switch.setOnCheckedChangeListener(switchListener);
}
private void runThread() {
i = 0;
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(connection.tcpClient.getStatusFlag()) {
Log.d("main", "got Status");
updateUI();
connection.tcpClient.setStatusFlag(false);
}
}
});
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
public void updateUI() {
try {
switch.setOnCheckedChangeListener(null);
switch.setChecked(switchFlag);
switch.setOnCheckedChangeListener(switchListener);
}catch (NullPointerException e) {e.printStackTrace();}
}
I am not getting where to use the synchronized.
Put
runThread();
below
switch.setOnCheckedChangeListener(switchListener);
Also Replace
switch.setChecked(lightFlag);
With
switch.setChecked(switchFlag);
I am working on an online radio app and I tried implementing a seek bar to it like the tunein. I gave the seekbar a max value since i could not use the MediaPlayer's .getDuration() method.
I successfully implemented it but when I try moving the seekbar it goes back to its previous position and somehow my play/pause button stops working.
HERE IS THE SUMMARISED CODE
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_radio);
handler = new Handler(); //for seekbar
seekBar = (SeekBar) findViewById(R.id.seekBar);
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(radioLink);
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (started) {
started = false;
mediaPlayer.pause();
playButton.setImageResource(R.drawable.pplay);
} else {
started = true;
mediaPlayer.start();
playButton.setImageResource(R.drawable.ppause);
}
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b)
{
mediaPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
class PlayerTask extends AsyncTask<String, Void, Boolean> {
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
loadingSoundtxt.setVisibility(View.GONE);
playButton.setVisibility(View.VISIBLE);
seekBar.setMax(1800000); //30mins in milliseconds
mediaPlayer.start();
changeSeekbar();
}
}
private void changeSeekbar(){
seekBar.setProgress(mediaPlayer.getCurrentPosition());
if (mediaPlayer.isPlaying())
{
runnable = new Runnable() {
#Override
public void run() {
changeSeekbar();
}
};
handler.postDelayed(runnable, 1000);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) mediaPlayer.release();
}
}
I want to show numbers from 1 to 100 in sequel order in the TextView and to wait 1 second after printing each number. I also want to implement it using Android services.
I don't know the difference between UIHandler and Handler. When I google about this issue, all I am getting is the difference between handler and a thread.
Please help me out of this,
Thanks in advance
private static final int SHOW_MESSAGE = 1;
private static final int m_cdelay = 1000;
private UIHandler m_cUIHandler;
public int m_cI= 0;
TextView m_cTextShow;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_cTextShow = (TextView) findViewById(R.id.textview1);
for(m_cI=1; m_cI <= 100; m_cI++){
//m_cUIHandler = new UIHandler();
//m_cUIHandler.sendEmptyMessageDelayed(SHOW_MESSAGE, 1000);
showMessage(m_cI);
}
}
private void showMessage(int m_cI2) {
for(m_cI=1; m_cI <= 100; m_cI++){
m_cTextShow.setText(""+m_cI);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
try {
Thread.sleep(m_cdelay);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}).start();
}
}
#Override
protected void onResume() {
super.onResume();
startService(new Intent(this, NumberService.class));
}
public final class UIHandler extends Handler {
#Override
public void handleMessage(Message pObjMessage) {
switch(pObjMessage.what) {
case SHOW_MESSAGE:
m_cTextShow.setText(""+m_cI);
break;
}
}
}
You can actually rewrite your code like that to make it probably work.
Pls test it and respond.
public void showMessage(int number){
runOnUiThread(new Runnable(){
public void run() {
//Write your number onto the screen
}
});
}
protected void onCreate(Bundle savedInstanceState) {
//Blablabla...
for(m_cI=1; m_cI <= 100; m_cI++){
//m_cUIHandler = new UIHandler();
//m_cUIHandler.sendEmptyMessageDelayed(SHOW_MESSAGE, 1000);
showMessage(m_cI);
Thread.sleep(1000);
}
}
I have been spending couple hours to try to update the textview inside the dialog, but failed.
When the option is clicked, there are new dialog is shown, and inside the dialog, there are textviews and button, when I click the button, the textview will be update.
Here is the code related to the button onClick listener:
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
for (int i = 0; i < 50 ; i ++){
final String currentNum = String.valueOf(i + 1);
Thread t = new Thread() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(currentNum); //it is fine
currentNum.setText(currentNum); //it is the problem, the setText only work when the for loop is finished.
}
});
}
};
t.start();
}
}
});
Please let me know if you need more information. Thanks a lot in advance!
//it is a optionmenu
case R.id.action_refresh:
final TextView currentNum;
final ImageButton start;
String currentNum = Integer.toString(songList.size());
final Dialog lyricsAnalysis = new Dialog(this,R.style.cust_dialog);
lyricsAnalysis.requestWindowFeature(Window.FEATURE_NO_TITLE);
lyricsAnalysis.setContentView(R.layout.analysis);
lyricsAnalysis.setCancelable(true); //back button to cancel
lyricsAnalysis.setCanceledOnTouchOutside(true);
start = (ImageButton) lyricsAnalysis.findViewById(R.id.start);
//first value
currentNum.setText(String.valueOf(currentNum));
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
for (int i = 0; i < 50 ; i ++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
updateTextView(lyricsAnalysis,i);
}
}
});
lyricsAnalysis.show();
lyricsAnalysis.getWindow().setLayout(600, 1000);
break;
}
return super.onOptionsItemSelected(item); }
public void updateTextView(Dialog dialog, int i) {
final TextView currentNum = (TextView) dialog.findViewById(R.id.currentNum);
currentNum.setText(Stri`enter code here`ng.valueOf(i));
//return;
}
Try this method. This may helps you. It's work for me.(But I am not use this in dialog)
public void updateTextView(String toThis) {
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(toThis);
//return;
}
try like this
int elapsedtime=0;
boolean isTimerRunning=false;
Timer timerr;
inside onCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//declare your textview here;
timerr=new Timer();
startTimer();
}
/*
* timer for displaying message bubble
*/
protected static void startTimer() {
isTimerRunning = true;
elapsedtime = 0;
// recordingseek.setProgress(0);
timerr.scheduleAtFixedRate(new TimerTask() {
public void run() {
// increase every sec
elapsedtime++;
mmHandler.obtainMessage(1).sendToTarget();
System.out.println("recording time" + elapsedtime);
if(elapsedtime==50)
timerr.cancel();
}
}, 1000, 2000);
};
public static Handler mmHandler = new Handler() {
public void handleMessage(Message msg) {
textview.setText(elapsedtime);
}
};
}
};
Is it possible, if yes how, how do i go from progress 100 to 1 without the user doing anything.
Like for every .05sec seekbar.setProgress(-=1)
So without the user doing anything the seekbar will go down until it reach 1.
Please anser how to do this
Thank-you
class Async extends AsyncTask<Void, Integer, Void>{
ProgressDialog dialog;
public Async(Context ctx) {
dialog = new ProgressDialog(ctx);
dialog.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
dialog.incrementProgressBy(1);
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
dialog.dismiss();
super.onPostExecute(result);
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
int i=0;
while (i < 1000) {
publishProgress(1);
i++;
}
return null;
}
}
You may be forced to write your own progress bar. Here's an example: http://techdroid.kbeanie.com/2010/04/custom-progressbar-for-android.html
There's more than one way to do it...
Something roughly like this (note: may not compile):
private int progressStatus = 100;
new Thread(new Runnable()
{
public void run()
{
while (progressStatus > 1)
{
progressStatus = doSomeWork();
//---Update the progress bar---
handler.post(new Runnable()
{
public void run() {
progressBar.setProgress(progressStatus);
}
});
}
handler.post(new Runnable()
{
public void run() {
// Do your thing here when it's done
}
});
}
private int doSomeWork()
{
try
{
//---simulate doing some work---
Thread.sleep(50);
} catch (InterruptedException e)
{
e.printStackTrace();
}
int progress = progressStatus - 1;
return progress;
}
}).start();