I wrote a guitar tuner in music application. The main activity launch the tuner when click on button. The tuner works fine. But if I come back to main activity.
The Tuner activity start, but pitch detection does not.
The thread don't stop for the recorder.
I launch an activity Act_Accordage from the main activity with
public void clicAccordage(View v){
Intent intentAct_Accordage = new Intent(this, Act_Accordeur .class);
startActivity(intentAct_Accordage);
}
Here is my Act_Accordage activity
public final AudioDispatcher dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(22050, 2048, 0);
....
dispatcher.addAudioProcessor(new PitchProcessor(PitchEstimationAlgorithm.YIN, 22050, 2048, new PitchDetectionHandler() {
#Override
public void handlePitch(PitchDetectionResult pitchDetectionResult,
AudioEvent audioEvent) {
final float pitchInHz = pitchDetectionResult.getPitch();
if (Logo.interrupted()) {
return;
}
if (pitchInHz > -1) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// display name note and cursor ou UI thread
textFreqNote.setText(String.valueOf(pitchInHz) + " CREATE ");
Affcurseur(pitchInHz);
});
}
}
}));
new Thread(dispatcher, "Audio Dispatcher");
2***/I come back main with button or backbutton
public void onclicSetBackMain(View v) {
Act_Accordeur.this.finish();
Toast.makeText(Act_Accordeur.this, "Guitare accordée", Toast.LENGTH_LONG).show();}
Use dispatcher.stop(); to stop the Audio Dispatcher thread.It took me a long time in the official documentation but it was worth it.
Related
I have an application in which I'm receiving a sms containing his location.On receiving sms it calls another activity to start and passes that location to that activity to plot it on the map.Before calling the second activity it shows a toast like notification on the screen but somehoe due to calling second activity that toast doesn't come up.My question is how can we delay the calling of second activity from this activity ?
You can use something like this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i=new Intent(SearxhJobs.this,JobsTypes.class);
startActivity(i);
}
}, 5000);
Here it waits upto 5 seconds to launch activity.
Hope it helps
You can do it with a Handler like this
Handler h = new Handler(){
#Override
public void handleMessage(Message msg) {
Intent i = new Intent().setClass(ctx, MainActivity.class);
startActivity(i);
}
};
h.sendEmptyMessageDelayed(0, 1500); // 1500 is time in miliseconds
Make an AsyncClass that does Thread.sleep() in the doInBackground() method, then navigate to your new activity in the your onPostExecute() method.
Call your toast message and then execute the AsyncClass.
For Kotlin
Handler().postDelayed({
val i = Intent(this, MainActivity::class.java)
startActivity(i)
}, 5000)
Try:
Runnable r = new Runnable() {
#Override
public void run() {
// if you are redirecting from a fragment then use getActivity() as the context.
startActivity(new Intent(SplashActivity.this, MainActivity.class));
// To close the CurrentActitity, r.g. SpalshActivity
finish();
}
};
Handler h = new Handler();
// The Runnable will be executed after the given delay time
h.postDelayed(r, 1500); // will be delayed for 1.5 seconds
Simply set the layout!
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setContentView(R.layout.next); //where <next> is you target activity :)
}
}, 5000);
An example would be the following:
Handler TimeDelay=new Handler();
if(previous=="geofence"){
tts.speak(previous,TextToSpeech.QUEUE_ADD,null, null);
Runnable r = new Runnable() {
#Override
public void run() {
/*
Intent intent = new Intent(
MyBroadcastMessageReceiver.class.getName());
intent.putExtra("some additional data", choice);
someActivity.sendBroadcast(intent);*/
tts.speak(previous,TextToSpeech.QUEUE_ADD,null, null);
}
};
TimeDelay.postDelayed(r, 150000);
I am making an alarm clock which asks user to do a particular work in order to close the alarm when it rings. It is working fine but the problem is that if the user closes the alarm app from the recent activities while the alarm is ringing, the alarm stops ringing. I want that even if the user clears the app while its ringing, it should not stop ringing. It should only stop once the task given is completed. How can I implement this?
Edit #1: Activity that is called when alarm rings
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOG_TAG, "in AlarmAlert");
unlockScreen();
setContentView(R.layout.activity_alarm_alert);
Bundle bundle = this.getIntent().getExtras();
alarm = (Alarm) bundle.getSerializable("alarm");
alarmDatabase = new AlarmDatabase(this);
//Uri uri = alarm.getRingtonePath();
question = (TextView)findViewById(R.id.question);
answer = (TextView) findViewById(R.id.answer);
oldColors = answer.getTextColors();
diff = alarm.getDifficulty().toString();
questionString = GenerateMathsQuestion.generateQuestion(diff);
question.setText(questionString);
actualAnswer = EvaluateString.evaluate(questionString);
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
int result = am.requestAudioFocus(focusChangeListener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mediaPlayer = new MediaPlayer();
mediaPlayer.setVolume(1.0f, 1.0f);
mediaPlayer.setLooping(true);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
try {
mediaPlayer.setDataSource(this, Uri.parse(alarm.getRingtonePath()));
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.start();
}
if(alarm.getIsVibrate()) {
vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
long[] pattern = {1000, 200, 200, 200};
vibrator.vibrate(pattern, 0);
}
}
public void closeAlarm(){
Log.v(LOG_TAG, "will now stop");
mediaPlayer.stop();
if(vibrator!=null)
vibrator.cancel();
Log.v(LOG_TAG, "will now release");
mediaPlayer.release();
Log.v(LOG_TAG, "id of ringing alarm: " + alarm.getAlarmId());
alarm.setIsActive(false);
alarmDatabase.updateData(alarm);
cursor = alarmDatabase.sortQuery();
while(cursor.moveToNext()){
int id = cursor.getInt(cursor.getColumnIndex(AlarmDatabase.COLUMN_UID));
currentAlarm = alarmDatabase.getAlarm(id);
Log.v(LOG_TAG, "id of next alarm " + id);
if(currentAlarm != null) {
if (currentAlarm.getIsActive() == true) {
currentAlarm.scheduleAlarm(this, true);
break;
}
}
}
this.finish();
}
You should use Services. Take a look at it, that is what you want it. Generally you can make it to run an operation, and a service wont return any result. But it runs indefinitely even when you kill the app from task manager or free RAM.
I suggest this tutorial for reading about services.
UPDATE
Implement your activity with the service in the following way so it can talk with the layout and stops the alarm when required.
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
#Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
Hey I am doing a simple Android app and I am trying to a start new activity from a thread like this:
public void startUI (){
Thread t = new Thread(){
public void run () {
runOnUiThread(new Runnable() {
#Override
public void run() {
Intent goToMenu = new Intent(getApplicationContext(), MainMenu.class);
startActivity(goToMenu);
}
});
;}
};
t.start;
}
But when my code comes to this line
Intent goToMenu = new Intent(getApplicationContext(), MainMenu.class);
It crashes and writes: "application stopped working".
If you want to start an activity you need to use Activity context as a first parameter. If you use Application context then your MainMenu activity must have a FLAG_ACTIVITY_NEW_TASK flag set. You cannot start new activity in the same task from application context.
Refer: http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK
As #Raghunandan mentioned, if you want a delay, you should use a Handler like this:
uiHandler.postDelayed(new Runnable() {
#Override
public void run() {
Intent goToMenu = new Intent(getApplicationContext(), MainMenu.class);
goToMenu.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(goToMenu);
}
}, 500);
I was using following code to play sound. Everything worked fine before ICS. But on ICS and higher versions no sound is heard. There is no error, but no sound can be heard.
EDIT: Note, the following code is triggered by a broadcase receiver. BroadCast receiver invokes a async task. In the post process method of asycn task the following method is called.
What could the error possibly be?
public static void playSound(final Context context, final int volume,
Uri uri, final int stream, int maxTime, int tickTime) {
//stopPlaying();
/*
if (stream < 0 || stream > 100) {
throw new IllegalArgumentException(
"volume must be between 0 and 100 .Current volume "
+ volume);
}*/
final AudioManager mAudioManager = (AudioManager) context
.getSystemService(Context.AUDIO_SERVICE);
int deviceLocalVolume = getDeviceVolume(volume,
mAudioManager.getStreamMaxVolume(stream));
Log.d(TAG,
"device max volume = "
+ mAudioManager.getStreamMaxVolume(stream)
+ " for streamType " + stream);
Log.d(TAG, "playing sound " + uri.toString()
+ " with device local volume " + deviceLocalVolume);
final int oldVolume = mAudioManager.getStreamVolume(stream);
// set the volume to what we want it to be. In this case it's max volume
// for the alarm stream.
Log.d(Constants.APP_TAG, "setting device local volume to " + deviceLocalVolume);
mAudioManager.setStreamVolume(stream, deviceLocalVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
final MediaPlayer mediaPlayer = new MediaPlayer();
golbalMMediaPlayer = mediaPlayer;
try {
final OnPreparedListener OnPreparedListener = new OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mp) {
Log.d(TAG, "onMediaPlayercompletion listener");
mp.start();
countDownTimer.start();
}
};
mediaPlayer.setDataSource(context.getApplicationContext(), uri);
mediaPlayer.setAudioStreamType(stream);
mediaPlayer.setLooping(false);
mediaPlayer.setOnPreparedListener(OnPreparedListener);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
Log.d(Constants.APP_TAG, "Entered onCompletion listener of mediaplayer");
mAudioManager.setStreamVolume(stream, oldVolume,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
try{
if(mediaPlayer != null && mediaPlayer.isPlaying()){
mediaPlayer.release();
}
}catch(Exception ex){
Log.e(Constants.APP_TAG, "error on oncompletion listener" ,ex);
}
}
});
CountDownTimer timer = new CountDownTimer(maxTime*1000, tickTime*1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.d(TAG, "tick while playing sound ");
}
#Override
public void onFinish() {
Log.d(TAG, "timer finished");
stopPlaying();
}
};
countDownTimer = timer;
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e(TAG, "problem while playing sound", e);
} finally {
}
}
LOGS:
:07-01 00:00:00.030: D/beephourly(9500): device max volume = 7 for streamType 5
07-01 00:00:00.030: D/beephourly(9500): playing sound content://media/internal/audio/media/166 with device local volume 7
07-01 00:00:00.030: D/beephourly(9500): setting device local volume to 7
07-01 00:00:00.080: D/beephourly(9500): vibrating with pattern = [J#428bae20
07-01 00:00:00.090: D/beephourly(9500): will show normal notification
07-01 00:00:00.100: D/beephourly(9500): notification is enabled
07-01 00:00:00.100: D/usersettings(9500): hr = 0
07-01 00:00:00.110: D/beephourly(9500): onMediaPlayercompletion listener
07-01 00:00:00.451: D/beephourly(9500): tick while playing sound
07-01 00:00:20.460: D/beephourly(9500): timer finished
07-01 00:00:20.460: D/beephourly(9500): got request to stop playing
07-01 00:00:20.460: D/beephourly(9500): cancelling countdowntimer
07-01 00:00:20.460: D/beephourly(9500): releasing mediaplayer now
Try this :
Playing sound
public class PlaySound extends Activity implements OnTouchListener {
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View view = findViewById(R.id.textView1);
view.setOnTouchListener(this);
// Set the hardware buttons to control the music
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
// Load the sound
soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
#Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = soundPool.load(this, R.raw.sound1, 1);
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// Getting the user sound settings
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
if (loaded) {
soundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
return false;
}
}
Layout file :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Click on the screen to start playing" >
</TextView>
</LinearLayout>
Source link : http://www.vogella.com/tutorials/AndroidMedia/article.html#sound
Sometimes MediaPlayer objects have to be declared as a public variable or they will be deleted by the Dalvik Heap.
public final MediaPlayer mediaPlayer = new MediaPlayer();
private MediaPlayer mPlayer;
....
SoundPool sp = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
int iTmp = sp.load(getBaseContext(), R.raw.windows_8_notify, 1);
sp.play(iTmp, 1, 1, 0, 0, 1);
mPlayer = MediaPlayer.create(getBaseContext(), R.raw.windows_8_notify);
mPlayer.start();
mPlayer.setLooping(true); }
First , where all your privates are , before the onCreate, put the first line, then, Inside the onCreate start the music, just make sure to change the "windows_8_notify" to the name of the song you want.
I would Wrap the call in an IllegalStateException, run it through the debugger and see what you get.
Things to try
Set the boolean isPlaying=mp.isPlaying(); and check its value.
Try a mp.reset() before starting and see if it works.
Implement MediaPlayer.OnErrorListener and register the method with the media player.
See what error you get. This might be helpful.
LOGS
...streamType 5
StreamType 5 means STREAM_NOTIFICATION.
(Called from notification?)
It should be STREAM_MUSIC (3)
To check it's not ICS/device specific problem,
- place a sound file (sound_01.ogg or sound_01.mp3) under res/raw/ folder
- place buttons named start_button and stop_button in main_layout
and try this.
(I've checked this code with API10 and API19 emulator and sounds are played.)
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity
// implements MediaPlayer.OnPreparedListener
{
private MediaPlayer mediaPlayer;
private boolean isPrepared;
private boolean isPlaying;
private View start_button;
private View stop_button;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
Init();
}
#Override
protected void onResume()
{
super.onResume();
Load();
}
#Override
protected void onPause()
{
super.onPause();
Unload();
}
private void Init()
{
setVolumeControlStream(AudioManager.STREAM_MUSIC);
start_button = findViewById(R.id.start_button);
stop_button = findViewById(R.id.stop_button);
start_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Play();
}
});
stop_button.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Stop();
}
});
}
private void Load()
{
Unload();
// load from resource (res/raw/xx.ogg or .mp3)
// It's better to use thread
mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sound_01); // On success, prepare() will already have been called
// mediaPlayer.setOnPreparedListener(this); // cannot set this listener (MediaPlayer.create does not return before prepared)
isPrepared = true;
}
private void Unload()
{
isPrepared = false;
if (null != mediaPlayer)
{
mediaPlayer.release();
mediaPlayer = null;
}
}
// #Override
// public void onPrepared(MediaPlayer mp)
// {
// isPrepared = true;
// }
private void Play()
{
// If you got "start called in state xx" error, no sound will be heard.
// To reset this error, call reset(), setDataSource() and prepare()
// (for resources: call release() and create())
if (!isPrepared)
{
return;
}
mediaPlayer.start();
isPlaying = true;
}
private void Stop()
{
// Do not omit this check
// or you will get "called in wrong state" errors
// like "pause called in state 8"
// and error (-38, 0)
if (!isPlaying)
{
return;
}
isPlaying = false;
mediaPlayer.pause();
mediaPlayer.seekTo(0);
}
}
If it's ICS/device specific, these links may help. (A little old...)
after small sound is played, no sound will be heard
Issue 35861: Low Volume sound cut out - ICS Galaxy Note
audio focus bug
Issue 1908: No Audio with Android 4.0.4 ICS Galaxy Tab 10.1
device specific problem
No sound during calls (samsung galaxy s3 problem)
You might have a problem if you are using other AsyncTasks or the SerialExecutor in another task elsewhere in your program (and you may not even know it if you are using third party SDK's).
See the post here:
https://code.google.com/p/android/issues/detail?id=20941
I'm suggesting this because your sound "tick" isn't working either. So it isn't a matter of AudioPlayer executing with an incorrect setting necessarily, but rather some other task appears to be blocking it until that task stops, and it probably is a task that runs concurrently with when you expect to hear sound.
I'm using finish() to end a thread in my SplashScreen activity and when I do the app gets minimized before going to Activity2. How can I end the SplashScreen activity and go to Activity2 without calling finish() so the app won't minimize?
public class SplashScreen extends Activity {
/**
* The thread to process splash screen events
*/
private Thread mSplashThread;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Splash screen view
setContentView(R.layout.splash);
final SplashScreen sPlashScreen = this;
// The thread to wait for splash screen events
mSplashThread = new Thread(){
#Override
public void run(){
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(5000);
}
}
catch(InterruptedException ex){
}
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, MainActivity.class);
startActivity(intent);
//stop();
}
};
mSplashThread.start();
}
/**
* Processes splash screen touch events
*/
#Override
public boolean onTouchEvent(MotionEvent evt)
{
if(evt.getAction() == MotionEvent.ACTION_DOWN)
{
synchronized(mSplashThread){
mSplashThread.notifyAll();
}
}
return true;
}
}
call finish after startActivity
mSplashThread = new Thread(){
#Override
public void run(){
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(5000);
}
}
catch(InterruptedException ex){
}
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, MainActivity.class);
startActivity(intent);
//call finish after startActivity
finish();
//stop();
}
};
mSplashThread.start();
I do it like this:
private class IntentLauncher extends Thread {
#Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME*1000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
// Start main activity
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
SplashActivity.this.startActivity(intent);
SplashActivity.this.finish();
}
}