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

Commit

Permalink
[Android] UI refactoring and bug fix (#2383)
Browse files Browse the repository at this point in the history
* [Android] #2232 refactored navigation drawer and settings view

* [Android] fixed #2235 default assistant app

* [Android] #2238 keep screen on config

* [Android] fixed #2235 start listening without showing app UI

* [Android] fixed null pointer exception in speech service

* [Android] #2233 default configuration provided by a configuration file
  • Loading branch information
chon219 authored and ryanisgrig committed Sep 25, 2019
1 parent 2ccc211 commit efeacf3
Show file tree
Hide file tree
Showing 38 changed files with 925 additions and 533 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- for ContextCompat.startForegroundService -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<!-- DANGEROUS -->
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- FOR SPEECH COMMANDS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Expand Down Expand Up @@ -38,7 +39,8 @@
</activity>

<activity
android:name=".assistant.VoiceInteractionActivity">
android:name=".assistant.VoiceInteractionActivity"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"history_linecount": 2147483646,
"show_full_conversation": true,
"enable_dark_mode": false,
"keep_screen_on": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@

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 @@ -25,11 +20,6 @@ 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 @@ -26,6 +26,7 @@
import com.microsoft.bot.builder.solutions.directlinespeech.model.Configuration;
import com.microsoft.bot.builder.solutions.virtualassistant.ISpeechService;
import com.microsoft.bot.builder.solutions.virtualassistant.R;
import com.microsoft.bot.builder.solutions.virtualassistant.utils.AppConfigurationManager;

/**
* This base class provides functionality that is reusable in Activities of this app
Expand All @@ -37,14 +38,13 @@ public abstract class BaseActivity extends AppCompatActivity {
private static final Integer PERMISSION_REQUEST_RECORD_AUDIO = 101;
private static final Integer PERMISSION_REQUEST_FINE_LOCATION = 102;
public static final String SHARED_PREFS_NAME = "my_shared_prefs";
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";
protected static final String SHARED_PREF_ENABLE_KWS = "SHARED_PREF_ENABLE_KWS";

// STATE
private SharedPreferences sharedPreferences;
protected ISpeechService speechServiceBinder;
protected ConfigurationManager configurationManager;
protected AppConfigurationManager appConfigurationManager;

// OVERRIDE THESE
protected void permissionDenied(String manifestPermission){}
Expand All @@ -57,6 +57,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
sharedPreferences = getSharedPreferences(SHARED_PREFS_NAME, MODE_PRIVATE);
setupMainWindowDisplayMode();
configurationManager = new ConfigurationManager(this);
appConfigurationManager = new AppConfigurationManager(this);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
Expand All @@ -28,6 +29,7 @@
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.CompoundButton;
import android.widget.ImageView;
Expand All @@ -36,7 +38,6 @@

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.microsoft.bot.builder.solutions.directlinespeech.model.Configuration;
import com.microsoft.bot.builder.solutions.virtualassistant.R;
import com.microsoft.bot.builder.solutions.virtualassistant.activities.BaseActivity;
import com.microsoft.bot.builder.solutions.virtualassistant.activities.main.actionslist.ActionsAdapter;
Expand All @@ -45,7 +46,7 @@
import com.microsoft.bot.builder.solutions.virtualassistant.activities.main.chatlist.ChatAdapter;
import com.microsoft.bot.builder.solutions.virtualassistant.activities.main.chatlist.ItemOffsetDecoration;
import com.microsoft.bot.builder.solutions.virtualassistant.activities.settings.SettingsActivity;
import com.microsoft.bot.builder.solutions.virtualassistant.assistant.VoiceInteractionActivity;
import com.microsoft.bot.builder.solutions.virtualassistant.utils.AppConfiguration;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
Expand Down Expand Up @@ -87,26 +88,27 @@ public class MainActivity extends BaseActivity
@BindView(R.id.textinput) TextInputEditText textInput;
@BindView(R.id.drawer_layout) DrawerLayout drawer;
@BindView(R.id.nav_view) NavigationView navigationView;
@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.mic_image) ImageView micImage;
@BindView(R.id.kbd_image) ImageView kbdImage;
@BindView(R.id.animated_assistant) AppCompatImageView animatedAssistant;
@BindView(R.id.switch_enable_kws) SwitchCompat switchEnableKws;
@BindView(R.id.nav_menu_set_as_default_assistant) TextView setDefaultAssistant;

// CONSTANTS
private static final int CONTENT_VIEW = R.layout.activity_main;
private static final String LOGTAG = "MainActivity";
private static final int REQUEST_CODE_SETTINGS = 256;
private static final int REQUEST_CODE_OVERLAY_PERMISSION = 255;

// STATE
private ChatAdapter chatAdapter;
private ActionsAdapter suggActionsAdapter;
private boolean showFullConversation;
private Handler handler;
private boolean launchedAsAssistant;
private Gson gson;
private SfxManager sfxManager;
private boolean enableDarkMode;
private boolean keepScreenOn;
private boolean enableKws;
private boolean isExpandedTextInput;
private boolean isCreated;// used to identify when onCreate() is complete, used with SwitchCompat
Expand All @@ -124,9 +126,6 @@ protected void onCreate(Bundle savedInstanceState) {
setupSuggestedActionsRecyclerView();

// Options hidden in the nav-drawer
showFullConversation = getBooleanSharedPref(SHARED_PREF_SHOW_FULL_CONVERSATION);
switchShowFullConversation.setChecked(showFullConversation);
switchNightMode.setChecked(AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES);
enableKws = getBooleanSharedPref(SHARED_PREF_ENABLE_KWS);
switchEnableKws.setChecked(enableKws);

Expand All @@ -148,21 +147,15 @@ protected void onCreate(Bundle savedInstanceState) {
// make media volume the default
setVolumeControlStream(AudioManager.STREAM_MUSIC);

// check if this activity was launched as an assistant
Intent intent = getIntent();
if (intent != null) {
String originator = intent.getStringExtra(VoiceInteractionActivity.KEY_ORIGINATOR);
if (originator != null && originator.equals(VoiceInteractionActivity.KEY_VALUE)) {
launchedAsAssistant = true;//this flag can now be used, i.e. to automatically start microphone recording
}
}

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

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

// load configurations from shared preferences
loadAppConfiguration();

isCreated = true;//keep this as last line in onCreate()
}

Expand All @@ -179,11 +172,15 @@ public void onStart() {
@Override
protected void onResume() {
super.onResume();
final Configuration configuration = configurationManager.getConfiguration();
chatAdapter.setChatItemHistoryCount(configuration.historyLinecount==null?1:configuration.historyLinecount);
chatAdapter.setChatBubbleColors(configuration.colorBubbleBot, configuration.colorBubbleUser);
chatAdapter.setChatTextColors(configuration.colorTextBot, configuration.colorTextUser);
chatAdapter.setShowFullConversation(showFullConversation);
if (keepScreenOn) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // to keep screen on
}
}

@Override
protected void onPause() {
super.onPause();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // to disable keeping screen on
}

// Unregister EventBus messages and SpeechService
Expand Down Expand Up @@ -280,18 +277,15 @@ public boolean onNavigationItemSelected(MenuItem item) {
try {

switch (id) {
case R.id.nav_menu_configuration:
startActivity(SettingsActivity.getNewIntent(this));
case R.id.nav_menu_settings:
startActivityForResult(SettingsActivity.getNewIntent(this), REQUEST_CODE_SETTINGS);
break;
case R.id.nav_menu_reset_bot:
case R.id.nav_menu_restart_conversation:
speechServiceBinder.resetBot();
chatAdapter.resetChat();
suggActionsAdapter.clear();
speechServiceBinder.clearSuggestedActions();
break;
case R.id.nav_menu_show_assistant_settings:
startActivity(new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS));
break;
}

} catch (RemoteException exception){
Expand All @@ -303,6 +297,27 @@ public boolean onNavigationItemSelected(MenuItem item) {
return true;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_SETTINGS && resultCode == RESULT_OK) {
loadAppConfiguration();
} else if (requestCode == REQUEST_CODE_OVERLAY_PERMISSION) {
if (Settings.canDrawOverlays(this)) {
startActivity(new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS));
}
}
}

private void loadAppConfiguration() {
AppConfiguration appConfiguration = appConfigurationManager.getConfiguration();
setDarkMode(appConfiguration.enableDarkMode);
keepScreenOn = appConfiguration.keepScreenOn;
chatAdapter.setShowFullConversation(appConfiguration.showFullConversation);
chatAdapter.setChatItemHistoryCount(appConfiguration.historyLinecount);
chatAdapter.setChatBubbleColors(appConfiguration.colorBubbleBot, appConfiguration.colorBubbleUser);
chatAdapter.setChatTextColors(appConfiguration.colorTextBot, appConfiguration.colorTextUser);
}

private void showListeningAnimation(){
Log.i(LOGTAG, "Listening again - showListeningAnimation()");
animatedAssistant.setVisibility(View.VISIBLE);
Expand Down Expand Up @@ -336,6 +351,17 @@ public void onClickAssistant() {
}
}

@OnClick(R.id.nav_menu_set_as_default_assistant)
public void onClickSetDefaultAssistant() {
if (Settings.canDrawOverlays(this)) {
startActivity(new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS));
} else {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_OVERLAY_PERMISSION);
}
}

@OnCheckedChanged(R.id.switch_enable_kws)
public void onCheckedChangedEnableKws(CompoundButton button, boolean checked){
if (isCreated) {
Expand All @@ -355,27 +381,18 @@ public void onCheckedChangedEnableKws(CompoundButton button, boolean checked){
}
}

@OnCheckedChanged(R.id.switch_show_full_conversation)
public void OnCheckedChangedShowFullConversation(CompoundButton button, boolean checked){
if (isCreated) {
showFullConversation = checked;
putBooleanSharedPref(SHARED_PREF_SHOW_FULL_CONVERSATION, checked);
chatAdapter.setShowFullConversation(showFullConversation);
}
}
public void setDarkMode(boolean enabled){
if (enableDarkMode != enabled) {
enableDarkMode = enabled;

@OnCheckedChanged(R.id.switch_night_mode)
public void OnCheckedChangedEnableNightMode(CompoundButton button, boolean checked){
if (isCreated) {
// OutOfMemoryError can occur, try to free as many objects as possible 1st
// note: the assistant animation might need to be unloaded prior to switching night mode
sfxManager.reset();
sfxManager = null;
System.gc();

// now proceed with the night mode switch
putBooleanSharedPref(SHARED_PREF_DARK_MODE, checked);
AppCompatDelegate.setDefaultNightMode(checked ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
AppCompatDelegate.setDefaultNightMode(enabled ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
getDelegate().applyDayNight();

// re-init SFX manager
Expand Down
Loading

0 comments on commit efeacf3

Please sign in to comment.