从活动中呼叫服务

时间:2014-01-16 12:26:53

标签: android service

我正在通过活动呼叫(尝试)服务。我已经成功地在应用程序中为另一个服务构建了这样的调用。那个工作正常,但这个没有。对于我的生活,我无法弄清楚为什么。

我在代码中放了一些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>

1 个答案:

答案 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;
    }