androidaudiocountdowntimer

Start audio clip in background in Android at a particular time


I am creating an Android app in which I want to put clock ticking sound in the background and that too for last few seconds.

The audio is for 21 sec and I want it to be played in last 21 seconds of the timer. The actual timer is running for 2 minutes.

I was trying the following code :

public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
            millis = millisUntilFinished;
            if(millis == 21000){
                mp1.start();
            }
            hms = String.format("%02d:%02d", 
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
            timer.setText(hms);
            
    }

where mp1 is:

mp1 = MediaPlayer.create(AnimalMain.this,R.raw.tick_tock);

But nothing is getting played. Also, I am getting the error in the log cat as:

should have subtitle controller already set

I tried some Stack Overflow links with the same issue but could not resolve it using them.

For any reference, see the entire code here:

package com.example.jumboquest;

import android.app.Activity;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;




import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.media.MediaPlayer;


public class AnimalMain extends Activity {
    
    TextView timer, roundStatus;
    ListView jum;
    ProgressBar prog;
    EditText ans;
    ToggleButton pause;
    String s,hms,hmso;
    int[] a;
    Button next;
    static long millis;
    static CountDownTimer t;
    long toggleValue;
    String[] s1 = new String[4];
    static ArrayList<String> words;
    static ArrayAdapter<String> aa;
    static int progressStatus = 0;
    //Button match;
    static long resumeTsp;
    static boolean phoneRinging = false;
    static int scorekeeper;
    static int rnd_counter;
    boolean bonus = false;
    long bonus_millis = 0;
    MediaPlayer mp1;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        rnd_counter++;
        setContentView(R.layout.screen2);
        
        resumeTsp = 120000;
        jum = (ListView)findViewById(R.id.jum);
        ans = (EditText)findViewById(R.id.ans);
        timer = (TextView)findViewById(R.id.timer);
        roundStatus = (TextView)findViewById(R.id.desc);
        prog = (ProgressBar)findViewById(R.id.prog);
        //match = (Button) findViewById(R.id.button1);
        mp1 = MediaPlayer.create(AnimalMain.this,R.raw.tick_tock);
        roundStatus.setText("Round:" +rnd_counter);
        
        Intent intnt = getIntent();
        progressStatus = intnt.getIntExtra("prog", 0);
        
