java - 播放音乐的Android应用几秒钟后停止工作

标签 java android audio audiotrack

我已经制作了一个可产生声音并播放声音的android应用程序,它在我的模拟器上可以正常工作,但是在我的实际设备上,大约一分钟后,它“停止工作”。有什么想法吗?
这是几乎所有事情发生的类(class):

package com.funguscow;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;

public class Afspl extends Activity {

    public DrawView vi;
    private Point size;
    Display disp;
    public int wide, high, cx, cy;
    boolean doPlay = false;
    Thread soundPlayer;
    int note = 0;
    int lastNote = note;
    boolean changed = false;
    int countTick = 0;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        disp = getWindowManager().getDefaultDisplay();
        try{
            disp.getSize(size);
            wide = size.x;
            high = size.y;
        }catch(Exception e){
            wide = disp.getWidth();
            high = disp.getHeight();
        }
        cx = 0; //tracks mouse x
        cy = 0; //tracks mouse y
        vi = new DrawView(getApplicationContext());
        setContentView(vi);
        soundPlayer = new Thread(new Runnable(){
            public void run(){
                int count = 0;
                while(true){
                    try{
                    Thread.sleep((long)(duration * 10));
                    }catch(Exception e){}
                    //if(++countTick>)
                    if(!doPlay){
                        if(count==1 && track.getState()==AudioTrack.STATE_INITIALIZED)track.stop();
                        continue;
                    }
                    lastNote = note;
                    note = cy * 12 / high;
                    changed = (lastNote!=note);
                    if(cx > wide/2)note+=12;
                    int freq = (int)(440 * Math.pow(1.059463, note));
                    genTone(freq);
                    if(count==0){
                    handler.post(new Runnable(){
                        public void run(){
                            playSound();
                        }
                    });
                    count++;
                    }else{
                        handler.post(new Runnable(){
                            public void run(){
                                if(++countTick >= 10){
                                    countTick = 0;
                                    return;
                                }
                                track.release();
                                playSound();
                            }
                        });
                    }
                }
            }
        });
        soundPlayer.start();
    }

    private int waveType = 0;


    class DrawView extends View{
        Paint paint = new Paint();

        public DrawView(Context context){
            super(context);
        }

        public void onDraw(Canvas c){
            int red = 256;
            int green = 0;
            int blue = 0;
            int curInc = 0;
            for(int i=0; i<24; i++){
                if(curInc==0){
                    green += 256/2;
                    if(green>=256){
                        curInc = 1;
                    }
                }
                else if(curInc == 1){
                    red -= 256/2;
                    if(red<=0){
                        curInc = 2;
                    }
                }
                else if(curInc == 2){
                    blue += 256/2;
                    if(blue >= 256){
                        curInc = 3;
                    }
                }
                else if(curInc == 3){
                    green -= 256/2;
                    if(green<=0){
                        curInc = 4;
                    }
                }
                else if(curInc == 4){
                    red += 256/2;
                    if(red>=256){
                        curInc = 5;
                    }
                }else if(curInc == 5){
                    blue -= 256/2;
                    if(blue<=0){
                        curInc=0;
                    }
                }
                int width = wide;
                int start = 0;
                if(i<12){
                    width/=2;
                }
                else{
                    start = width/2;
                    red = 256-red;
                    green = 256-green;
                    blue = 256-blue;
                }

                paint.setColor(getColor(red, blue, green));
                int height = high / 12;
                int starty = i * height;
                int endy = (i+1) * height;
                if(i>=12){
                    starty = (i-12) * height;
                    endy = (i-11) * height;
                }
                c.drawRect(start, starty, width, endy, paint);
            }
            paint.setColor(Color.WHITE);
            c.drawRect((wide * 11)/12, (high*11)/12, wide, high, paint);
        }
        public int getColor(int r, int g, int b){
            int red = (r << 16) & 0x00ff0000;
            int green = (g << 8) & 0x0000ff00;
            int blue = b & 0x000000ff;
            return 0xff000000 | red | green | blue;
        }
    }

    public boolean onTouchEvent(MotionEvent me){
        int type = me.getActionMasked();
        switch(type){
        case MotionEvent.ACTION_DOWN:
            cx = (int)me.getX();
            cy = (int)me.getY();
            doPlay = true;
            return true;
        case MotionEvent.ACTION_UP:
            doPlay = false;
            if(cx > (wide * 11)/12 && cy > (high * 11)/12){
                if(++waveType>3)waveType=0;
            }
            return true;
        case MotionEvent.ACTION_MOVE:
            cx = (int)me.getX();
            cy = (int)me.getY();
            return true;
        default:
            return super.onTouchEvent(me);
        }
    }

    public double duration = 1;
    public int sampleRate = 8000;
    public int numSamples = (int)duration * sampleRate;
    public final double[] samples = new double[numSamples];
    public final byte[] generatedSnd = new byte[numSamples * 2];
    public Handler handler = new Handler();
    AudioTrack track;


    public void genTone(int freq){
        float period = (float)sampleRate / (float)freq;

        for(int i = 0; i<numSamples; i++){
            switch(waveType){
            case 0:
                samples[i] = Math.sin(2 * i * Math.PI / period);
                break;
            case 1:
                samples[i] = (int)(i/period) % 2 == 0 ? -1 : 1;
                break;
            case 2:
                samples[i] = (i % period)/period;
                break;
            default:
                samples[i] = ( 2 * Math.asin(Math.sin(2 * Math.PI * i / period)) / Math.PI);
            }
        }
        int idx = 0;
        int efcx = cx;
        if(cx>wide/2)efcx = wide-cx;
        int volume = 32767 * 2 * efcx/wide;
        for (final double dVal : samples) {
            final short val = (short) ((dVal) * volume);

            generatedSnd[idx++] = (byte) (val & 0x00ff);
            generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
        }
    }


    public void playSound(){
        track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length, AudioTrack.MODE_STATIC);
        track.write(generatedSnd, 0, generatedSnd.length);
        track.play();
    }




}

那么...如何在不“停止工作”的情况下使该应用正常运行?这个类有什么我应该改变的吗?如果您有答案,请不要含糊其词,请告诉我编码问题以及如何解决。谢谢。

最佳答案

在调用stop()之前,我必须检查track.getState()不是STATE_UNINITIALIZED,并且track.getPlayState()不是PLAYSTATE_STOPPED。

关于java - 播放音乐的Android应用几秒钟后停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27349429/

相关文章:

c# - 如何将计算机音频传递给程序以进行可视化?

java - 如何使用 JSF 获取用户的浏览器 ID?

java - 复选框节点树

android - SeekBar进度更新重绘整个ViewGroup

android - Maven 和 Android Facebook SDK apklib

audio - .Ogg 与 .mp3 用于移动应用程序?

html - 让盲人适应网站

java - 如何处理 Selenium 页面对象模型中的动态元素?

java - getView() 在第二个 Activity 中返回 null

android - 如何让 Android 应用程序在下载和安装后自动运行?