Deal with blank background layout for RecognizerIn

2019-09-12 05:26发布

问题:

i am newbie in to android studio and java. i am making an app using speech recognition. The app is working fine but i decided to look into this issue.

STT dialog screen after button is pressed

blank background layout if user pressed back or touch outside the STT dialog

If user said something, the activity works ok. But if the user pressed back or touch outside the dialog. A blank layout is shown which i want to avoid.

this STT activity will be called via widget and the app activity.

STT activity in manifests

    <activity
        android:name=".RecordActivity"
        android:label="@string/title_record"
        android:theme="@android:style/Theme.Dialog" />

launch STT via Widget

        Intent popUpIntent = new Intent(context, RecordActivity.class);
        popUpIntent.setAction("com.XXX.XXX.FROM_WIDGET");
        popUpIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        popUpIntent.putExtra("fileName", recordFile.getAbsolutePath());
        context.startActivity(popUpIntent);

launch STT via Activity

        Intent popUpIntent = new Intent(this, RecordActivity.class);
        popUpIntent.putExtra("fileName", recordFile.getAbsolutePath());
        startActivityForResult(popUpIntent , START_RECORD);

STT activity:

public class RecordActivity extends Activity  implements RecognitionListener {

//
private static final int REQUEST_SPEECH_TO_TEXT = 1;

private String fileName;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    promptSpeechInput();
    // Read Filename
    Intent intent = getIntent();
    fileName = intent.getStringExtra("fileName");
}

public void onSubmit(View view) {
    finish();
}

/**
 * Receiving speech input
 * */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    switch (requestCode) {
        case REQUEST_SPEECH_TO_TEXT: {
            if (resultCode == RESULT_OK && null != data) {
                // the resulting text is in the getExtras:
                Bundle bundle = data.getExtras();
                ArrayList<String> matches = bundle.getStringArrayList(RecognizerIntent.EXTRA_RESULTS);

                // Default 
                contentText = matches.get(0);
                Uri audioUri = data.getData();
                ...
                setResult(Activity.RESULT_OK, result);
                finish();
            }
            break;
        }

    }
}

private void promptSpeechInput() {
    Intent voiceIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
            RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
    voiceIntent.putExtra("android.speech.extra.DICTATION_MODE", true);       // can listen for a long time
    voiceIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_MINIMUM_LENGTH_MILLIS, 10000);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);
    voiceIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_POSSIBLY_COMPLETE_SILENCE_LENGTH_MILLIS, 5000);
    voiceIntent.putExtra("android.speech.extra.GET_AUDIO_FORMAT", "audio/AMR");
    voiceIntent.putExtra("android.speech.extra.GET_AUDIO", true);
    try {
        startActivityForResult(voiceIntent, REQUEST_SPEECH_TO_TEXT);
    } catch (ActivityNotFoundException a) {
        Toast.makeText(getApplicationContext(),
                getString(R.string.record_audio_denied),
                Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onReadyForSpeech(Bundle params) {

}

@Override
public void onBeginningOfSpeech() {

}

@Override
public void onRmsChanged(float rmsdB) {

}

@Override
public void onBufferReceived(byte[] buffer) {

}

@Override
public void onEndOfSpeech() {

}

@Override
public void onError(int error) {

}

@Override
public void onResults(Bundle results) {

}

@Override
public void onPartialResults(Bundle partialResults) {

}

@Override
public void onEvent(int eventType, Bundle params) {

}

}

In this activity, please forgive me in not deleting those RecognitionListener methods, because i was going to embed those methods myself instead of using RecognizerIntent in this activity.

Actually, i work around with Theme.NoDisplay in manifests that the beep sound works but STT dialog does not show up until it catches error (i.e. no sounds)

STT part in manifests

    <activity
        android:name=".RecordActivity"
        android:label="@string/title_record"
        android:theme="@android:style/Theme.NoDisplay" />

In my mind, there are few possible solutions:

1) maybe some intent.setAction("") or intent.setFlags() will help - mostly perferable

2) "@android:style/Theme.NoDisplay" might actually work - preferable

3) add finish() to touch action and OnBackpressed in RecognizerIntent - less preferable

4) implement RecognitionListener instead - i will go this way if none of above works.

5) use STT as service in background - required a bit of more work

===============================================================================

OK, thank you for pointing out this link which is same as my option (4) and then i have some issue getting the audio data by making my own RecognitionListener...(sorry for not mentioning I need the text and audio output from RecognizerIntent before...problem after a problem), i have updated my Activity code with few lines getting text and audio...

seem to me, in order to get the audio data, this approach lacks of obvious resource. but from this link and i am looking at some code example,

RecognitionService.Callback says about bufferReceived

and RecognitionService.Callback is what i am trying to understand now.

but back to this question, i wonder if anyone could suggest an easier way for my issue, because if there is not, i may come up with option 6.

6) put a fancy custom layout to replace the blank layout