我正在通过活动呼叫(尝试)服务。我已经成功地在应用程序中为另一个服务构建了这样的调用。那个工作正常,但这个没有。对于我的生活,我无法弄清楚为什么。
我在代码中放了一些Log.d标志,告诉我发生了什么。基本上当我在RecordActivity时,我点击一个按钮。在LogCat中,我看到OnCreate,InitRecorder和OnDestroy。但缺少onStartCommand。对我而言,这意味着onStartCommend永远不会被执行。也许你能明白为什么?
以下是服务代码:
public class SnoreSensor extends Service {
public static final int SAMPLE_RATE = 16000;
private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
// private final String startRecordingLabel = "Start recording";
// private final String stopRecordingLabel = "Stop recording";
private boolean mIsRecording = false;
private ProgressBar mProgressBar;
private static String TAG = "SnoreSensor";
int amplitudeFinal;
/**
* //REMOVED TO CHANGE FROM ACTIVITY TO SERVICE
*
* @Override public void onCreate(final Bundle savedInstanceState) {
* super.onCreate(savedInstanceState);
* setContentView(R.layout.view_snoresensor);
*
* initRecorder();
*
* mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
*
* final Button button = (Button) findViewById(R.id.button);
* button.setText(startRecordingLabel);
*
* button.setOnClickListener(new View.OnClickListener() {
* @Override public void onClick(final View v) { if (!mIsRecording) {
* button.setText(stopRecordingLabel); mIsRecording = true;
* mRecorder.startRecording(); mRecording = getFile("raw");
* startBufferedWrite(mRecording); } else {
* button.setText(startRecordingLabel); mIsRecording = false;
* mRecorder.stop(); File waveFile = getFile("wav"); try {
* rawToWave(mRecording, waveFile); } catch (IOException e) {
* Toast.makeText(SnoreSensor.this, e.getMessage(),
* Toast.LENGTH_SHORT).show(); } Toast.makeText(SnoreSensor.this,
* "Recorded to " + waveFile.getName(),
* Toast.LENGTH_SHORT).show(); } } }); }
**/
public void onCreate() {
Log.d(TAG, "OnCreate");
mIsRecording = false;
initRecorder();
}
public void onStartCommand() {
Log.d(TAG, "OnStartCommand");
mIsRecording = true;
mRecorder.startRecording();
mRecording = getFile("raw");
startBufferedWrite(mRecording);
}
@Override
public void onDestroy() {
Log.d(TAG, "OnDestroy");
mIsRecording = false;
mRecorder.stop();
File waveFile = getFile("wav");
try {
rawToWave(mRecording, waveFile);
} catch (IOException e) {
Toast.makeText(SnoreSensor.this, e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
Toast.makeText(SnoreSensor.this, "Recorded to " + waveFile.getName(),
Toast.LENGTH_SHORT).show();
mRecorder.release();
super.onDestroy();
}
private void initRecorder() {
Log.d(TAG, "initRecorder");
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(
MediaRecorder.AudioSource.VOICE_RECOGNITION, SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
}
private void startBufferedWrite(final File file) {
Log.d(TAG, "startBufferedWrite");
new Thread(new Runnable() {
@Override
public void run() {
DataOutputStream output = null;
try {
output = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(file)));
while (mIsRecording) {
double sum = 0;
int readSize = mRecorder.read(mBuffer, 0,
mBuffer.length);
for (int i = 0; i < readSize; i++) {
output.writeShort(mBuffer[i]);
sum += mBuffer[i] * mBuffer[i];
}
if (readSize > 0) {
final double amplitude = sum / readSize;
final int amplitudeFinal = (int) Math
.sqrt(amplitude);
mProgressBar.setProgress(amplitudeFinal);
Log.d(TAG, "amplitude: " + amplitudeFinal);
}
}
} catch (IOException e) {
Toast.makeText(SnoreSensor.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
} finally {
mProgressBar.setProgress(0);
if (output != null) {
try {
output.flush();
} catch (IOException e) {
Toast.makeText(SnoreSensor.this, e.getMessage(),
Toast.LENGTH_SHORT).show();
} finally {
try {
output.close();
} catch (IOException e) {
Toast.makeText(SnoreSensor.this,
e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
}
}
}
}
}).start();
}
private void rawToWave(final File rawFile, final File waveFile)
throws IOException {
byte[] rawData = new byte[(int) rawFile.length()];
DataInputStream input = null;
try {
input = new DataInputStream(new FileInputStream(rawFile));
input.read(rawData);
} finally {
if (input != null) {
input.close();
}
}
DataOutputStream output = null;
try {
output = new DataOutputStream(new FileOutputStream(waveFile));
// WAVE header
// see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
writeString(output, "RIFF"); // chunk id
writeInt(output, 36 + rawData.length); // chunk size
writeString(output, "WAVE"); // format
writeString(output, "fmt "); // subchunk 1 id
writeInt(output, 16); // subchunk 1 size
writeShort(output, (short) 1); // audio format (1 = PCM)
writeShort(output, (short) 1); // number of channels
writeInt(output, SAMPLE_RATE); // sample rate
writeInt(output, SAMPLE_RATE * 2); // byte rate
writeShort(output, (short) 2); // block align
writeShort(output, (short) 16); // bits per sample
writeString(output, "data"); // subchunk 2 id
writeInt(output, rawData.length); // subchunk 2 size
// Audio data (conversion big endian -> little endian)
short[] shorts = new short[rawData.length / 2];
ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN)
.asShortBuffer().get(shorts);
ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
for (short s : shorts) {
bytes.putShort(s);
}
output.write(bytes.array());
} finally {
if (output != null) {
output.close();
}
}
}
private File getFile(final String suffix) {
Time time = new Time();
time.setToNow();
return new File(Environment.getExternalStorageDirectory(),
time.format("%Y%m%d%H%M%S") + "." + suffix);
}
private void writeInt(final DataOutputStream output, final int value)
throws IOException {
output.write(value >> 0);
output.write(value >> 8);
output.write(value >> 16);
output.write(value >> 24);
}
private void writeShort(final DataOutputStream output, final short value)
throws IOException {
output.write(value >> 0);
output.write(value >> 8);
}
private void writeString(final DataOutputStream output, final String value)
throws IOException {
for (int i = 0; i < value.length(); i++) {
output.write(value.charAt(i));
}
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
/*********************************************
* BROADCAST THE UPDATE TO ACTIVITYRECORDSLEEP
*********************************************/
private void sendSnoreUpdate() {
Log.d(TAG, "sender Broadcasting Amplitude " + amplitudeFinal);
Intent intent = new Intent("SnoreUpdate");
intent.putExtra("Amplitude", amplitudeFinal);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}// End
在我的Activity start()中,我有以下内容来调用服务:
LocalBroadcastManager.getInstance(this).registerReceiver(
mSnoreReceiver, new IntentFilter("SnoreUpdate"));
.....
.....
//Intent startSnoreSensorService = new Intent(this, SnoreSensor.class);
//startService(startSnoreSensorService);
startService(new Intent(this, SnoreSensor.class));
我只是在测试是否存在差异,但这两种类型都运行良好。在清单中我有这个:
<service
android:name=".sensors.SnoreSensor"
android:enabled="true"
android:exported="true" >
</service>
答案 0 :(得分:0)
如果你看一下Service
类,你会看到方法onStartCommand(Intent i, int flags, int startId)
,你必须覆盖它以便以这种方式与服务进行通信。但是你创建的方法哪个签名与Service
类中声明的签名不匹配。这就是为什么在开始服务时没有调用此方法的原因。
@Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
Log.d(TAG, "OnStartCommand");
mIsRecording = true;
mRecorder.startRecording();
mRecording = getFile("raw");
startBufferedWrite(mRecording);
return START_STICKY;
}