Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

latest Android updates #1950

Merged
merged 56 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
e6b68bb
blue background for users' requests in chat
abiemann Jul 1, 2019
eee8227
added demo feature to update widgets of 3rd party app
abiemann Jul 1, 2019
2df4caa
added ISO 8601 timestamps to generated activity events
abiemann Jul 2, 2019
c0f4f6e
pull from upstream (#11)
abiemann Jul 3, 2019
e2f1535
Merge branch 'master' into work_in_progress
abiemann Jul 3, 2019
ab5c193
removed timestamp from Activity events
abiemann Jul 3, 2019
3e40bba
added Timezone feature. Fixes #1678
abiemann Jul 8, 2019
31274ef
removed unnecessary Directline constant
abiemann Jul 8, 2019
7d5c4c3
updates:
abiemann Jul 9, 2019
6ce7387
Settings screen cleanup
abiemann Jul 9, 2019
120169d
Merge branch 'master' of
abiemann Jul 9, 2019
8761e06
Merge branch 'microsoft-master'
abiemann Jul 9, 2019
d67b479
Merge branch 'master' into work_in_progress
abiemann Jul 9, 2019
18dc686
fix merge for these files with special chars
abiemann Jul 9, 2019
329a74e
Improved broadcasting to 3rd-party apps
abiemann Jul 9, 2019
cbbd950
Latest Android Assistant updates (#1771) (#14)
abiemann Jul 9, 2019
2bdce1d
updated LocationProvider to function without Play Store installed
abiemann Jul 11, 2019
69d91a6
added missing fields to Activity model
abiemann Jul 11, 2019
117d6ed
fixed spaces in InputHints model
abiemann Jul 11, 2019
217ce9e
pulling latest upstream changes (#15)
abiemann Jul 11, 2019
0c8ac53
Merge branch 'master' into work_in_progress
abiemann Jul 11, 2019
23afe24
merged latest upstream changes
abiemann Jul 11, 2019
2717267
fixes #1755 Clean up test events in sidebar
abiemann Jul 11, 2019
36e0469
updated build gradle after Android Studio Update
abiemann Jul 11, 2019
e42a6c7
latest upstream changes (#16)
abiemann Jul 11, 2019
4d3959b
Merge branch 'work_in_progress'
abiemann Jul 11, 2019
0484d98
updated documentation
abiemann Jul 11, 2019
2e33ad6
Merge remote-tracking branch 'upstream/master'
abiemann Jul 11, 2019
dfdabbb
fixed merge
abiemann Jul 11, 2019
e560960
Merge remote-tracking branch 'upstream/master'
abiemann Jul 11, 2019
0a010c7
Merge branch 'work_in_progress'
abiemann Jul 11, 2019
0cf8ba0
continued fixing merge issues
abiemann Jul 11, 2019
39d6523
additional merge-fixed files
abiemann Jul 11, 2019
a86af5a
updated documentation
abiemann Jul 12, 2019
dc1788d
documentation update
abiemann Jul 13, 2019
e18b4e1
latest upstream updates (#18)
abiemann Jul 15, 2019
5123b42
updated documentation (#19)
abiemann Jul 15, 2019
f3751b2
Merge branch 'master' into master
abiemann Jul 16, 2019
5e2a1df
Latest Android Updates (#1828) (#20)
abiemann Jul 16, 2019
1ac61cd
latest upstream updates (#21)
abiemann Jul 16, 2019
510aba0
fixes restarting conversation #1846
abiemann Jul 16, 2019
47e130f
WIP updating Settings
abiemann Jul 17, 2019
b806028
fixes #1849 Update default colors & add configuration
abiemann Jul 18, 2019
69ebb55
latest upstream updates (#22)
abiemann Jul 18, 2019
00c6080
code cleanup
abiemann Jul 18, 2019
13c4a2c
Merge branch 'master' into work_in_progress
abiemann Jul 18, 2019
2b36d36
Merge branch 'master' into master
abiemann Jul 18, 2019
cf99d3f
fixes #1848 (added dark theme)
abiemann Jul 23, 2019
31d0307
fixes MaterialButton inflation exception
abiemann Jul 24, 2019
caf264c
finishing touches - fixes #1848 (dark theme)
abiemann Jul 24, 2019
22350ef
fixes #1677 Animated graphic when app is listening
abiemann Jul 24, 2019
f631432
fixes #1911 Incorporate support of Input hints for Mic open and close
abiemann Jul 25, 2019
03b4e20
update default config
abiemann Jul 25, 2019
6f29fc3
latest upstream changes (#23)
abiemann Jul 25, 2019
36a811d
Merge branch 'master' into work_in_progress
abiemann Jul 25, 2019
1b799e1
Merge branch 'master' into master
abiemann Jul 25, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- FOR SPEECH COMMANDS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- note: largeHeap is needed due to animations -->
<application
android:name=".MainApplication"
android:allowBackup="true"
Expand All @@ -21,13 +22,14 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:largeHeap="true"
android:theme="@style/AppTheme">

<!-- android:windowSoftInputMode="adjustPan" prevents keyboard from hiding TextInputEditText's -->
<activity
android:name=".activities.main.MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan|stateAlwaysHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
Expand All @@ -46,7 +48,7 @@

<activity
android:name=".activities.settings.SettingsActivity"
android:theme="@style/AppTheme.NoActionBar"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan|stateAlwaysHidden" />

<!-- WIDGETS -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@

import android.app.Application;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatDelegate;

import com.microsoft.bot.builder.solutions.virtualassistant.service.SpeechService;

import static com.microsoft.bot.builder.solutions.virtualassistant.activities.BaseActivity.SHARED_PREFS_NAME;
import static com.microsoft.bot.builder.solutions.virtualassistant.activities.BaseActivity.SHARED_PREF_DARK_MODE;

public class MainApplication extends Application {

// STATE
Expand All @@ -20,6 +25,11 @@ public void onCreate() {
Intent intent = new Intent(this, SpeechService.class);
intent.setAction(SpeechService.ACTION_START_FOREGROUND_SERVICE);
ContextCompat.startForegroundService(this, intent);

// read the dark-mode setting (necessary because setDefaultNightMode() doesn't persist between app restarts)
SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
boolean darkModeEnabled = sharedPreferences.getBoolean(SHARED_PREF_DARK_MODE, false);
AppCompatDelegate.setDefaultNightMode(darkModeEnabled?AppCompatDelegate.MODE_NIGHT_YES:AppCompatDelegate.MODE_NIGHT_NO);
}

public static MainApplication getInstance(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ public abstract class BaseActivity extends AppCompatActivity {
public static final String LOGTAG = "BaseActivity";
private static final Integer PERMISSION_REQUEST_RECORD_AUDIO = 101;
private static final Integer PERMISSION_REQUEST_FINE_LOCATION = 102;
private static final String SHARED_PREFS_NAME = "my_shared_prefs";
public static final String SHARED_PREFS_NAME = "my_shared_prefs";
protected static final String SHARED_PREF_SHOW_TEXTINPUT = "SHARED_PREF_SHOW_TEXTINPUT";
protected static final String SHARED_PREF_SHOW_FULL_CONVERSATION = "SHARED_PREF_SHOW_FULL_CONVERSATION";
public static final String SHARED_PREF_DARK_MODE = "SHARED_PREF_DARK_MODE";

// State
private SharedPreferences sharedPreferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.app.assist.AssistContent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
Expand All @@ -18,6 +19,8 @@
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SwitchCompat;
Expand Down Expand Up @@ -61,11 +64,13 @@
import butterknife.OnEditorAction;
import client.model.BotConnectorActivity;
import client.model.CardAction;
import client.model.InputHints;
import events.ActivityReceived;
import events.Disconnected;
import events.Recognized;
import events.RecognizedIntermediateResult;
import events.RequestTimeout;
import events.SynthesizerStopped;

public class MainActivity extends BaseActivity
implements NavigationView.OnNavigationItemSelectedListener, ViewholderBot.OnClickListener, ActionsViewholder.OnClickListener {
Expand All @@ -80,8 +85,10 @@ public class MainActivity extends BaseActivity
@BindView(R.id.nav_view) NavigationView navigationView;
@BindView(R.id.switch_show_textinput) SwitchCompat switchShowTextInput;
@BindView(R.id.switch_show_full_conversation) SwitchCompat switchShowFullConversation;
@BindView(R.id.switch_night_mode) SwitchCompat switchNightMode;
@BindView(R.id.speech_detection) TextView detectedSpeechToText;
@BindView(R.id.agent_image) ImageView agentImage;
@BindView(R.id.mic_image) ImageView micImage;
@BindView(R.id.animated_assistant) AppCompatImageView animatedAssistant;

// CONSTANTS
private static final int CONTENT_VIEW = R.layout.activity_main;
Expand All @@ -97,6 +104,7 @@ public class MainActivity extends BaseActivity
private Gson gson;
private SfxManager sfxManager;
private ConfigurationManager configurationManager;
private boolean willListenAgain;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -116,6 +124,7 @@ protected void onCreate(Bundle savedInstanceState) {
switchShowTextInput.setChecked(alwaysShowTextInput);
showFullConversation = getBooleanSharedPref(SHARED_PREF_SHOW_FULL_CONVERSATION);
switchShowFullConversation.setChecked(showFullConversation);
switchNightMode.setChecked(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);

// NAV DRAWER
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( this, drawer, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
Expand Down Expand Up @@ -146,6 +155,9 @@ protected void onCreate(Bundle savedInstanceState) {

sfxManager = new SfxManager();
sfxManager.initialize(this);

// assign animation
animatedAssistant.setBackgroundResource(R.drawable.agent_listening_animation);
}

// Register for EventBus messages and SpeechService
Expand Down Expand Up @@ -208,7 +220,7 @@ protected void permissionDenied(String manifestPermission) {
try {
speechServiceBinder.initializeSpeechSdk(false);
speechServiceBinder.connectAsync();
agentImage.setVisibility(View.GONE);//hide the assistant since voice is deactivated
micImage.setVisibility(View.GONE);//hide the mic since voice is deactivated
textInputLayout.setVisibility(View.VISIBLE);// show the text-input prompt
} catch (RemoteException exception){
Log.e(LOGTAG, exception.getMessage());
Expand Down Expand Up @@ -280,11 +292,21 @@ public boolean onNavigationItemSelected(MenuItem item) {
return true;
}

@OnClick(R.id.agent_image)
public void onAssistantClick() {
private void showListeningAnimation(){
animatedAssistant.setVisibility(View.VISIBLE);
((AnimationDrawable) animatedAssistant.getBackground()).start();
sfxManager.playEarconListening();
}

private void hideListeningAnimation(){
animatedAssistant.setVisibility(View.GONE);
sfxManager.playEarconDoneListening();
}

@OnClick(R.id.mic_image)
public void onClickAssistant() {
try {
showSnackbar(uiContainer, getString(R.string.msg_listening));
sfxManager.playEarconListening();
showListeningAnimation();
speechServiceBinder.listenOnceAsync();
} catch (RemoteException exception){
Log.e(LOGTAG, exception.getMessage());
Expand All @@ -308,6 +330,13 @@ public void OnShowFullConversation(CompoundButton button, boolean checked){
chatAdapter.setShowFullConversation(showFullConversation);
}

@OnCheckedChanged(R.id.switch_night_mode)
public void OnEnableNightMode(CompoundButton button, boolean checked){
putBooleanSharedPref(SHARED_PREF_DARK_MODE, checked);
AppCompatDelegate.setDefaultNightMode(checked?AppCompatDelegate.MODE_NIGHT_YES:AppCompatDelegate.MODE_NIGHT_NO);
getDelegate().applyDayNight();
}

@OnEditorAction(R.id.textinput)
boolean onEditorAction(int actionId, KeyEvent key){
boolean handled = false;
Expand Down Expand Up @@ -364,6 +393,20 @@ public void onEventDisconnected(Disconnected event) {
}
}

// EventBus: the synthesizer has stopped playing
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventSynthesizerStopped(SynthesizerStopped event) {

// Note: the SpeechService will trigger the actual listening. Since the app needs to show a
// visual, the app also needs to subscribe to this event and act on it.
if(willListenAgain){
willListenAgain = false;
Log.i(LOGTAG, "Listening again");
showListeningAnimation();
}

}

// EventBus: the user spoke and the app recognized intermediate speech
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventRecognizedIntermediateResult(RecognizedIntermediateResult event) {
Expand All @@ -373,8 +416,9 @@ public void onEventRecognizedIntermediateResult(RecognizedIntermediateResult eve
// EventBus: the user spoke and the app recognized the speech. Disconnect mic.
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventRecognized(Recognized event) {
sfxManager.playEarconDoneListening();
hideListeningAnimation();
detectedSpeechToText.setText(event.recognized_speech);

// in 2 seconds clear the text (at this point the bot should be giving its' response)
handler.postDelayed(() -> detectedSpeechToText.setText(""), 2000);
}
Expand Down Expand Up @@ -414,6 +458,14 @@ public void onEventActivityReceived(ActivityReceived activityReceived) throws IO
default:
break;
}

// the service looks for the same expectingInput event. The app needs it to trigger visuals
if(botConnectorActivity.getInputHint() != null){
Log.i(LOGTAG, "InputHint: "+botConnectorActivity.getInputHint());
if(botConnectorActivity.getInputHint().equals(InputHints.EXPECTINGINPUT.toString())){
willListenAgain = true;
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ public void onEventSynthesizerStopped(SynthesizerStopped event) {

if(shouldListenAgain){
shouldListenAgain = false;
Log.i(TAG_FOREGROUND_SERVICE, "Listening again");
speechSdk.listenOnceAsync();
}

Expand Down Expand Up @@ -394,7 +395,8 @@ public void onEventActivityReceived(ActivityReceived activityReceived) throws IO

// make the bot automatically listen again
if(botConnectorActivity.getInputHint() != null){
if(botConnectorActivity.getInputHint().equals(InputHints.EXPECTINGINPUT)){
Log.i(TAG_FOREGROUND_SERVICE, "InputHint: "+botConnectorActivity.getInputHint());
if(botConnectorActivity.getInputHint().equals(InputHints.EXPECTINGINPUT.toString())){
shouldListenAgain = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">

<item android:duration="66" android:drawable="@drawable/agent_listening_loop_00"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_01"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_02"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_03"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_04"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_05"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_06"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_07"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_08"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_09"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_10"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_11"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_12"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_13"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_14"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_15"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_16"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_17"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_18"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_19"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_20"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_21"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_22"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_23"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_24"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_25"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_26"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_27"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_28"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_29"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_30"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_31"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_32"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_33"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_34"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_35"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_36"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_37"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_38"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_39"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_40"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_41"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_42"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_43"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_44"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_45"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_46"/>
<item android:duration="66" android:drawable="@drawable/agent_listening_loop_47"/>

</animation-list>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading