Android Open Source - api-ai-android-sdk A I Button






From Project

Back to project page api-ai-android-sdk.

License

The source code is released under:

Apache License

If you think the Android project api-ai-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package ai.api.ui;
/*  w  ww . j av a2s  .c o m*/
/***********************************************************************************************************************
 *
 * API.AI Android SDK - client-side libraries for API.AI
 * =================================================
 *
 * Copyright (C) 2014 by Speaktoit, Inc. (https://www.speaktoit.com)
 * https://www.api.ai
 *
 ***********************************************************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 *
 ***********************************************************************************************************************/

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import ai.api.AIConfiguration;
import ai.api.AIListener;
import ai.api.AIService;
import ai.api.R;
import ai.api.model.AIError;
import ai.api.model.AIResponse;

public class AIButton extends SoundLevelButton implements AIListener {

    public interface AIButtonListener{
        public void onResult(final AIResponse result);
        public void onError(final AIError error);
    }

    private static final String TAG = AIButton.class.getName();

  protected static final int[] STATE_WAITING = {R.attr.state_waiting};
  protected static final int[] STATE_SPEAKING = {R.attr.state_speaking};

  private float animationStage = 0;
  private boolean animationSecondPhase = false;
  private final WaitingAnimation animation = new WaitingAnimation();

    private AIService aiService;
    private AIButtonListener resultsListener;

    private final ExecutorService eventsExecutor = Executors.newSingleThreadExecutor();

    @Override
    public void onResult(final AIResponse result) {

        post(new Runnable() {
            @Override
            public void run() {
                changeState(MicState.normal);
            }
        });

        if (resultsListener != null) {
            resultsListener.onResult(result);
        }
    }

    @Override
    public void onError(final AIError error) {
        post(new Runnable() {
            @Override
            public void run() {
                changeState(MicState.normal);
            }
        });

        if (resultsListener != null) {
            resultsListener.onError(error);
        }
    }

    @Override
    public void onAudioLevel(final float level) {
        setSoundLevel(level);
    }

    @Override
    public void onListeningStarted() {
        post(new Runnable() {
            @Override
            public void run() {
                changeState(MicState.listening);
            }
        });
    }

    @Override
    public void onListeningFinished() {
        post(new Runnable() {
            @Override
            public void run() {
                changeState(MicState.busy);
            }
        });
    }

    public enum MicState {
    normal,
    busy, // transitive state with disabled mic
    listening, // state with sound indicator
    speaking;

    public static MicState fromAttrs(final TypedArray viewAttrs) {
      if (viewAttrs.getBoolean(R.styleable.SoundLevelButton_state_listening, false))
        return listening;
      if (viewAttrs.getBoolean(R.styleable.SoundLevelButton_state_waiting, false))
        return busy;
      if (viewAttrs.getBoolean(R.styleable.SoundLevelButton_state_speaking, false))
        return speaking;
      return normal;
    }
  }

  private MicState currentState = MicState.normal;

  public AIButton(final Context context) {
    super(context);
    init(context, null);
  }

  public AIButton(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
  }

