Android节拍器

写完Java节拍器,本以为能够很容易的过渡到Android节拍器。后来发现不对。在网上查询了之后,才知道,Android考虑到线程安全问 题,不允许在线程中执行UI线程。这里我们要学到一个Android中重要的类:android.os.Handler,这个可以实现各处线程间的消息传 递。

      我们可以在原先的TimerTask子类MyTimerTask的方法run()中,只是给Handler发送一个Message。我们让Handler进行UI线程上的操作(在节拍器的例子中,指的是更新那个显示节拍的控件的数值)。

      最终节拍器打节拍的同时发生。(由于时间原因,音量控制尚未实现)实现截图如下:

 
    

 

Java代码
  1. package  com.Android.Jiapaiqi;  
  2.   
  3. import  android.app.Activity;  
  4. import  android.content.Context;  
  5. import  android.media.AudioManager;  
  6. import  android.media.SoundPool;  
  7. import  android.os.Bundle;  
  8. import  android.os.Handler;  
  9. import  android.os.Message;  
  10. import  android.view.View;  
  11. import  android.view.View.OnClickListener;  
  12. import  android.widget.Button;  
  13. import  android.widget.EditText;  
  14. import  android.widget.SeekBar;  
  15. import  android.widget.TextView;  
  16. import  android.widget.SeekBar.OnSeekBarChangeListener;  
  17.   
  18. import  java.util.Timer;  
  19. import  java.util.TimerTask;  
  20.   
  21. public   class  ActivityMain  extends  Activity {  
  22.       
  23.     Button button_start;  
  24.     Button button_stop;  
  25.     EditText edit_sudu;  
  26.     EditText edit_paishu;  
  27.     TextView result;  
  28.     SeekBar seekbar;  
  29.     public   float  tempo;  
  30.     public   int  section;  
  31.     public   int  pp;  
  32.     Handler handler;  
  33.     Timer mytimer;  
  34.       
  35.     private  SoundPool sndHigh;  
  36.     private  SoundPool sndLow;  
  37.     private   int  hitOfHigh;  
  38.     private   int  hitOfLow;  
  39.       
  40.     //声音控制   
  41.     private  AudioManager audioManager;  
  42.     //声音变量   
  43.     private   int  volume= 0 ;  
  44.     //声音模式   
  45.     //private int mode;   
  46.     //是否有声音   
  47.     private   int  flag= 1 ;  
  48.       
  49.     //内部类   
  50.     class  MyTimerTask  extends  TimerTask{  
  51.   
  52.         @Override   
  53.         public   void  run() {           
  54.             Message message=new  Message();  
  55.             message.what=1 ;  
  56.             handler.sendMessage(message);  
  57.         }     
  58.     };  
  59.       
  60.     /** Called when the activity is first created. */   
  61.     @Override   
  62.     public   void  onCreate(Bundle savedInstanceState) {  
  63.         super .onCreate(savedInstanceState);  
  64.    
  65.         pp=1 ;  
  66.         setContentView(R.layout.main);  
  67.           
  68.         final  EditText edit_sudu = (EditText) this .findViewById(R.id.edit_sudu);  
  69.         final  EditText edit_paishu = (EditText) this .findViewById(R.id.edit_paishu);  
  70.         final  TextView result = (TextView)findViewById(R.id.result);  
  71.           
  72.         handler = new  Handler()  
  73.         {  
  74.             public   void  handleMessage(Message msg)  
  75.             {  
  76.                 switch (msg.what)  
  77.                 {  
  78.                 case   1 :  
  79.                     result.setText(String.valueOf(pp));  
  80.                         if (pp== 1 )  
  81.                             // play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)   
  82.                             //播放音频,可以对左右音量分别设置,还可以设置优先级,循环次数以及速率   
  83.                             sndHigh.play(hitOfHigh, 11001 );  
  84.                         else   
  85.                             sndLow.play(hitOfLow, 11001 );  
  86.                     if (pp!=section)  
  87.                     {  
  88.                         pp++;  
  89.                     }  
  90.                     else   
  91.                     {  
  92.                         pp=1 ;  
  93.                     }  
  94.                         break ;  
  95.                 }  
  96.                 super .handleMessage(msg);  
  97.             }  
  98.         };  
  99.           
  100.         button_start = (Button) findViewById(R.id.button_start);  
  101.         button_start.setOnClickListener(new  OnClickListener() {  
  102.             public   void  onClick(View v) {  
  103.                 tempo=Float.parseFloat(edit_sudu.getText().toString());   
  104.                 section=Integer.parseInt(edit_paishu.getText().toString());   
  105.                 mytimer=new  Timer();  
  106.                 float  tempFloat= 60 /tempo* 1000 ;  
  107.                 mytimer.schedule(new  MyTimerTask(), 0 , ( long )tempFloat);  
  108.             }  
  109.         });  
  110.               
  111.         button_stop = (Button) findViewById(R.id.button_stop);  
  112.         button_stop.setOnClickListener(new  OnClickListener() {  
  113.             public   void  onClick(View v) {  
  114.                 mytimer.cancel();  
  115.                 sndHigh.pause(hitOfHigh);  
  116.                 sndLow.pause(hitOfLow);  
  117.             }  
  118.         });  
  119.               
  120.         final  SeekBar seekbar = (SeekBar) findViewById(R.id.seekbar);  
  121.         //设置拖动条的初始值和文本框的初始值   
  122.         seekbar.setMax(7 );  
  123.         seekbar.setProgress(5 );  
  124.         seekbar.setOnSeekBarChangeListener(new  OnSeekBarChangeListener()  
  125.         {  
  126.             @Override   
  127.             public   void  onProgressChanged(SeekBar seekBar,  int  progress,  
  128.                     boolean  fromUser) {  
  129.                 // TODO Auto-generated method stub   
  130.             }  
  131.             @Override   
  132.             public   void  onStartTrackingTouch(SeekBar seekBar) {  
  133.                 // TODO Auto-generated method stub   
  134.   
  135.             }  
  136.             @Override   
  137.             public   void  onStopTrackingTouch(SeekBar seekBar) {  
  138.                 // TODO Auto-generated method stub   
  139.             }  
  140.         });  
  141.         audioManager = (AudioManager) getBaseContext().getSystemService(Context.AUDIO_SERVICE);  
  142.         //通过getStreamVolume获得当前音量大小   
  143.         volume=audioManager.getStreamVolume(AudioManager.STREAM_RING);  
  144.         //把当前音量的值 设置给进度条   
  145.         //seekbar.setProgress(volume);   
  146.           
  147.         sndHigh = new  SoundPool( 10 , AudioManager.STREAM_SYSTEM, 5 );  
  148.         //载入音频流   
  149.         hitOfHigh = sndHigh.load(getBaseContext(), R.drawable.high, 0 );  
  150.           
  151.         sndLow = new  SoundPool( 10 , AudioManager.STREAM_SYSTEM, 5 );  
  152.         //载入音频流   
  153.         hitOfLow = sndLow.load(getBaseContext(), R.drawable.low, 0 );  
  154.     }  

要在Android Studio中实现节拍器功能,可以按照以下步骤进行操作: 1. 创建一个新的Android项目或打开现有项目。 2. 在项目的布局文件中添加一个按钮和一个文本视图,用于控制和显示节拍器的信息。 3. 在活动类中找到按钮的引用,并设置一个点击事件监听器。 4. 在点击事件监听器中初始化一个计时器,并设置计时器的定时任务。 5. 在定时任务中执行节拍器的逻辑。可以使用`MediaPlayer`类播放声音或使用`Vibrator`类控制震动。 下面是一个简单的示例代码: ```java public class MainActivity extends AppCompatActivity { private Button startButton; private TextView beatTextView; private Timer timer; private int beatCount; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startButton = findViewById(R.id.start_button); beatTextView = findViewById(R.id.beat_textview); startButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startMetronome(); } }); } private void startMetronome() { if (timer != null) { timer.cancel(); } timer = new Timer(); beatCount = 0; TimerTask timerTask = new TimerTask() { @Override public void run() { // 执行节拍器逻辑 beatCount++; playSound(); // 播放声音或控制震动 updateBeatCount(); } }; // 以1000毫秒为间隔执行定时任务 timer.scheduleAtFixedRate(timerTask, 0, 1000); } private void playSound() { // 在这里实现播放声音或控制震动的逻辑 } private void updateBeatCount() { runOnUiThread(new Runnable() { @Override public void run() { beatTextView.setText("当前节拍数:" + beatCount); } }); } } ``` 请注意,上述代码只是一个简单的示例,你还需要根据自己的需求进行更多的定制和扩展。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值