Skip to content

Commit 51b0fd7

Browse files
committed
Feature: New and improved User Interface
- New UI design for various screens. - Updated icons and images. - Improved user experience. - Time zone configuration support for nodes. - Fixed token authentication issue.
1 parent c54274c commit 51b0fd7

File tree

225 files changed

+6256
-3439
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

225 files changed

+6256
-3439
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ For more details :
99
## Setup
1010

1111
To build this app, you will need a development machine, with Android Studio installed.
12-
Download the source code and open this project in Android Studio.
12+
13+
To get this app please clone this repository using the below command and open this project in Android Studio:
14+
```
15+
git clone https://github.com/espressif/esp-rainmaker-android.git
16+
```
1317
You are now ready to run this demo.
1418

1519
## Features

app/build.gradle

+17-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def defaultTransport = "Both"
1515
def defaultSecurity = "Sec1"
1616
def defaultPoP = ""
1717
def defaultPrefix = "PROV_"
18+
def defaultWiFiScanSrc = "Device"
1819

1920
def defaultAwsRegion = "us-east-1"
2021
def defaultUserPoolId = "us-east-1_kWz4M6MfD"
@@ -43,7 +44,7 @@ android {
4344
applicationId "com.espressif.rainmaker"
4445
minSdkVersion 23
4546
targetSdkVersion 30
46-
versionCode 16
47+
versionCode 28
4748
versionName "2.3.0 - ${getGitHash()}"
4849
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
4950

@@ -70,6 +71,15 @@ android {
7071
buildConfigField "String", "SECURITY", '"' + security + '"'
7172
}
7273

74+
def wifiScanSrc = localProperties.getProperty("wifiScanSource", defaultWiFiScanSrc)
75+
if (wifiScanSrc == null) {
76+
throw new GradleException("WiFi scan source not found. Define it in the local.properties file.")
77+
} else if (!wifiScanSrc.equalsIgnoreCase("Device") && !wifiScanSrc.equalsIgnoreCase("Phone")) {
78+
throw new GradleException("Invalid 'wifiScanSource' value. Please check 'wifiScanSource' value in local.properties file.")
79+
} else {
80+
buildConfigField "String", "WIFI_SCAN_SRC", '"' + wifiScanSrc + '"'
81+
}
82+
7383
buildConfigField "boolean", "isFilterPrefixEditable", localProperties.getProperty("isFilterPrefixEditable", "true")
7484
buildConfigField "String", "DEVICE_NAME_PREFIX", '"' + localProperties.getProperty("deviceNamePrefix", defaultPrefix) + '"'
7585

@@ -151,6 +161,7 @@ dependencies {
151161
implementation 'com.google.android.material:material:1.1.0'
152162
implementation 'androidx.recyclerview:recyclerview:1.1.0'
153163
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
164+
implementation 'com.larswerkman:HoloColorPicker:1.5'
154165

155166
implementation 'com.google.protobuf:protobuf-lite:3.0.1'
156167
implementation 'com.google.crypto.tink:tink-android:1.1.0'
@@ -166,16 +177,17 @@ dependencies {
166177

167178
implementation 'com.aventrix.jnanoid:jnanoid:2.0.0'
168179
implementation 'com.budiyev.android:code-scanner:2.1.0'
169-
implementation 'com.github.espressif:esp-idf-provisioning-android:lib-2.0.8'
180+
implementation 'com.github.espressif:esp-idf-provisioning-android:lib-2.0.9'
170181

171-
implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.22.5'
182+
implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.19.0'
172183
implementation 'com.github.warkiz.tickseekbar:tickseekbar:0.1.4'
173184
implementation('com.amazonaws:aws-android-sdk-iot:2.15.2') { transitive = true }
174185
implementation('com.amazonaws:aws-android-sdk-mobile-client:2.15.2') { transitive = true }
175186

176187
// Room dependencies
177-
implementation 'android.arch.persistence.room:runtime:2.2.6'
178-
annotationProcessor 'android.arch.persistence.room:compiler:2.2.6'
188+
def room_version = "2.3.0"
189+
implementation "android.arch.persistence.room:runtime:$room_version"
190+
annotationProcessor "android.arch.persistence.room:compiler:$room_version"
179191

180192
testImplementation 'junit:junit:4.13.2'
181193
androidTestImplementation 'androidx.test:runner:1.3.0'

app/src/main/AndroidManifest.xml

+8-11
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@
3838

3939
<activity
4040
android:name="com.espressif.ui.activities.SplashActivity"
41-
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
42-
android:label="@string/app_name"
4341
android:screenOrientation="portrait"
44-
android:theme="@style/AppTheme.NoActionBar"
45-
android:windowSoftInputMode="adjustPan">
42+
android:theme="@android:style/Theme.NoDisplay">
4643

4744
<intent-filter>
4845
<action android:name="android.intent.action.MAIN" />
@@ -111,11 +108,6 @@
111108
android:label="@string/app_name"
112109
android:screenOrientation="portrait"
113110
android:theme="@style/AppTheme.NoActionBar" />
114-
<activity
115-
android:name="com.espressif.ui.activities.UserProfileActivity"
116-
android:label="@string/title_activity_settings"
117-
android:screenOrientation="portrait"
118-
android:theme="@style/AppTheme.NoActionBar" />
119111
<activity
120112
android:name="com.espressif.ui.activities.EspDeviceActivity"
121113
android:label="@string/title_activity_esp_device"
@@ -154,12 +146,12 @@
154146
android:theme="@style/AppTheme.NoActionBar" />
155147
<activity
156148
android:name="com.espressif.ui.activities.AddScheduleActivity"
157-
android:label="@string/title_activity_add_device"
149+
android:label="@string/title_activity_add_schedule"
158150
android:screenOrientation="portrait"
159151
android:theme="@style/AppTheme.NoActionBar" />
160152
<activity
161153
android:name="com.espressif.ui.activities.ScheduleActionsActivity"
162-
android:label="@string/title_activity_add_device"
154+
android:label="@string/title_activity_actions"
163155
android:screenOrientation="portrait"
164156
android:theme="@style/AppTheme.NoActionBar" />
165157
<activity
@@ -182,6 +174,11 @@
182174
android:label="@string/title_activity_sharing_requests"
183175
android:screenOrientation="portrait"
184176
android:theme="@style/AppTheme.NoActionBar" />
177+
<activity
178+
android:name="com.espressif.ui.activities.VoiceServicesActivity"
179+
android:label="@string/title_activity_voice_services"
180+
android:screenOrientation="portrait"
181+
android:theme="@style/AppTheme.NoActionBar" />
185182

186183
</application>
187184

app/src/main/java/com/espressif/AppConstants.java

+10-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class AppConstants {
3030
public static final String HANDLER_RM_CLAIM = "rmaker_claim";
3131

3232
public static final String ESP_PREFERENCES = "Esp_Preferences";
33+
public static final String PREF_FILE_WIFI_NETWORKS = "wifi_networks";
3334
public static final String ESP_DATABASE_NAME = "esp_db";
3435
public static final String NODE_TABLE = "node_table";
3536
public static final String GROUP_TABLE = "group_table";
@@ -41,7 +42,8 @@ public enum UpdateEventType {
4142
EVENT_DEVICE_ADDED,
4243
EVENT_DEVICE_REMOVED,
4344
EVENT_ADD_DEVICE_TIME_OUT,
44-
EVENT_DEVICE_STATUS_UPDATE
45+
EVENT_DEVICE_STATUS_UPDATE,
46+
EVENT_STATE_CHANGE_UPDATE
4547
}
4648

4749
public static final String CURRENT_VERSION = "v1";
@@ -73,8 +75,10 @@ public enum UpdateEventType {
7375

7476
// UI Types of Device
7577
public static final String UI_TYPE_TOGGLE = "esp.ui.toggle";
78+
public static final String UI_TYPE_PUSH_BTN_BIG = "esp.ui.push-btn-big";
7679
public static final String UI_TYPE_SLIDER = "esp.ui.slider";
7780
public static final String UI_TYPE_HUE_SLIDER = "esp.ui.hue-slider";
81+
public static final String UI_TYPE_HUE_CIRCLE = "esp.ui.hue-circle";
7882
public static final String UI_TYPE_DROP_DOWN = "esp.ui.dropdown";
7983

8084
// ESP Device Types
@@ -102,6 +106,7 @@ public enum UpdateEventType {
102106
public static final String PARAM_TYPE_BRIGHTNESS = "esp.param.brightness";
103107
public static final String PARAM_TYPE_TEMPERATURE = "esp.param.temperature";
104108
public static final String PARAM_TYPE_TZ = "esp.param.tz";
109+
public static final String PARAM_TYPE_TZ_POSIX = "esp.param.tz_posix";
105110

106111
// Keys used to pass data between activities and to store data in SharedPreference.
107112
public static final String KEY_DEVICE_NAME_PREFIX = "device_prefix";
@@ -118,6 +123,7 @@ public enum UpdateEventType {
118123
public static final String KEY_SSID = "ssid";
119124
public static final String KEY_PASSWORD = "password";
120125
public static final String KEY_SECURITY_TYPE = "security_type";
126+
public static final String KEY_SHOULD_SAVE_PWD = "save_password";
121127

122128
// Keys used in JSON responses and used to pass data between activities.
123129
public static final String KEY_NAME = "name";
@@ -216,4 +222,7 @@ public enum UpdateEventType {
216222
public static final String CAPABILITY_WIFI_SACN = "wifi_scan";
217223
public static final String CAPABILITY_NO_POP = "no_pop";
218224
public static final String CAPABILITY_CLAIM = "claim";
225+
226+
public static final String WIFI_SCAN_FROM_DEVICE = "Device";
227+
public static final String WIFI_SCAN_FROM_PHONE = "Phone";
219228
}

app/src/main/java/com/espressif/EspApplication.java

+131-9
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,49 @@
1515
package com.espressif;
1616

1717
import android.app.Application;
18+
import android.content.Context;
19+
import android.content.SharedPreferences;
20+
import android.os.Bundle;
1821
import android.util.Log;
1922

23+
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser;
2024
import com.espressif.cloudapi.ApiManager;
25+
import com.espressif.cloudapi.ApiResponseListener;
26+
import com.espressif.db.EspDatabase;
2127
import com.espressif.mdns.mDNSDevice;
2228
import com.espressif.provisioning.ESPProvisionManager;
29+
import com.espressif.rainmaker.BuildConfig;
2330
import com.espressif.ui.models.EspNode;
2431
import com.espressif.ui.models.Group;
2532
import com.espressif.ui.models.Schedule;
33+
import com.espressif.ui.models.UpdateEvent;
2634
import com.espressif.ui.user_module.AppHelper;
2735

36+
import org.greenrobot.eventbus.EventBus;
37+
2838
import java.util.HashMap;
2939

3040
public class EspApplication extends Application {
3141

3242
private static final String TAG = EspApplication.class.getSimpleName();
3343

34-
private GetDataStatus currentStatus = GetDataStatus.FETCHING_DATA;
44+
private AppState appState = AppState.NO_USER_LOGIN;
3545

3646
public HashMap<String, EspNode> nodeMap;
3747
public HashMap<String, Schedule> scheduleMap;
3848
public HashMap<String, mDNSDevice> mDNSDeviceMap;
3949
public HashMap<String, Group> groupMap;
4050

41-
public enum GetDataStatus {
42-
FETCHING_DATA,
51+
private SharedPreferences appPreferences;
52+
private ApiManager apiManager;
53+
54+
public enum AppState {
55+
NO_USER_LOGIN,
56+
GETTING_DATA,
4357
GET_DATA_SUCCESS,
4458
GET_DATA_FAILED,
45-
DATA_REFRESHING
59+
NO_INTERNET,
60+
REFRESH_DATA
4661
}
4762

4863
@Override
@@ -53,16 +68,123 @@ public void onCreate() {
5368
scheduleMap = new HashMap<>();
5469
mDNSDeviceMap = new HashMap<>();
5570
groupMap = new HashMap<>();
71+
appPreferences = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE);
5672
AppHelper.init(this);
57-
ApiManager.getInstance(this);
73+
apiManager = ApiManager.getInstance(this);
5874
ESPProvisionManager.getInstance(this);
5975
}
6076

61-
public GetDataStatus getCurrentStatus() {
62-
return currentStatus;
77+
public AppState getAppState() {
78+
return appState;
79+
}
80+
81+
public void changeAppState(AppState newState, Bundle extras) {
82+
83+
switch (newState) {
84+
case GETTING_DATA:
85+
case REFRESH_DATA:
86+
if (!appState.equals(newState)) {
87+
appState = newState;
88+
getNodesFromCloud();
89+
}
90+
EventBus.getDefault().post(new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE));
91+
break;
92+
93+
case GET_DATA_FAILED:
94+
appState = newState;
95+
UpdateEvent updateEvent = new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE);
96+
if (extras != null) {
97+
updateEvent.setData(extras);
98+
}
99+
EventBus.getDefault().post(updateEvent);
100+
break;
101+
102+
case NO_USER_LOGIN:
103+
case GET_DATA_SUCCESS:
104+
case NO_INTERNET:
105+
appState = newState;
106+
EventBus.getDefault().post(new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE));
107+
break;
108+
}
63109
}
64110

65-
public void setCurrentStatus(GetDataStatus currentStatus) {
66-
this.currentStatus = currentStatus;
111+
private void getNodesFromCloud() {
112+
113+
apiManager.getNodes(new ApiResponseListener() {
114+
115+
@Override
116+
public void onSuccess(Bundle data) {
117+
118+
if (BuildConfig.isNodeGroupingSupported) {
119+
120+
apiManager.getUserGroups(null, new ApiResponseListener() {
121+
122+
@Override
123+
public void onSuccess(Bundle data) {
124+
changeAppState(AppState.GET_DATA_SUCCESS, null);
125+
}
126+
127+
@Override
128+
public void onResponseFailure(Exception exception) {
129+
Bundle data = new Bundle();
130+
data.putString(AppConstants.KEY_ERROR_MSG, exception.getMessage());
131+
changeAppState(EspApplication.AppState.GET_DATA_FAILED, data);
132+
}
133+
134+
@Override
135+
public void onNetworkFailure(Exception exception) {
136+
changeAppState(AppState.NO_INTERNET, null);
137+
}
138+
});
139+
} else {
140+
changeAppState(AppState.GET_DATA_SUCCESS, null);
141+
}
142+
}
143+
144+
@Override
145+
public void onResponseFailure(Exception exception) {
146+
Bundle data = new Bundle();
147+
data.putString(AppConstants.KEY_ERROR_MSG, exception.getMessage());
148+
changeAppState(EspApplication.AppState.GET_DATA_FAILED, data);
149+
}
150+
151+
@Override
152+
public void onNetworkFailure(Exception exception) {
153+
changeAppState(AppState.NO_INTERNET, null);
154+
}
155+
});
156+
}
157+
158+
public void refreshData() {
159+
if (!appState.equals(AppState.GETTING_DATA)) {
160+
changeAppState(AppState.REFRESH_DATA, null);
161+
}
162+
}
163+
164+
public void logout() {
165+
// Do logout and clear all data
166+
if (!ApiManager.isOAuthLogin) {
167+
String username = AppHelper.getCurrUser();
168+
CognitoUser user = AppHelper.getPool().getUser(username);
169+
user.signOut();
170+
}
171+
172+
EspDatabase.getInstance(this).getNodeDao().deleteAll();
173+
EspDatabase.getInstance(this).getGroupDao().deleteAll();
174+
nodeMap.clear();
175+
scheduleMap.clear();
176+
mDNSDeviceMap.clear();
177+
groupMap.clear();
178+
179+
SharedPreferences.Editor editor = appPreferences.edit();
180+
editor.clear();
181+
editor.apply();
182+
183+
SharedPreferences wifiNetworkPref = getSharedPreferences(AppConstants.PREF_FILE_WIFI_NETWORKS, Context.MODE_PRIVATE);
184+
SharedPreferences.Editor wifiNetworkEditor = wifiNetworkPref.edit();
185+
wifiNetworkEditor.clear();
186+
wifiNetworkEditor.apply();
187+
Log.e(TAG, "Deleted all things from local storage.");
188+
changeAppState(AppState.NO_USER_LOGIN, null);
67189
}
68190
}

0 commit comments

Comments
 (0)