  public AIButton(final Context context, final AttributeSet attrs, final int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs);
  }

  private void init(final Context context, final AttributeSet attrs) {
    if (attrs != null) {
      final TypedArray viewAttrs = context.obtainStyledAttributes(attrs, R.styleable.SoundLevelButton);
      try {
        currentState = MicState.fromAttrs(viewAttrs);
      } finally {
        viewAttrs.recycle();
      }
    }
  }

    public void initialize(final AIConfiguration config) {
        aiService = AIService.getService(getContext(), config);
        aiService.setListener(this);
    }

    public void setResultsListener(final AIButtonListener resultsListener) {
        this.resultsListener = resultsListener;
    }

    @Override
    protected void onClick(final View v) {
        super.onClick(v);

        if (aiService != null) {
            if (currentState != MicState.normal) {
                eventsExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        aiService.cancel();
                    }
                });
            } else {
                eventsExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        aiService.startListening();
                    }
                });
            }
        }

    }

    @Override
  public int[] onCreateDrawableState(final int extraSpace) {
    final int[] state = super.onCreateDrawableState(extraSpace + 1);
    if (currentState != null) {
      switch (currentState) {
        case normal:
          break;
        case busy:
          mergeDrawableStates(state, STATE_WAITING);
          break;
        case listening:
          mergeDrawableStates(state, STATE_LISTENING);
          break;
        case speaking:
          mergeDrawableStates(state, STATE_SPEAKING);
          break;
      }
    }
    return state;
  }

  @Override
  protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();

    if (!isInEditMode()) {
            if (aiService != null) {
                aiService.pause();
            }
        }
    }

  @Override
  protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    if (!isInEditMode()) {
            if (aiService != null) {
                aiService.resume();
            }
        }
    }

    private void changeState(final MicState toState) {
    switch (toState) {
      case normal:
        stopProcessingAnimation();
        setDrawSoundLevel(false);
        break;
      case busy:
        startProcessingAnimation();
        setDrawSoundLevel(false);
        break;
      case listening:
        stopProcessingAnimation();
        setDrawSoundLevel(true);
        break;
      case speaking:
        stopProcessingAnimation();
        setDrawSoundLevel(false);
        break;
    }

    currentState = toState;
    refreshDrawableState();
  }

  private void startProcessingAnimation() {
    setDrawCenter(true);
    animationSecondPhase = false;
    startAnimation(animation);
  }

  private void stopProcessingAnimation() {
    setDrawCenter(false);
    clearAnimation();
    animationStage = 0;
    animationSecondPhase = false;
    postInvalidate();
  }

  @Override
  protected String getDebugState() {
    return super.getDebugState() + "\nst:" + currentState;
  }

  private class WaitingAnimation extends Animation {
    protected WaitingAnimation() {
      super();
      setDuration(1500);
      this.setRepeatCount(INFINITE);
      this.setRepeatMode(RESTART);
      this.setInterpolator(new LinearInterpolator());

    }

    @Override
    protected void applyTransformation(final float interpolatedTime, final Transformation t) {
      animationStage = interpolatedTime;
      invalidate();
    }
  }

  @Override
  protected void onDraw(final Canvas canvas) {
    super.onDraw(canvas);
    if (animationStage > 0 || animationSecondPhase) {
      final float center = getWidth() / 2f;
      final float radius = getMinRadius() * 1.25f;
      final RectF size = new RectF(center - radius, center - radius, center + radius, center + radius);
      final Paint paint = new Paint();
      paint.setColor(getResources().getColor(R.color.icon_orange_color));
      paint.setStyle(Paint.Style.STROKE);
      paint.setStrokeWidth(dpToPixels(this.getContext(), 4));
      paint.setStrokeCap(Paint.Cap.ROUND);
      paint.setAntiAlias(true);
      final float startingAngle;
      final float sweepAngle;
      if (animationStage < 0.5 && !animationSecondPhase) {
        startingAngle = 0;
        sweepAngle = animationStage * 360;
      } else {
        startingAngle = (animationStage - 0.5f) * 360;
        sweepAngle = 180;
        animationSecondPhase = true;
      }
      canvas.drawArc(size, 270f + startingAngle, sweepAngle, false, paint);
    }
  }

    private static int dpToPixels(final Context context, final float dp) {
        final Resources r = context.getResources();
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
    }
}




Java Source Code List

ai.api.AIConfiguration.java
ai.api.AIDataService.java
ai.api.AIListener.java
ai.api.AIServiceException.java
ai.api.AIService.java
ai.api.AudioRequestTask.java
ai.api.AudioRequest.java
ai.api.GoogleRecognitionServiceImpl.java
ai.api.GsonFactory.java
ai.api.RecognitionEngine.java
ai.api.RequestTask.java
ai.api.SpeaktoitRecognitionServiceImpl.java
ai.api.http.HttpClient.java
ai.api.model.AIContext.java
ai.api.model.AIError.java
ai.api.model.AIRequest.java
ai.api.model.AIResponse.java
ai.api.model.Constants.java
ai.api.model.Metadata.java
ai.api.model.QuestionMetadata.java
ai.api.model.Result.java
ai.api.model.Status.java
ai.api.sample.AIButtonSampleActivity.java
ai.api.sample.AIServiceSampleActivity.java
ai.api.sample.Config.java
ai.api.sample.MainActivity.java
ai.api.ui.AIButton.java
ai.api.ui.MaskedColorView.java
ai.api.ui.SoundLevelButton.java
ai.api.ui.SoundLevelCircleDrawable.java
ai.api.util.RecognizerChecker.java
ai.api.util.VoiceActivityDetector.java