        new Thread(new Runnable(){
            public void run(){
                prog.setProgress(progressStatus);
                try{
                    Thread.sleep(5000);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
                
        // Create the array list of to do items
        words = new ArrayList<String>();
        // Create the array adapter to bind the array to the listview
        
        aa = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,words);
        // Bind the array adapter to the listview.
        jum.setAdapter(aa);
        
        
        
        InputStream i = this.getResources().openRawResource(R.raw.first_round);
        String line = null;
        int currentLineNo = 1;
        int min = 1;
        int max = 49;
        
        int startLine = 0;
        int endLine = 0;
        Random rand = new Random();
        switch(rnd_counter){
        case 1:
            min = 1;
            max = 28;
            break;
        case 2:
            min = 32;
            max = 59;
            break;
        case 3:
            min = 63;
            max = 92;
            break;
        }
        
        int r = rand.nextInt((max - min) + 1) + min;
        
        startLine = r;
        endLine = r+3;
        
        BufferedReader in = null;
        try {
            in = new BufferedReader (new InputStreamReader(i));         
            //read to startLine
            while(currentLineNo<startLine) {
                if (in.readLine()==null) {
                    // oops, early end of file
                    throw new IOException("File too small");
                }
                ++currentLineNo;
            }
            
            int i1=0;
            //read until endLine
            while(currentLineNo<=endLine) {
                line = in.readLine();
                if (line==null) {
                    // here, we'll forgive a short file
                    // note finally still cleans up
                    return;
                }
                s1[i1]=line;
                //= new StringBuffer(line).reverse().toString();
                
                List<Character> jumble = new ArrayList<Character>();
                StringBuilder sample = new StringBuilder(line.length());
                for(char c : line.toCharArray()){
                    jumble.add(c);
                }
                //int flag_first = 0;
                while(jumble.size() != 0){
                    int rnd = (int)(Math.random()*jumble.size());
                    if(rnd == 0 && jumble.size() == line.length()){
                        continue;
                    }
                    else{
                        sample.append(jumble.remove(rnd));
                    }
                }
                
                words.add(sample.toString());
                aa.notifyDataSetChanged();
                ++i1;
                
                ++currentLineNo;
                
            }
            
        } catch (IOException ex) {
            System.out.println("Problem reading file.\n" + ex.getMessage());
        } finally {
            try { if (in!=null) in.close(); } catch(IOException ignore) {}
        }
                
        a = new int[4];
        a[0] = 0;
        a[1] = 0;
        a[2] = 0;
        a[3] = 0;
        
        
      /*  match.setOnClickListener(new OnClickListener(){
            public void onClick(View v){
                String answer = ans.getText().toString();
                if(answer.equalsIgnoreCase(s1[0])){
                    words.remove(0);
                    aa.notifyDataSetChanged();
                    words.add(0,answer);
                    aa.notifyDataSetChanged();
                }
                else if(answer.equalsIgnoreCase(s1[1])){
                    words.remove(1);
                    aa.notifyDataSetChanged();
                    words.add(1,answer);
                    aa.notifyDataSetChanged();
                }
                else if(answer.equalsIgnoreCase(s1[2])){
                    words.remove(2);
                    aa.notifyDataSetChanged();
                    words.add(2,answer);
                    aa.notifyDataSetChanged();
                }
                else if(answer.equalsIgnoreCase(s1[3])){
                    words.remove(3);
                    aa.notifyDataSetChanged();
                    words.add(3,answer);
                    aa.notifyDataSetChanged();
                }
            }
        });*/
        
        jum.setOnItemClickListener(new OnItemClickListener() {

                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                        long arg3) {
                    String selected = jum.getItemAtPosition(arg2).toString();
                    s= ans.getText().toString();
                     
                    if(s.equals(s1[arg2]))
                    {
                        a[arg2]=1;
                        //Toast.makeText(getApplicationContext(), "CORRECT!! Now Crack the Next One.. :) ", Toast.LENGTH_SHORT).show();
                        words.remove(arg2);
                        aa.notifyDataSetChanged();
                        words.add(arg2,s);
                        aa.notifyDataSetChanged();
                        arg1.setEnabled(false);
                        
                        ans.setText("");
                        if(a[0]==1 && a[1]==1 && a[2]==1 && a[3]==1)
                        {
                                    
                                    t.cancel();
                                    if(millis >= 60000){
                                        bonus = true;
                                        bonus_millis = (millis/1000)-60;
                                    }
                                    //scorekeeper += 40;
                                    Intent i=new Intent(getApplicationContext(), AnimalDatabase.class);
                                    i.putExtra("milli", millis);
                                    i.putExtra("score", scorekeeper);
                                    i.putExtra("bonus", bonus);
                                    i.putExtra("round", rnd_counter);
                                    i.putExtra("bonus_score",bonus_millis);
                                    //i.putExtra("progress",progressStatus);
                                    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                    startActivity(i);
                                    //Toast.makeText(getApplicationContext(), "WELL DONE!! All the best for the quiz :) ", Toast.LENGTH_LONG).show();
                                //  finish();
                                    
                            
                        }
                    }
                    else
                    {
                        ans.setText(s);
                        Toast.makeText(getApplicationContext(), "INCORRECT :( Try Again.. ", Toast.LENGTH_SHORT).show();
                    }
                    
                }
            });
        
        
        TelephonyManager telephonyManager =  
                (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
   
        PhoneStateListener callStateListener = new PhoneStateListener() {  
            public void onCallStateChanged(int state, String incomingNumber)   
            {  
        
                if(state==TelephonyManager.CALL_STATE_RINGING){  
                    resumeTsp = millis;
                    t.cancel();
                    timer.setText("Game Paused!");
                    Toast.makeText(getApplicationContext(),"Phone Is Riging",  
                                                                   Toast.LENGTH_LONG).show();  
                }  
                if(state==TelephonyManager.CALL_STATE_OFFHOOK){  
                    Toast.makeText(getApplicationContext(),"Phone is Currently in A call",   
                                                                            Toast.LENGTH_LONG).show();  
                }  
                if(state==TelephonyManager.CALL_STATE_IDLE){  
                    t = new StartTimer(resumeTsp,1000);
                    t.start();
                    
                }  
            }  
        };  
        telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);  
    
    }
    
    @Override
    public void onBackPressed(){
        return;
    }
    
    class StartTimer extends CountDownTimer{
        public StartTimer(long duration, long interval){
                super(duration, interval);
        }
            
        public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
            millis = millisUntilFinished;
            //if(millis == 21000){
            //  Toast.makeText(getApplicationContext(), String.valueOf(millis), Toast.LENGTH_SHORT).show();
            //  mp1.start();
            //}
            hms = String.format("%02d:%02d", 
                    TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
                    TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
            timer.setText(hms);
            
        }
        
        @Override
        public void onFinish() {
            //time up
            phoneRinging = false;
            timer.setText("TIME UP!");
            mp1.stop();
            ans.setEnabled(false);
            for(int j = 0; j<4;j++){
                timer.setText("SOLUTION:");
                words.remove(j);
                aa.notifyDataSetChanged();
                words.add(j,s1[j]);
                aa.notifyDataSetChanged();
            }
        }
        
        
    }
}

Solution

  • It can be done by simply adding delay instead of checking timer value in the OnTick() which will not work. The delay can be added in the following way :

    final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    // Do something after 5s = 5000ms
                    mp1.start();
                    mp1.setLooping(true);
                }
            }, 100000);
    

    put the delay after which you want to start the audio in background and it worked in my case.