当我在android手机或模拟器上运行这个类时,应用程序甚至没有启动。我将非常感谢任何改进:)
public class Whistly extends Activity implements OnClickListener,
OnSeekBarChangeListener {
private SeekBar seekBar;
private Button k5;
private Button k10;
private Button k15;
private Button k20;
private ToggleButton whistle;
private TextView frequency;
private Integer intToneFreq = Integer.parseInt(String.valueOf(seekBar.getProgress()));
private final int duration = 2; // seconds
private final int sampleRate = 8000;
private final int numSamples = duration * sampleRate;
private final double sample[] = new double[numSamples];
private int freqOfTone = intToneFreq * 1000; // hz
private final byte generatedSnd[] = new byte[2 * numSamples];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_whistly);
seekBar = (SeekBar) findViewById(R.id.seekBar);
k5 = (Button) findViewById(R.id.k5);
k10 = (Button) findViewById(R.id.k10);
k15 = (Button) findViewById(R.id.k15);
k20 = (Button) findViewById(R.id.k20);
whistle = (ToggleButton) findViewById(R.id.toggleButton1);
frequency = (TextView) findViewById(R.id.textView1);
seekBar.setMax(25);
seekBar.setOnSeekBarChangeListener(this);
k5.setOnClickListener(this);
k10.setOnClickListener(this);
k15.setOnClickListener(this);
k20.setOnClickListener(this);
whistle.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.whistly, menu);
return true;
}
@Override
public void onClick(View v) {
if (v == k5) {
frequency.setText(R.string.k5);
seekBar.setProgress(5);
}
if (v == k10) {
frequency.setText(R.string.k10);
seekBar.setProgress(10);
}
if (v == k15) {
frequency.setText(R.string.k15);
seekBar.setProgress(15);
}
if (v == k20) {
frequency.setText(R.string.k20);
seekBar.setProgress(20);
}
if (v == whistle) {
if(whistle.isChecked()){
playSound();
}
}
}
@Override
protected void onResume() {
super.onResume();
// Use a new tread as this can take a while
final Thread thread = new Thread(new Runnable() {
public void run() {
genTone();
}
});
thread.start();
}
void genTone() {
// fill out the array
for (int i = 0; i < numSamples; ++i) {
sample[i] = Math.sin(2 * Math.PI * i / (sampleRate / freqOfTone));
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
int idx = 0;
for (final double dVal : sample) {
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
void playSound() {
final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
String progress1 = String.valueOf(progress);
frequency.setText(progress1 + " kHz");
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
你不能这么做
private Integer intToneFreq = Integer.parseInt(String.valueOf(seekBar.getProgress()));
在静态初始化式中;在执行的早期,当它运行时,您还没有任何内容视图来包含膨胀的SeekBar,并且您还没有将SeekBar变量指向它。
你可以简单地通过初始化intToneFreq为一些安全的默认值来解决你的直接问题,并且只有当你的应用程序完全启动时才尝试读取进度条。但很可能你也会发现其他问题。正如在注释中提到的,您需要学习使用logcat工具和/或源代码调试器。