Android и ACRCloud: startRecording() вызывается для неинициализированного AudioRecord

Я разрабатываю простое приложение для распознавания музыки, используя этот SDK https://www.acrcloud.com/docs/audio-fingerprinting-sdks/android-sdk/

Демонстрация, предоставленная SDK, отлично работает на моем телефоне, целевой Android SDK — 18. В настоящее время я разрабатываю это приложение для minSdkVersion 19и targetSdkVersion 24. С точки зрения кода, ничто не отличается от демо, кроме макета Activity.

Вот мой код:

import com.dd.CircularProgressButton;

import com.acrcloud.rec.sdk.ACRCloudConfig;
import com.acrcloud.rec.sdk.ACRCloudClient;
import com.acrcloud.rec.sdk.IACRCloudListener;
import com.acrcloud.rec.sdk.utils.ACRCloudLogger;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MainActivity extends AppCompatActivity implements IACRCloudListener {

    //Main recognition class and config objects
    private ACRCloudClient mClient;
    private ACRCloudConfig mConfig;

    private TextView successOrFail;

    private CircularProgressButton recognitionButton;

    //recognition flags
    private boolean mProcessing = false;
    private boolean initState = false;

    //path for local db, if necessary
    //private String path = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_activity);


        recognitionButton = (CircularProgressButton) findViewById(R.id.startRecognition);
        recognitionButton.setIndeterminateProgressMode(true);
        recognitionButton.setText(R.string.rec_start);
        recognitionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                start();
                recognitionButton.setProgress(50);
            }
        });

        final CircularProgressButton cancelButton = (CircularProgressButton) findViewById(R.id.stopRecogition);
        cancelButton.setText(R.string.rec_cancel);
        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                cancel();
                cancelButton.setProgress(-1);
            }
        });

        successOrFail = (TextView) findViewById(R.id.successOrFailView);

        //Configure ACRCloud
        this.mConfig = new ACRCloudConfig();
        this.mConfig.acrcloudListener = this;
        this.mConfig.context = this;
        this.mConfig.host = "xxxxxxxxxxxxxx";
        this.mConfig.accessKey = "xxxxxxxxxxxxxxxx";
        this.mConfig.accessSecret = "xxxxxxxxxxxxxxxx";
        this.mConfig.reqMode = ACRCloudConfig.ACRCloudRecMode.REC_MODE_REMOTE;

        this.mClient = new ACRCloudClient();

        this.initState = this.mClient.initWithConfig(this.mConfig);
        if (this.initState) {
            this.mClient.startPreRecord(3000);
        }
    }


    //Start recognition
    public void start() {
        if (!this.initState) {
            Toast.makeText(this, "init error", Toast.LENGTH_SHORT).show();
            return;
        }

        if (!mProcessing) {
            mProcessing = true;
            if (this.mClient == null || !this.mClient.startRecognize()) {
                mProcessing = false;
                //mResult.setText("start error!");
            }
        }
    }

    //recognition canceled
    protected void cancel(){
        if(mProcessing && this.mClient != null){
            mProcessing = false;
            this.mClient.cancel();
        }
    }


    //handle result
    @Override
    public void onResult(String result) {
        if (this.mClient != null) {
            this.mClient.cancel();
            mProcessing = false;
        }


        try {
            JSONObject j = new JSONObject(result);
            JSONObject j1 = j.getJSONObject("status");
            int j2 = j1.getInt("code");
            if(j2 == 0){
                successOrFail.setVisibility(View.VISIBLE);
                successOrFail.setText(R.string.success);
                recognitionButton.setProgress(100);
            }else{
                successOrFail.setVisibility(View.VISIBLE);
                successOrFail.setText(R.string.error);
                recognitionButton.setProgress(0);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onVolumeChanged(double volume){

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("MainActivity", "release");
        if (this.mClient != null) {
            this.mClient.release();
            this.initState = false;
            this.mClient = null;
        }
    }
}

и я получаю это исключение

08-31 16:38:20.119 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err: java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
08-31 16:38:20.119 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at android.media.AudioRecord.startRecording(AudioRecord.java:943)
08-31 16:38:20.119 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at com.acrcloud.rec.record.ACRCloudRecorder.startRecording(ACRCloudRecorder.java:64)
08-31 16:38:20.119 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at com.acrcloud.rec.sdk.worker.ACRCloudWorker.run(ACRCloudWorker.java:215)
08-31 16:38:20.139 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
08-31 16:38:20.139 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 I/System.out: (HTTPLog)-Static: isSBSettingEnabled false
08-31 16:38:21.789 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err: java.lang.IllegalStateException: stop() called on an uninitialized AudioRecord.
08-31 16:38:21.789 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at android.media.AudioRecord.stop(AudioRecord.java:996)
08-31 16:38:21.789 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at com.acrcloud.rec.record.ACRCloudRecorder.release(ACRCloudRecorder.java:133)
08-31 16:38:21.789 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at com.acrcloud.rec.sdk.worker.ACRCloudWorker.resumeRecognize(ACRCloudWorker.java:126)
08-31 16:38:21.789 29895-30448/musicmappr.abon219.com.musicmappr_prototype1 W/System.err:     at com.acrcloud.rec.sdk.worker.ACRCloudWorker.run(ACRCloudWorker.java:222)

любые советы по этому вопросу будут очень, очень признательны


person Anthony Bonarrigo    schedule 31.08.2016    source источник


Ответы (2)


Вы использовали эмулятор Android для тестирования? Эмулятор Android не использует микрофон компьютера.

person Tony Li    schedule 01.09.2016
comment
Нет, это на реальном устройстве, и на самом деле это скорее комментарий. - person Anthony Bonarrigo; 01.09.2016
comment
Какую версию Android вы используете? Можете ли вы повторить демонстрационный проект с более низкой targetSdkVersion? - person Tony Li; 01.09.2016

Поскольку ответы не были предоставлены, я предоставлю свой собственный вклад, чтобы помочь любому, кто использует этот SDK с этой проблемой.

После уровня API 23 вам НЕОБХОДИМО запрашивать разрешения у пользователя. Добавления разрешения к AndroidManifest недостаточно. Следующий фрагмент кода является примером:

if(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) ActivityCompat.requestPermissions(this, new String[{Manifest.permission.RECORD_AUDIO}, 1);

person Anthony Bonarrigo    schedule 26.09.2016