diff --git a/README.md b/README.md index 108d039..8b95983 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,11 @@ For more details : ## Setup To build this app, you will need a development machine, with Android Studio installed. -Download the source code and open this project in Android Studio. + +To get this app please clone this repository using the below command and open this project in Android Studio: +``` + git clone https://github.com/espressif/esp-rainmaker-android.git +``` You are now ready to run this demo. ## Features diff --git a/app/build.gradle b/app/build.gradle index 968e7c6..6955d0d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,6 +15,7 @@ def defaultTransport = "Both" def defaultSecurity = "Sec1" def defaultPoP = "" def defaultPrefix = "PROV_" +def defaultWiFiScanSrc = "Device" def defaultAwsRegion = "us-east-1" def defaultUserPoolId = "us-east-1_kWz4M6MfD" @@ -43,7 +44,7 @@ android { applicationId "com.espressif.rainmaker" minSdkVersion 23 targetSdkVersion 30 - versionCode 16 + versionCode 28 versionName "2.3.0 - ${getGitHash()}" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -70,6 +71,15 @@ android { buildConfigField "String", "SECURITY", '"' + security + '"' } + def wifiScanSrc = localProperties.getProperty("wifiScanSource", defaultWiFiScanSrc) + if (wifiScanSrc == null) { + throw new GradleException("WiFi scan source not found. Define it in the local.properties file.") + } else if (!wifiScanSrc.equalsIgnoreCase("Device") && !wifiScanSrc.equalsIgnoreCase("Phone")) { + throw new GradleException("Invalid 'wifiScanSource' value. Please check 'wifiScanSource' value in local.properties file.") + } else { + buildConfigField "String", "WIFI_SCAN_SRC", '"' + wifiScanSrc + '"' + } + buildConfigField "boolean", "isFilterPrefixEditable", localProperties.getProperty("isFilterPrefixEditable", "true") buildConfigField "String", "DEVICE_NAME_PREFIX", '"' + localProperties.getProperty("deviceNamePrefix", defaultPrefix) + '"' @@ -151,6 +161,7 @@ dependencies { implementation 'com.google.android.material:material:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' + implementation 'com.larswerkman:HoloColorPicker:1.5' implementation 'com.google.protobuf:protobuf-lite:3.0.1' implementation 'com.google.crypto.tink:tink-android:1.1.0' @@ -166,16 +177,17 @@ dependencies { implementation 'com.aventrix.jnanoid:jnanoid:2.0.0' implementation 'com.budiyev.android:code-scanner:2.1.0' - implementation 'com.github.espressif:esp-idf-provisioning-android:lib-2.0.8' + implementation 'com.github.espressif:esp-idf-provisioning-android:lib-2.0.9' - implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.22.5' + implementation 'com.amazonaws:aws-android-sdk-cognitoidentityprovider:2.19.0' implementation 'com.github.warkiz.tickseekbar:tickseekbar:0.1.4' implementation('com.amazonaws:aws-android-sdk-iot:2.15.2') { transitive = true } implementation('com.amazonaws:aws-android-sdk-mobile-client:2.15.2') { transitive = true } // Room dependencies - implementation 'android.arch.persistence.room:runtime:2.2.6' - annotationProcessor 'android.arch.persistence.room:compiler:2.2.6' + def room_version = "2.3.0" + implementation "android.arch.persistence.room:runtime:$room_version" + annotationProcessor "android.arch.persistence.room:compiler:$room_version" testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test:runner:1.3.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8eef057..4bc92e2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -38,11 +38,8 @@ + android:theme="@android:style/Theme.NoDisplay"> @@ -111,11 +108,6 @@ android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/AppTheme.NoActionBar" /> - + diff --git a/app/src/main/java/com/espressif/AppConstants.java b/app/src/main/java/com/espressif/AppConstants.java index 87a69a9..83b084b 100644 --- a/app/src/main/java/com/espressif/AppConstants.java +++ b/app/src/main/java/com/espressif/AppConstants.java @@ -30,6 +30,7 @@ public class AppConstants { public static final String HANDLER_RM_CLAIM = "rmaker_claim"; public static final String ESP_PREFERENCES = "Esp_Preferences"; + public static final String PREF_FILE_WIFI_NETWORKS = "wifi_networks"; public static final String ESP_DATABASE_NAME = "esp_db"; public static final String NODE_TABLE = "node_table"; public static final String GROUP_TABLE = "group_table"; @@ -41,7 +42,8 @@ public enum UpdateEventType { EVENT_DEVICE_ADDED, EVENT_DEVICE_REMOVED, EVENT_ADD_DEVICE_TIME_OUT, - EVENT_DEVICE_STATUS_UPDATE + EVENT_DEVICE_STATUS_UPDATE, + EVENT_STATE_CHANGE_UPDATE } public static final String CURRENT_VERSION = "v1"; @@ -73,8 +75,10 @@ public enum UpdateEventType { // UI Types of Device public static final String UI_TYPE_TOGGLE = "esp.ui.toggle"; + public static final String UI_TYPE_PUSH_BTN_BIG = "esp.ui.push-btn-big"; public static final String UI_TYPE_SLIDER = "esp.ui.slider"; public static final String UI_TYPE_HUE_SLIDER = "esp.ui.hue-slider"; + public static final String UI_TYPE_HUE_CIRCLE = "esp.ui.hue-circle"; public static final String UI_TYPE_DROP_DOWN = "esp.ui.dropdown"; // ESP Device Types @@ -102,6 +106,7 @@ public enum UpdateEventType { public static final String PARAM_TYPE_BRIGHTNESS = "esp.param.brightness"; public static final String PARAM_TYPE_TEMPERATURE = "esp.param.temperature"; public static final String PARAM_TYPE_TZ = "esp.param.tz"; + public static final String PARAM_TYPE_TZ_POSIX = "esp.param.tz_posix"; // Keys used to pass data between activities and to store data in SharedPreference. public static final String KEY_DEVICE_NAME_PREFIX = "device_prefix"; @@ -118,6 +123,7 @@ public enum UpdateEventType { public static final String KEY_SSID = "ssid"; public static final String KEY_PASSWORD = "password"; public static final String KEY_SECURITY_TYPE = "security_type"; + public static final String KEY_SHOULD_SAVE_PWD = "save_password"; // Keys used in JSON responses and used to pass data between activities. public static final String KEY_NAME = "name"; @@ -216,4 +222,7 @@ public enum UpdateEventType { public static final String CAPABILITY_WIFI_SACN = "wifi_scan"; public static final String CAPABILITY_NO_POP = "no_pop"; public static final String CAPABILITY_CLAIM = "claim"; + + public static final String WIFI_SCAN_FROM_DEVICE = "Device"; + public static final String WIFI_SCAN_FROM_PHONE = "Phone"; } diff --git a/app/src/main/java/com/espressif/EspApplication.java b/app/src/main/java/com/espressif/EspApplication.java index a4eb34d..9d3cfca 100644 --- a/app/src/main/java/com/espressif/EspApplication.java +++ b/app/src/main/java/com/espressif/EspApplication.java @@ -15,34 +15,49 @@ package com.espressif; import android.app.Application; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; import android.util.Log; +import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser; import com.espressif.cloudapi.ApiManager; +import com.espressif.cloudapi.ApiResponseListener; +import com.espressif.db.EspDatabase; import com.espressif.mdns.mDNSDevice; import com.espressif.provisioning.ESPProvisionManager; +import com.espressif.rainmaker.BuildConfig; import com.espressif.ui.models.EspNode; import com.espressif.ui.models.Group; import com.espressif.ui.models.Schedule; +import com.espressif.ui.models.UpdateEvent; import com.espressif.ui.user_module.AppHelper; +import org.greenrobot.eventbus.EventBus; + import java.util.HashMap; public class EspApplication extends Application { private static final String TAG = EspApplication.class.getSimpleName(); - private GetDataStatus currentStatus = GetDataStatus.FETCHING_DATA; + private AppState appState = AppState.NO_USER_LOGIN; public HashMap nodeMap; public HashMap scheduleMap; public HashMap mDNSDeviceMap; public HashMap groupMap; - public enum GetDataStatus { - FETCHING_DATA, + private SharedPreferences appPreferences; + private ApiManager apiManager; + + public enum AppState { + NO_USER_LOGIN, + GETTING_DATA, GET_DATA_SUCCESS, GET_DATA_FAILED, - DATA_REFRESHING + NO_INTERNET, + REFRESH_DATA } @Override @@ -53,16 +68,123 @@ public void onCreate() { scheduleMap = new HashMap<>(); mDNSDeviceMap = new HashMap<>(); groupMap = new HashMap<>(); + appPreferences = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE); AppHelper.init(this); - ApiManager.getInstance(this); + apiManager = ApiManager.getInstance(this); ESPProvisionManager.getInstance(this); } - public GetDataStatus getCurrentStatus() { - return currentStatus; + public AppState getAppState() { + return appState; + } + + public void changeAppState(AppState newState, Bundle extras) { + + switch (newState) { + case GETTING_DATA: + case REFRESH_DATA: + if (!appState.equals(newState)) { + appState = newState; + getNodesFromCloud(); + } + EventBus.getDefault().post(new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE)); + break; + + case GET_DATA_FAILED: + appState = newState; + UpdateEvent updateEvent = new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE); + if (extras != null) { + updateEvent.setData(extras); + } + EventBus.getDefault().post(updateEvent); + break; + + case NO_USER_LOGIN: + case GET_DATA_SUCCESS: + case NO_INTERNET: + appState = newState; + EventBus.getDefault().post(new UpdateEvent(AppConstants.UpdateEventType.EVENT_STATE_CHANGE_UPDATE)); + break; + } } - public void setCurrentStatus(GetDataStatus currentStatus) { - this.currentStatus = currentStatus; + private void getNodesFromCloud() { + + apiManager.getNodes(new ApiResponseListener() { + + @Override + public void onSuccess(Bundle data) { + + if (BuildConfig.isNodeGroupingSupported) { + + apiManager.getUserGroups(null, new ApiResponseListener() { + + @Override + public void onSuccess(Bundle data) { + changeAppState(AppState.GET_DATA_SUCCESS, null); + } + + @Override + public void onResponseFailure(Exception exception) { + Bundle data = new Bundle(); + data.putString(AppConstants.KEY_ERROR_MSG, exception.getMessage()); + changeAppState(EspApplication.AppState.GET_DATA_FAILED, data); + } + + @Override + public void onNetworkFailure(Exception exception) { + changeAppState(AppState.NO_INTERNET, null); + } + }); + } else { + changeAppState(AppState.GET_DATA_SUCCESS, null); + } + } + + @Override + public void onResponseFailure(Exception exception) { + Bundle data = new Bundle(); + data.putString(AppConstants.KEY_ERROR_MSG, exception.getMessage()); + changeAppState(EspApplication.AppState.GET_DATA_FAILED, data); + } + + @Override + public void onNetworkFailure(Exception exception) { + changeAppState(AppState.NO_INTERNET, null); + } + }); + } + + public void refreshData() { + if (!appState.equals(AppState.GETTING_DATA)) { + changeAppState(AppState.REFRESH_DATA, null); + } + } + + public void logout() { + // Do logout and clear all data + if (!ApiManager.isOAuthLogin) { + String username = AppHelper.getCurrUser(); + CognitoUser user = AppHelper.getPool().getUser(username); + user.signOut(); + } + + EspDatabase.getInstance(this).getNodeDao().deleteAll(); + EspDatabase.getInstance(this).getGroupDao().deleteAll(); + nodeMap.clear(); + scheduleMap.clear(); + mDNSDeviceMap.clear(); + groupMap.clear(); + + SharedPreferences.Editor editor = appPreferences.edit(); + editor.clear(); + editor.apply(); + + SharedPreferences wifiNetworkPref = getSharedPreferences(AppConstants.PREF_FILE_WIFI_NETWORKS, Context.MODE_PRIVATE); + SharedPreferences.Editor wifiNetworkEditor = wifiNetworkPref.edit(); + wifiNetworkEditor.clear(); + wifiNetworkEditor.apply(); + Log.e(TAG, "Deleted all things from local storage."); + changeAppState(AppState.NO_USER_LOGIN, null); } } diff --git a/app/src/main/java/com/espressif/JsonDataParser.java b/app/src/main/java/com/espressif/JsonDataParser.java index 46933e8..719718b 100644 --- a/app/src/main/java/com/espressif/JsonDataParser.java +++ b/app/src/main/java/com/espressif/JsonDataParser.java @@ -353,33 +353,37 @@ public static EspNode setNodeConfig(EspNode espNode, JSONObject nodeConfigJson) public static void setAllParams(EspApplication espAppContext, EspNode node, JSONObject paramsJson) { + String nodeId = node.getNodeId(); ArrayList devices = node.getDevices(); + ArrayList services = node.getServices(); JSONObject scheduleJson = paramsJson.optJSONObject(AppConstants.KEY_SCHEDULE); - String nodeId = node.getNodeId(); + JSONObject timeJson = paramsJson.optJSONObject(AppConstants.KEY_TIME); - for (int i = 0; i < devices.size(); i++) { + if (devices != null) { + for (int i = 0; i < devices.size(); i++) { - ArrayList params = devices.get(i).getParams(); - String deviceName = devices.get(i).getDeviceName(); - JSONObject deviceJson = paramsJson.optJSONObject(deviceName); + ArrayList params = devices.get(i).getParams(); + String deviceName = devices.get(i).getDeviceName(); + JSONObject deviceJson = paramsJson.optJSONObject(deviceName); - if (deviceJson != null) { + if (deviceJson != null) { - for (int j = 0; j < params.size(); j++) { + for (int j = 0; j < params.size(); j++) { - Param param = params.get(j); - String key = param.getName(); + Param param = params.get(j); + String key = param.getName(); - if (!param.isDynamicParam()) { - continue; - } + if (!param.isDynamicParam()) { + continue; + } - if (deviceJson.has(key)) { - setDeviceParamValue(deviceJson, devices.get(i), param); + if (deviceJson.has(key)) { + setDeviceParamValue(deviceJson, devices.get(i), param); + } } + } else { + Log.e(TAG, "Device JSON is not available"); } - } else { - Log.e(TAG, "Device JSON is null"); } } @@ -542,7 +546,30 @@ public static void setAllParams(EspApplication espAppContext, EspNode node, JSON } } } else { - Log.e(TAG, "Schedule JSON is null"); + Log.e(TAG, "Schedule JSON is not available"); + } + + // Timezone + if (timeJson != null && services != null) { + for (int serviceIdx = 0; serviceIdx < services.size(); serviceIdx++) { + Service service = services.get(serviceIdx); + if (AppConstants.SERVICE_TYPE_TIME.equals(service.getType())) { + ArrayList timeParams = service.getParams(); + if (timeParams != null) { + for (int paramIdx = 0; paramIdx < timeParams.size(); paramIdx++) { + Param timeParam = timeParams.get(paramIdx); + String dataType = timeParam.getDataType(); + if (!TextUtils.isEmpty(dataType)) { + if (dataType.equalsIgnoreCase("string")) { + timeParam.setLabelValue(timeJson.optString(timeParam.getName())); + } + } + } + } + } + } + } else { + Log.e(TAG, "Time JSON is not available"); } } } diff --git a/app/src/main/java/com/espressif/NetworkApiManager.java b/app/src/main/java/com/espressif/NetworkApiManager.java index 0cce593..419eb02 100644 --- a/app/src/main/java/com/espressif/NetworkApiManager.java +++ b/app/src/main/java/com/espressif/NetworkApiManager.java @@ -63,7 +63,15 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Error : " + exception.getMessage()); + Log.e(TAG, "Removing Node id : " + nodeId); + espApp.mDNSDeviceMap.remove(nodeId); + updateParamValue(nodeId, body, listener); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Error : " + exception.getMessage()); Log.e(TAG, "Removing Node id : " + nodeId); espApp.mDNSDeviceMap.remove(nodeId); @@ -94,7 +102,15 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Error : " + exception.getMessage()); + Log.e(TAG, "Removing Node id : " + nodeId); + espApp.mDNSDeviceMap.remove(nodeId); + getParamsValues(nodeId, listener); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Error : " + exception.getMessage()); Log.e(TAG, "Removing Node id : " + nodeId); espApp.mDNSDeviceMap.remove(nodeId); @@ -125,7 +141,15 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Error : " + exception.getMessage()); + Log.e(TAG, "Removing Node id : " + nodeId); + espApp.mDNSDeviceMap.remove(nodeId); + getParamsValues(nodeId, listener); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Error : " + exception.getMessage()); Log.e(TAG, "Removing Node id : " + nodeId); espApp.mDNSDeviceMap.remove(nodeId); diff --git a/app/src/main/java/com/espressif/cloudapi/ApiClient.java b/app/src/main/java/com/espressif/cloudapi/ApiClient.java index 7d2fd75..a217e18 100644 --- a/app/src/main/java/com/espressif/cloudapi/ApiClient.java +++ b/app/src/main/java/com/espressif/cloudapi/ApiClient.java @@ -55,6 +55,7 @@ static Retrofit getClient(Context context) { InputStream cert = null; Certificate ca = null; OkHttpClient okHttpClient = null; + TokenAuthenticator authAuthenticator; try { @@ -64,11 +65,8 @@ static Retrofit getClient(Context context) { ca = cf.generateCertificate(cert); } catch (CertificateException e) { - e.printStackTrace(); - } finally { - try { cert.close(); } catch (IOException e) { @@ -79,9 +77,9 @@ static Retrofit getClient(Context context) { // creating a KeyStore containing our trusted CAs String keyStoreType = KeyStore.getDefaultType(); KeyStore keyStore = null; + authAuthenticator = new TokenAuthenticator(context); try { - keyStore = KeyStore.getInstance(keyStoreType); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); @@ -96,8 +94,8 @@ static Retrofit getClient(Context context) { sslContext.init(null, tmf.getTrustManagers(), null); // creating an OkHttpClient that uses our SSLSocketFactory - okHttpClient = new OkHttpClient.Builder() + .authenticator(authAuthenticator) .sslSocketFactory(sslContext.getSocketFactory(), systemDefaultTrustManager()) .connectTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) diff --git a/app/src/main/java/com/espressif/cloudapi/ApiManager.java b/app/src/main/java/com/espressif/cloudapi/ApiManager.java index 4628f49..1d373e1 100644 --- a/app/src/main/java/com/espressif/cloudapi/ApiManager.java +++ b/app/src/main/java/com/espressif/cloudapi/ApiManager.java @@ -44,6 +44,7 @@ import com.espressif.ui.models.Group; import com.espressif.ui.models.Param; import com.espressif.ui.models.Schedule; +import com.espressif.ui.models.Service; import com.espressif.ui.models.SharingRequest; import com.espressif.ui.models.UpdateEvent; import com.espressif.ui.user_module.AppHelper; @@ -57,7 +58,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -96,7 +96,6 @@ public class ApiManager { private SharedPreferences sharedPreferences; private static ArrayList nodeIds = new ArrayList<>(); private static ArrayList scheduleIds = new ArrayList<>(); - private boolean isGetNodesRunning = false; private static ApiManager apiManager; @@ -153,43 +152,27 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to login")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to login")); - } + processError(jsonErrResponse, listener, "Failed to login"); } } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } catch (Exception e) { e.printStackTrace(); - listener.onFailure(e); + listener.onNetworkFailure(e); } } @@ -223,7 +206,15 @@ public void getTokenAndUserId() { editor.putString(AppConstants.KEY_EMAIL, email); editor.apply(); } - Log.d(TAG, "==============>>>>>>>>>>> USER ID : " + userId); + + try { + jwt = new JWT(accessToken); + } catch (DecodeException e) { + e.printStackTrace(); + } + Date expiresAt = jwt.getExpiresAt(); + Log.e(TAG, "==============>>>>>>>>>>> USER ID : " + userId); + Log.e(TAG, "Token expires At : " + expiresAt); } } @@ -272,35 +263,19 @@ public void onResponse(Call call, Response response) } else { Log.e(TAG, "Response received : null"); - listener.onFailure(new RuntimeException("Failed to get Supported Versions")); + listener.onResponseFailure(new RuntimeException("Failed to get Supported Versions")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get Supported Versions")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get Supported Versions")); - } + processError(jsonErrResponse, listener, "Failed to get Supported Versions"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @@ -308,7 +283,7 @@ public void onResponse(Call call, Response response) public void onFailure(Call call, Throwable t) { Log.e(TAG, "Error in receiving Supported Versions"); t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -321,10 +296,6 @@ public void onFailure(Call call, Throwable t) { public void getNodes(final ApiResponseListener listener) { Log.d(TAG, "Get Nodes"); - if (isGetNodesRunning) { - return; - } - isGetNodesRunning = true; nodeIds.clear(); scheduleIds.clear(); getNodesFromCloud("", listener); @@ -405,7 +376,9 @@ public void onResponse(Call call, Response response) espDatabase.getNodeDao().insertOrUpdate(espNode); ArrayList devices = espNode.getDevices(); + ArrayList services = espNode.getServices(); JSONObject scheduleJson = paramsJson.optJSONObject(AppConstants.KEY_SCHEDULE); + JSONObject timeJson = paramsJson.optJSONObject(AppConstants.KEY_TIME); // If node is available on local network then ignore param values received from cloud. if (!espApp.mDNSDeviceMap.containsKey(nodeId) && devices != null) { @@ -597,6 +570,29 @@ public void onResponse(Call call, Response response) } else { Log.e(TAG, "Schedule JSON is null"); } + + // Timezone + if (timeJson != null && services != null) { + for (int serviceIdx = 0; serviceIdx < services.size(); serviceIdx++) { + Service service = services.get(serviceIdx); + if (AppConstants.SERVICE_TYPE_TIME.equals(service.getType())) { + ArrayList timeParams = service.getParams(); + if (timeParams != null) { + for (int paramIdx = 0; paramIdx < timeParams.size(); paramIdx++) { + Param timeParam = timeParams.get(paramIdx); + String dataType = timeParam.getDataType(); + if (!TextUtils.isEmpty(dataType)) { + if (dataType.equalsIgnoreCase("string")) { + timeParam.setLabelValue(timeJson.optString(timeParam.getName())); + } + } + } + } + } + } + } else { + Log.e(TAG, "Time JSON is not available"); + } } // Node Status @@ -657,60 +653,31 @@ public void onResponse(Call call, Response response) } } - if (!BuildConfig.isNodeGroupingSupported) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_SUCCESS); - } listener.onSuccess(null); } } else { Log.e(TAG, "Response received : null"); - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - listener.onFailure(new RuntimeException("Failed to get User device mapping")); + listener.onResponseFailure(new RuntimeException("Failed to get User device mapping")); } } else { String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get User device mapping")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get User device mapping")); - } + processError(jsonErrResponse, listener, "Failed to get User device mapping"); } } catch (JSONException e) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -731,10 +698,6 @@ public void onResponse(Call call, Response response) if (response.body() != null) { - if (espApp.nodeMap == null) { - espApp.nodeMap = new HashMap<>(); - } - String jsonResponse = response.body().string(); Log.e(TAG, "onResponse Success : " + jsonResponse); JSONObject jsonObject = new JSONObject(jsonResponse); @@ -809,41 +772,25 @@ public void onResponse(Call call, Response response) } else { Log.e(TAG, "Response received : null"); - listener.onFailure(new RuntimeException("Failed to get Node Details")); + listener.onResponseFailure(new RuntimeException("Failed to get Node Details")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get Node Details")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get Node Details")); - } + processError(jsonErrResponse, listener, "Failed to get Node Details"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -893,41 +840,25 @@ public void onResponse(Call call, Response response) } else { Log.e(TAG, "Response received : null"); - listener.onFailure(new RuntimeException("Failed to get Node status")); + listener.onResponseFailure(new RuntimeException("Failed to get Node status")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get Node status")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get Node status")); - } + processError(jsonErrResponse, listener, "Failed to get Node status"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -972,42 +903,26 @@ public void onResponse(Call call, Response response) listener.onSuccess(data); } else { - listener.onFailure(new RuntimeException("Failed to add device")); + listener.onResponseFailure(new RuntimeException("Failed to add device")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to add device")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to add device")); - } + processError(jsonErrResponse, listener, "Failed to add device"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -1043,42 +958,23 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - listener.onFailure(new RuntimeException("Failed to delete this node.")); + listener.onResponseFailure(new RuntimeException("Failed to delete this node.")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to delete this node.")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to delete this node.")); - } + processError(jsonErrResponse, listener, "Failed to delete this node."); } - } catch (JSONException e) { - e.printStackTrace(); - listener.onFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -1299,42 +1195,26 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - listener.onFailure(new RuntimeException("Failed to get param values")); + listener.onResponseFailure(new RuntimeException("Failed to get param values")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get param values")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get param values")); - } + processError(jsonErrResponse, listener, "Failed to get param values"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -1362,42 +1242,26 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - listener.onFailure(new RuntimeException("Failed to update param value")); + listener.onResponseFailure(new RuntimeException("Failed to update param value")); } } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to update param value")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to update param value")); - } + processError(jsonErrResponse, listener, "Failed to update param value"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -1471,7 +1335,7 @@ public void run() throws Exception { if (isAllReqSuccessful) { listener.onSuccess(null); } else { - listener.onFailure(new RuntimeException("Failed to update schedule for few devices")); + listener.onResponseFailure(new RuntimeException("Failed to update schedule for few devices")); } } }) @@ -1576,94 +1440,15 @@ public void run() { } }; - public boolean isTokenExpired() { - - Log.d(TAG, "Check isTokenExpired"); - - idToken = sharedPreferences.getString(AppConstants.KEY_ID_TOKEN, ""); - accessToken = sharedPreferences.getString(AppConstants.KEY_ACCESS_TOKEN, ""); - refreshToken = sharedPreferences.getString(AppConstants.KEY_REFRESH_TOKEN, ""); - - JWT jwt = null; - try { - jwt = new JWT(accessToken); - } catch (DecodeException e) { - e.printStackTrace(); - } - - Date expiresAt = jwt.getExpiresAt(); - Calendar calendar = Calendar.getInstance(); - Date currentTIme = calendar.getTime(); - Log.e(TAG, "Token expires At : " + expiresAt); - - if (currentTIme.after(expiresAt)) { - Log.e(TAG, "Token has expired"); - return true; - } else { - Log.d(TAG, "Token has not expired"); - return false; - } - } - - public void getNewToken(final ApiResponseListener listener) { - + public String getNewToken() { + String newAccToken = ""; + Log.d(TAG, "Getting new access token "); if (isOAuthLogin) { - - getNewTokenForOAuth(listener); - + newAccToken = getNewTokenForOAuthUser(); } else { - - AuthenticationHandler authenticationHandler = new AuthenticationHandler() { - - @Override - public void onSuccess(CognitoUserSession cognitoUserSession, CognitoDevice newDevice) { - - Log.d(TAG, " -- Auth Success"); - AppHelper.setCurrSession(cognitoUserSession); - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(AppConstants.KEY_ID_TOKEN, cognitoUserSession.getIdToken().getJWTToken()); - editor.putString(AppConstants.KEY_ACCESS_TOKEN, cognitoUserSession.getAccessToken().getJWTToken()); - editor.putString(AppConstants.KEY_REFRESH_TOKEN, cognitoUserSession.getRefreshToken().getToken()); - editor.putBoolean(AppConstants.KEY_IS_OAUTH_LOGIN, false); - editor.apply(); - - AppHelper.newDevice(newDevice); - getTokenAndUserId(); - listener.onSuccess(null); - } - - @Override - public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) { - Log.d(TAG, "getAuthenticationDetails " + userId); - Locale.setDefault(Locale.US); - getUserAuthentication(authenticationContinuation, userName); - } - - @Override - public void getMFACode(MultiFactorAuthenticationContinuation continuation) { - Log.d(TAG, "getMFACode "); - } - - @Override - public void authenticationChallenge(ChallengeContinuation continuation) { - // Nothing to do for this app. - /* - * For Custom authentication challenge, implement your logic to present challenge to the - * user and pass the user's responses to the continuation. - */ - Log.d(TAG, "authenticationChallenge : " + continuation.getChallengeName()); - } - - @Override - public void onFailure(Exception exception) { - Log.e(TAG, "onFailure "); - exception.printStackTrace(); - listener.onFailure(exception); - } - }; - - AppHelper.getPool().getUser(userName).getSessionInBackground(authenticationHandler); + newAccToken = getNewTokenForCognitoUser(); } + return newAccToken; } private void getUserAuthentication(AuthenticationContinuation continuation, String username) { @@ -1673,78 +1458,106 @@ private void getUserAuthentication(AuthenticationContinuation continuation, Stri userName = username; AppHelper.setUser(username); } - AuthenticationDetails authenticationDetails = new AuthenticationDetails(userName, "", null); continuation.setAuthenticationDetails(authenticationDetails); continuation.continueTask(); } - public void getNewTokenForOAuth(final ApiResponseListener listener) { + public String getNewTokenForCognitoUser() { - Log.d(TAG, "Get New Token For OAuth"); - HashMap body = new HashMap<>(); - body.put("user_name", userId); - body.put("refreshtoken", refreshToken); + Log.d(TAG, "Get New Token For Cognito user"); - apiInterface.getOAuthLoginToken(AppConstants.URL_OAUTH_LOGIN, body).enqueue(new Callback() { + AuthenticationHandler authenticationHandler = new AuthenticationHandler() { @Override - public void onResponse(Call call, Response response) { + public void onSuccess(CognitoUserSession cognitoUserSession, CognitoDevice newDevice) { - Log.d(TAG, "onResponse code : " + response.code()); - try { - if (response.isSuccessful()) { + Log.e(TAG, " -- Auth Success"); + AppHelper.setCurrSession(cognitoUserSession); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(AppConstants.KEY_ID_TOKEN, cognitoUserSession.getIdToken().getJWTToken()); + editor.putString(AppConstants.KEY_ACCESS_TOKEN, cognitoUserSession.getAccessToken().getJWTToken()); + editor.putString(AppConstants.KEY_REFRESH_TOKEN, cognitoUserSession.getRefreshToken().getToken()); + editor.putBoolean(AppConstants.KEY_IS_OAUTH_LOGIN, false); + editor.apply(); - String jsonResponse = response.body().string(); - JSONObject jsonObject = new JSONObject(jsonResponse); - idToken = jsonObject.getString("idtoken"); - accessToken = jsonObject.getString("accesstoken"); - isOAuthLogin = true; + AppHelper.newDevice(newDevice); + getTokenAndUserId(); + } - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.putString(AppConstants.KEY_ID_TOKEN, idToken); - editor.putString(AppConstants.KEY_ACCESS_TOKEN, accessToken); - editor.putBoolean(AppConstants.KEY_IS_OAUTH_LOGIN, true); - editor.apply(); + @Override + public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) { + Log.d(TAG, "getAuthenticationDetails " + userId); + Locale.setDefault(Locale.US); + getUserAuthentication(authenticationContinuation, userName); + } - getTokenAndUserId(); - listener.onSuccess(null); + @Override + public void getMFACode(MultiFactorAuthenticationContinuation continuation) { + Log.d(TAG, "getMFACode "); + } - } else { + @Override + public void authenticationChallenge(ChallengeContinuation continuation) { + // Nothing to do for this app. + /* + * For Custom authentication challenge, implement your logic to present challenge to the + * user and pass the user's responses to the continuation. + */ + Log.d(TAG, "authenticationChallenge : " + continuation.getChallengeName()); + } - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); + @Override + public void onFailure(Exception exception) { + Log.e(TAG, "onFailure "); + exception.printStackTrace(); + accessToken = null; + } + }; - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { + AppHelper.getPool().getUser(userName).getSession(authenticationHandler); + return accessToken; + } - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); + public String getNewTokenForOAuthUser() { - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get new token")); - } + Log.d(TAG, "Get New Token For OAuth User"); + HashMap body = new HashMap<>(); + body.put("user_name", userId); + body.put("refreshtoken", refreshToken); - } else { - listener.onFailure(new RuntimeException("Failed to get new token")); - } - } - } catch (IOException e) { - e.printStackTrace(); - listener.onFailure(e); + try { + Response response = apiInterface.getOAuthLoginToken(AppConstants.URL_OAUTH_LOGIN, body).execute(); + + if (response.isSuccessful()) { + ResponseBody responseBody = response.body(); + String jsonResponse = responseBody.string(); + Log.e(TAG, "Response Body : " + jsonResponse); + JSONObject jsonObject = null; + try { + jsonObject = new JSONObject(jsonResponse); + idToken = jsonObject.getString("idtoken"); + accessToken = jsonObject.getString("accesstoken"); + isOAuthLogin = true; } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + return null; } - } - @Override - public void onFailure(Call call, Throwable t) { - t.printStackTrace(); - listener.onFailure(new Exception(t)); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString(AppConstants.KEY_ID_TOKEN, idToken); + editor.putString(AppConstants.KEY_ACCESS_TOKEN, accessToken); + editor.putBoolean(AppConstants.KEY_IS_OAUTH_LOGIN, true); + editor.apply(); + getTokenAndUserId(); + return accessToken; + } else { + return null; } - }); + } catch (IOException e) { + e.printStackTrace(); + return null; + } } public void initiateClaim(JsonObject body, final ApiResponseListener listener) { @@ -1767,35 +1580,19 @@ public void onResponse(Call call, Response response) listener.onSuccess(data); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Claim init failed")); - } - - } else { - listener.onFailure(new RuntimeException("Claim init failed")); - } + processError(jsonErrResponse, listener, "Claim init failed"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Claim init failed")); + listener.onResponseFailure(new RuntimeException("Claim init failed")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Claim init failed")); + listener.onNetworkFailure(new RuntimeException("Claim init failed")); } }); } @@ -1809,7 +1606,7 @@ public void verifyClaiming(JsonObject body, final ApiResponseListener listener) @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Verify Claiming, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -1820,35 +1617,19 @@ public void onResponse(Call call, Response response) listener.onSuccess(data); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Claim verify failed")); - } - - } else { - listener.onFailure(new RuntimeException("Claim verify failed")); - } + processError(jsonErrResponse, listener, "Claim verify failed"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Claim verify failed")); + listener.onResponseFailure(new RuntimeException("Claim verify failed")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Claim verify failed")); + listener.onNetworkFailure(new RuntimeException("Claim verify failed")); } }); } @@ -1862,7 +1643,7 @@ public void createGroup(JsonObject body, final ApiResponseListener listener) { @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Create Group, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -1871,35 +1652,19 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to create group")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to create group")); - } + processError(jsonErrResponse, listener, "Failed to create group"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to create group")); + listener.onResponseFailure(new RuntimeException("Failed to create group")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to create group")); + listener.onNetworkFailure(new RuntimeException("Failed to create group")); } }); } @@ -1913,7 +1678,7 @@ public void updateGroup(final String groupId, JsonObject body, final ApiResponse @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Update Group, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -1922,35 +1687,19 @@ public void onResponse(Call call, Response response) getUserGroups(groupId, listener); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to update group")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to update group")); - } + processError(jsonErrResponse, listener, "Failed to update group"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to update group")); + listener.onResponseFailure(new RuntimeException("Failed to update group")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to update group")); + listener.onNetworkFailure(new RuntimeException("Failed to update group")); } }); } @@ -1964,7 +1713,7 @@ public void removeGroup(final String groupId, final ApiResponseListener listener @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Remove Group, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -1975,28 +1724,12 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to remove group")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to remove group")); - } + processError(jsonErrResponse, listener, "Failed to remove group"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove group")); + listener.onResponseFailure(new RuntimeException("Failed to remove group")); } } @@ -2004,7 +1737,7 @@ public void onResponse(Call call, Response response) public void onFailure(Call call, Throwable t) { Log.e(TAG, "ON FAILURE"); t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove group")); + listener.onNetworkFailure(new RuntimeException("Failed to remove group")); } }); } @@ -2018,7 +1751,7 @@ public void getUserGroups(final String groupId, final ApiResponseListener listen @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Get Groups, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -2059,58 +1792,22 @@ public void onResponse(Call call, Response response) } } } - if (isGetNodesRunning) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_SUCCESS); - } listener.onSuccess(null); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - if (isGetNodesRunning) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - } - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get user groups")); - } - - } else { - if (isGetNodesRunning) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - } - listener.onFailure(new RuntimeException("Failed to get user groups")); - } + processError(jsonErrResponse, listener, "Failed to get user groups"); } } catch (Exception e) { - if (isGetNodesRunning) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - } e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to get user groups")); + listener.onResponseFailure(new RuntimeException("Failed to get user groups")); } } @Override public void onFailure(Call call, Throwable t) { - if (isGetNodesRunning) { - isGetNodesRunning = false; - espApp.setCurrentStatus(EspApplication.GetDataStatus.GET_DATA_FAILED); - } t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to get user groups")); + listener.onNetworkFailure(new RuntimeException("Failed to get user groups")); } }); } @@ -2138,6 +1835,7 @@ public void onResponse(Call call, Response response) if (response.isSuccessful()) { if (response.body() != null) { String jsonResponse = response.body().string(); + Log.d(TAG, "Response : " + jsonResponse); JSONObject jsonObject = new JSONObject(jsonResponse); JSONArray nodeJsonArray = jsonObject.optJSONArray(AppConstants.KEY_SHARING_REQUESTS); @@ -2192,41 +1890,26 @@ public void onResponse(Call call, Response response) } else { Log.e(TAG, "Response received : null"); - listener.onFailure(new RuntimeException("Failed to get sharing requests")); + listener.onResponseFailure(new RuntimeException("Failed to get sharing requests")); } } else { String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get sharing requests")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get sharing requests")); - } + processError(jsonErrResponse, listener, "Failed to get sharing requests"); } } catch (JSONException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } catch (IOException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new Exception(t)); + listener.onNetworkFailure(new Exception(t)); } }); } @@ -2244,7 +1927,7 @@ public void updateSharingRequest(final String requestId, final boolean requestAc @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Update Sharing request, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -2253,33 +1936,18 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to update sharing request")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to update sharing request")); - } + processError(jsonErrResponse, listener, "Failed to update sharing request"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to update sharing request")); + listener.onResponseFailure(new RuntimeException("Failed to update sharing request")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to update sharing request")); + listener.onNetworkFailure(new RuntimeException("Failed to update sharing request")); } }); } @@ -2293,44 +1961,26 @@ public void removeSharingRequest(final String requestId, final ApiResponseListen @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Remove Sharing request, Response code : " + response.code()); try { if (response.isSuccessful()) { - String jsonResponse = response.body().string(); listener.onSuccess(null); - } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to remove sharing request")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to remove sharing request")); - } + processError(jsonErrResponse, listener, "Failed to remove sharing request"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove sharing request")); + listener.onResponseFailure(new RuntimeException("Failed to remove sharing request")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove sharing request")); + listener.onNetworkFailure(new RuntimeException("Failed to remove sharing request")); } }); } @@ -2365,7 +2015,7 @@ public void shareNodeWithUser(final String nodeId, final String email, final Api @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Share node, Response code : " + response.code()); try { if (response.isSuccessful()) { String jsonResponse = response.body().string(); @@ -2377,35 +2027,19 @@ public void onResponse(Call call, Response response) listener.onSuccess(bundle); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Node sharing failed")); - } - - } else { - listener.onFailure(new RuntimeException("Node sharing failed")); - } + processError(jsonErrResponse, listener, "Node sharing failed"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Node sharing failed")); + listener.onResponseFailure(new RuntimeException("Node sharing failed")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Node sharing failed")); + listener.onNetworkFailure(new RuntimeException("Node sharing failed")); } }); } @@ -2419,7 +2053,7 @@ public void getNodeSharing(final String nodeId, final ApiResponseListener listen @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); + Log.d(TAG, "Get node sharing info, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -2474,35 +2108,19 @@ public void onResponse(Call call, Response response) listener.onSuccess(data); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to get node sharing info")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to get node sharing info")); - } + processError(jsonErrResponse, listener, "Failed to get node sharing info"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to get node sharing info")); + listener.onResponseFailure(new RuntimeException("Failed to get node sharing info")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to get node sharing info")); + listener.onNetworkFailure(new RuntimeException("Failed to get node sharing info")); } }); } @@ -2516,8 +2134,7 @@ public void removeSharing(final String nodeId, final String email, final ApiResp @Override public void onResponse(Call call, Response response) { - Log.d(TAG, "Response code : " + response.code()); - + Log.d(TAG, "Remove Sharing, Response code : " + response.code()); try { if (response.isSuccessful()) { @@ -2526,39 +2143,46 @@ public void onResponse(Call call, Response response) listener.onSuccess(null); } else { - String jsonErrResponse = response.errorBody().string(); - Log.e(TAG, "Error Response : " + jsonErrResponse); - - if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { - - JSONObject jsonObject = new JSONObject(jsonErrResponse); - String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); - - if (!TextUtils.isEmpty(err)) { - listener.onFailure(new CloudException(err)); - } else { - listener.onFailure(new RuntimeException("Failed to remove sharing")); - } - - } else { - listener.onFailure(new RuntimeException("Failed to remove sharing")); - } + processError(jsonErrResponse, listener, "Failed to remove sharing"); } } catch (Exception e) { e.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove sharing")); + listener.onResponseFailure(new RuntimeException("Failed to remove sharing")); } } @Override public void onFailure(Call call, Throwable t) { t.printStackTrace(); - listener.onFailure(new RuntimeException("Failed to remove sharing")); + listener.onNetworkFailure(new RuntimeException("Failed to remove sharing")); } }); } + private void processError(String jsonErrResponse, ApiResponseListener listener, String errMsg) { + + Log.e(TAG, "Error Response : " + jsonErrResponse); + try { + if (jsonErrResponse.contains(AppConstants.KEY_FAILURE_RESPONSE)) { + + JSONObject jsonObject = new JSONObject(jsonErrResponse); + String err = jsonObject.optString(AppConstants.KEY_DESCRIPTION); + + if (!TextUtils.isEmpty(err)) { + listener.onResponseFailure(new CloudException(err)); + } else { + listener.onResponseFailure(new RuntimeException(errMsg)); + } + } else { + listener.onResponseFailure(new RuntimeException(errMsg)); + } + } catch (JSONException e) { + e.printStackTrace(); + listener.onResponseFailure(new RuntimeException(errMsg)); + } + } + private Runnable stopRequestStatusPollingTask = new Runnable() { @Override @@ -2571,7 +2195,6 @@ public void run() { }; public void cancelRequestStatusPollingTask() { - handler.removeCallbacks(stopRequestStatusPollingTask); } } diff --git a/app/src/main/java/com/espressif/cloudapi/ApiResponseListener.java b/app/src/main/java/com/espressif/cloudapi/ApiResponseListener.java index aec8434..24e9aed 100644 --- a/app/src/main/java/com/espressif/cloudapi/ApiResponseListener.java +++ b/app/src/main/java/com/espressif/cloudapi/ApiResponseListener.java @@ -23,5 +23,7 @@ public interface ApiResponseListener { void onSuccess(Bundle data); - void onFailure(Exception exception); + void onResponseFailure(Exception exception); + + void onNetworkFailure(Exception exception); } diff --git a/app/src/main/java/com/espressif/cloudapi/TokenAuthenticator.java b/app/src/main/java/com/espressif/cloudapi/TokenAuthenticator.java new file mode 100644 index 0000000..049e23b --- /dev/null +++ b/app/src/main/java/com/espressif/cloudapi/TokenAuthenticator.java @@ -0,0 +1,69 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +package com.espressif.cloudapi; + +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import android.util.Log; + +import com.espressif.AppConstants; +import com.espressif.EspApplication; +import com.espressif.ui.activities.MainActivity; + +import okhttp3.Authenticator; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; + +public class TokenAuthenticator implements Authenticator { + + private static final String TAG = TokenAuthenticator.class.getSimpleName(); + + private Context context; + + TokenAuthenticator(Context context) { + this.context = context; + } + + @Override + public Request authenticate(Route route, Response response) { + + Log.d(TAG, "=============== Authenticate callback ==============="); + Log.d(TAG, "Response code : " + response.code()); + String newToken = ApiManager.getInstance(context).getNewToken(); + + if (!TextUtils.isEmpty(newToken)) { + Log.d(TAG, "Retrying with new token"); +// Add new header to rejected request and retry it + return response.request().newBuilder() + .header(AppConstants.HEADER_AUTHORIZATION, newToken) + .build(); + } else { + gotoLoginScreen(); + return null; + } + } + + private void gotoLoginScreen() { + ((EspApplication) context).logout(); + Log.d(TAG, "Logout and display Login screen"); + Intent i = new Intent(context, MainActivity.class); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(i); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/espressif/mdns/mDNSApiManager.java b/app/src/main/java/com/espressif/mdns/mDNSApiManager.java index 5090fde..234b5c1 100644 --- a/app/src/main/java/com/espressif/mdns/mDNSApiManager.java +++ b/app/src/main/java/com/espressif/mdns/mDNSApiManager.java @@ -109,8 +109,13 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { - listener.onFailure(exception); + public void onResponseFailure(Exception exception) { + listener.onResponseFailure(exception); + } + + @Override + public void onNetworkFailure(Exception exception) { + listener.onResponseFailure(exception); } }); @@ -130,13 +135,18 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { - listener.onFailure(exception); + public void onResponseFailure(Exception exception) { + listener.onResponseFailure(exception); + } + + @Override + public void onNetworkFailure(Exception exception) { + listener.onResponseFailure(exception); } }); } } else { - listener.onFailure(new RuntimeException("Device not available locally.")); + listener.onResponseFailure(new RuntimeException("Device not available locally.")); } } @@ -197,8 +207,13 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { - listener.onFailure(exception); + public void onResponseFailure(Exception exception) { + listener.onResponseFailure(exception); + } + + @Override + public void onNetworkFailure(Exception exception) { + listener.onResponseFailure(exception); } }); @@ -218,13 +233,18 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { - listener.onFailure(exception); + public void onResponseFailure(Exception exception) { + listener.onResponseFailure(exception); + } + + @Override + public void onNetworkFailure(Exception exception) { + listener.onResponseFailure(exception); } }); } } else { - listener.onFailure(new RuntimeException("Device not available locally.")); + listener.onResponseFailure(new RuntimeException("Device not available locally.")); } } @@ -258,7 +278,7 @@ public void onSuccess(byte[] returnData) { if (status.equals(Constants.Status.Success)) { listener.onSuccess(null); } else { - listener.onFailure(new RuntimeException("Failed to update param.")); + listener.onResponseFailure(new RuntimeException("Failed to update param.")); } } catch (InvalidProtocolBufferException e) { @@ -267,18 +287,18 @@ public void onSuccess(byte[] returnData) { } else { Log.e(TAG, "returnData is null"); - listener.onFailure(new RuntimeException("Response not received.")); + listener.onResponseFailure(new RuntimeException("Response not received.")); } } @Override public void onFailure(Exception e) { - listener.onFailure(e); + listener.onResponseFailure(e); } }); } else { - listener.onFailure(new RuntimeException("Device not available locally.")); + listener.onResponseFailure(new RuntimeException("Device not available locally.")); } } @@ -303,7 +323,7 @@ public void onSuccess(byte[] returnData) { @Override public void onFailure(Exception e) { - listener.onFailure(e); + listener.onResponseFailure(e); } }); } @@ -320,13 +340,13 @@ public void onSuccess(byte[] returnData) { if (returnData != null) { processGetPropertyValue(returnData, listener); } else { - listener.onFailure(new RuntimeException("Response not received.")); + listener.onResponseFailure(new RuntimeException("Response not received.")); } } @Override public void onFailure(Exception e) { - listener.onFailure(e); + listener.onResponseFailure(e); } }); } @@ -411,12 +431,12 @@ private void processGetPropertyValue(byte[] returnData, final ApiResponseListene } listener.onSuccess(bundle); } else { - listener.onFailure(new RuntimeException("Failed to get data from device")); + listener.onResponseFailure(new RuntimeException("Failed to get data from device")); } } catch (InvalidProtocolBufferException e) { e.printStackTrace(); - listener.onFailure(e); + listener.onResponseFailure(e); } } } diff --git a/app/src/main/java/com/espressif/ui/activities/AddDeviceActivity.java b/app/src/main/java/com/espressif/ui/activities/AddDeviceActivity.java index 5b57a47..acf72f9 100644 --- a/app/src/main/java/com/espressif/ui/activities/AddDeviceActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/AddDeviceActivity.java @@ -28,6 +28,8 @@ import android.text.TextUtils; import android.util.Log; import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -47,6 +49,7 @@ import com.espressif.provisioning.listeners.QRCodeScanListener; import com.espressif.rainmaker.BuildConfig; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.wang.avi.AVLoadingIndicatorView; @@ -66,16 +69,19 @@ public class AddDeviceActivity extends AppCompatActivity { private static final int REQUEST_CAMERA_PERMISSION = 1; private static final int REQUEST_ACCESS_FINE_LOCATION = 2; - private TextView tvTitle, tvBack, tvCancel; - private MaterialCardView btnAddManually; + private CodeScanner codeScanner; + // private CameraSourcePreview cameraPreview; + private MaterialCardView btnAddManually, btnGetPermission; private TextView txtAddManuallyBtn; - private AVLoadingIndicatorView loader; + private LinearLayout layoutQrCode, layoutPermissionErr; + private TextView tvPermissionErr; + private ImageView ivPermissionErr; + private ESPDevice espDevice; private ESPProvisionManager provisionManager; - // private CameraSourcePreview cameraPreview; - private CodeScanner codeScanner; private boolean isQrCodeDataReceived = false; + private String connectedNetwork; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -84,15 +90,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { provisionManager = ESPProvisionManager.getInstance(getApplicationContext()); initViews(); EventBus.getDefault().register(this); + connectedNetwork = getWifiSsid(); } @Override protected void onResume() { super.onResume(); - if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED - && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { - // if (cameraPreview != null) { // try { // cameraPreview.start(); @@ -101,21 +105,8 @@ protected void onResume() { // } // } - if (codeScanner != null && !isQrCodeDataReceived) { - codeScanner.startPreview(); - } - - // This condition is to get event of cancel button of "try again" popup. Because Android 10 is not giving event on cancel button click if network is not found. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && espDevice != null && espDevice.getTransportType().equals(ESPConstants.TransportType.TRANSPORT_SOFTAP)) { - - String ssid = getWifiSsid(); - Log.d(TAG, "Currently connected WiFi SSID : " + ssid); - Log.d(TAG, "Device Name : " + espDevice.getDeviceName()); - if (!TextUtils.isEmpty(ssid) && !ssid.equals(espDevice.getDeviceName())) { - Log.e(TAG, "Device is not connected"); - finish(); - } - } + if (codeScanner != null && !isQrCodeDataReceived) { + codeScanner.startPreview(); } } @@ -124,13 +115,13 @@ protected void onResume() { */ @Override protected void onPause() { - super.onPause(); -// if (cameraPreview != null) { + // if (cameraPreview != null) { // cameraPreview.stop(); // } if (codeScanner != null) { - codeScanner.stopPreview(); + codeScanner.releaseResources(); } + super.onPause(); } @Override @@ -141,9 +132,9 @@ protected void onDestroy() { // if (cameraPreview != null) { // cameraPreview.release(); // } - if (codeScanner != null) { - codeScanner.releaseResources(); - } +// if (codeScanner != null) { +// codeScanner.releaseResources(); +// } super.onDestroy(); } @@ -159,16 +150,33 @@ public void onBackPressed() { @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - Log.e(TAG, "onRequestPermissionsResult , requestCode : " + requestCode); - if (requestCode == REQUEST_CAMERA_PERMISSION) { - - initialiseDetectorsAndSources(); - - } else if (requestCode == REQUEST_ACCESS_FINE_LOCATION) { - - initialiseDetectorsAndSources(); + if (requestCode == REQUEST_CAMERA_PERMISSION && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + findViewById(R.id.scanner_view).setVisibility(View.GONE); + layoutQrCode.setVisibility(View.GONE); + layoutPermissionErr.setVisibility(View.VISIBLE); + tvPermissionErr.setText(R.string.error_camera_permission); + ivPermissionErr.setImageResource(R.drawable.ic_no_camera_permission); + } else { + layoutQrCode.setVisibility(View.VISIBLE); + layoutPermissionErr.setVisibility(View.GONE); + openCamera(); + } + } else if (requestCode == REQUEST_ACCESS_FINE_LOCATION && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + findViewById(R.id.scanner_view).setVisibility(View.GONE); + layoutQrCode.setVisibility(View.GONE); + layoutPermissionErr.setVisibility(View.VISIBLE); + tvPermissionErr.setText(R.string.error_location_permission); + ivPermissionErr.setImageResource(R.drawable.ic_no_location_permission); + } else { + findViewById(R.id.scanner_view).setVisibility(View.VISIBLE); + layoutQrCode.setVisibility(View.VISIBLE); + layoutPermissionErr.setVisibility(View.GONE); + scanQrCode(); + } } } @@ -180,18 +188,12 @@ public void onEvent(DeviceConnectionEvent event) { switch (event.getEventType()) { case ESPConstants.EVENT_DEVICE_CONNECTED: - Log.e(TAG, "Device Connected Event Received"); checkDeviceCapabilities(); break; case ESPConstants.EVENT_DEVICE_DISCONNECTED: -// Toast.makeText(AddDeviceActivity.this, "Device disconnected", Toast.LENGTH_LONG).show(); - askForManualDeviceConnection(); - break; - case ESPConstants.EVENT_DEVICE_CONNECTION_FAILED: -// Toast.makeText(AddDeviceActivity.this, "Failed to connect with device", Toast.LENGTH_LONG).show(); askForManualDeviceConnection(); break; } @@ -235,77 +237,85 @@ public void onClick(View v) { } }; - private View.OnClickListener cancelBtnClickListener = new View.OnClickListener() { + View.OnClickListener btnGetPermissionClickListener = new View.OnClickListener() { @Override public void onClick(View v) { + if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + + ActivityCompat.requestPermissions(AddDeviceActivity.this, new + String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); + + } else if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - if (provisionManager.getEspDevice() != null) { - provisionManager.getEspDevice().disconnectDevice(); + ActivityCompat.requestPermissions(AddDeviceActivity.this, new + String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION); } - setResult(RESULT_CANCELED, getIntent()); - finish(); } }; private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_add_device); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); - tvCancel.setOnClickListener(cancelBtnClickListener); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_add_device); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } + setResult(RESULT_CANCELED, getIntent()); + finish(); + } + }); CodeScannerView scannerView = findViewById(R.id.scanner_view); codeScanner = new CodeScanner(this, scannerView); // cameraPreview = findViewById(R.id.preview); - btnAddManually = findViewById(R.id.btn_add_device_manually); - txtAddManuallyBtn = findViewById(R.id.text_btn); loader = findViewById(R.id.loader); + layoutQrCode = findViewById(R.id.layout_qr_code_txt); + layoutPermissionErr = findViewById(R.id.layout_permission_error); + tvPermissionErr = findViewById(R.id.tv_permission_error); + ivPermissionErr = findViewById(R.id.iv_permission_error); + btnAddManually = findViewById(R.id.btn_add_device_manually); + txtAddManuallyBtn = btnAddManually.findViewById(R.id.text_btn); txtAddManuallyBtn.setText(R.string.btn_no_qr_code); btnAddManually.setOnClickListener(btnAddManuallyClickListener); - initialiseDetectorsAndSources(); - } - - private void initialiseDetectorsAndSources() { - - if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED - && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED - && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { - - provisionManager.scanQRCode(codeScanner, qrCodeScanListener); -// cameraPreview.setVisibility(View.VISIBLE); - findViewById(R.id.scanner_view).setVisibility(View.VISIBLE); + btnGetPermission = findViewById(R.id.btn_get_permission); + TextView btnPermissionText = btnGetPermission.findViewById(R.id.text_btn); + btnPermissionText.setText(R.string.btn_get_permission); + btnGetPermission.setOnClickListener(btnGetPermissionClickListener); - if (codeScanner != null) { - codeScanner.startPreview(); - } + if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { + openCamera(); } else { - Log.e(TAG, "All permissions are not granted."); - askForPermissions(); + ActivityCompat.requestPermissions(AddDeviceActivity.this, new + String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); } } - private void askForPermissions() { - - if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { - - ActivityCompat.requestPermissions(AddDeviceActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION); + private void openCamera() { + findViewById(R.id.scanner_view).setVisibility(View.VISIBLE); + if (codeScanner != null) { + codeScanner.startPreview(); + } + scanQrCode(); + } - } else if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + private void scanQrCode() { + if (ActivityCompat.checkSelfPermission(AddDeviceActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + provisionManager.scanQRCode(codeScanner, qrCodeScanListener); + } else { ActivityCompat.requestPermissions(AddDeviceActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION); - } else if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { - - ActivityCompat.requestPermissions(AddDeviceActivity.this, new - String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION); } } @@ -531,6 +541,7 @@ private void goToBLEProvisionLanding(boolean isSec1) { if (espDevice != null) { intent.putExtra(AppConstants.KEY_DEVICE_NAME, espDevice.getDeviceName()); intent.putExtra(AppConstants.KEY_PROOF_OF_POSSESSION, espDevice.getProofOfPossession()); + intent.putExtra(AppConstants.KEY_SSID, connectedNetwork); } startActivity(intent); } @@ -548,6 +559,7 @@ private void goToWiFiProvisionLanding(boolean isSec1) { if (espDevice != null) { intent.putExtra(AppConstants.KEY_DEVICE_NAME, espDevice.getDeviceName()); intent.putExtra(AppConstants.KEY_PROOF_OF_POSSESSION, espDevice.getProofOfPossession()); + intent.putExtra(AppConstants.KEY_SSID, connectedNetwork); } startActivity(intent); } @@ -555,18 +567,21 @@ private void goToWiFiProvisionLanding(boolean isSec1) { private void goToWiFiScanActivity() { finish(); Intent wifiListIntent = new Intent(getApplicationContext(), WiFiScanActivity.class); + wifiListIntent.putExtra(AppConstants.KEY_SSID, connectedNetwork); startActivity(wifiListIntent); } private void goToWiFiConfigActivity() { finish(); Intent wifiConfigIntent = new Intent(getApplicationContext(), WiFiConfigActivity.class); + wifiConfigIntent.putExtra(AppConstants.KEY_SSID, connectedNetwork); startActivity(wifiConfigIntent); } private void goToClaimingActivity() { finish(); Intent claimingIntent = new Intent(getApplicationContext(), ClaimingActivity.class); + claimingIntent.putExtra(AppConstants.KEY_SSID, connectedNetwork); startActivity(claimingIntent); } diff --git a/app/src/main/java/com/espressif/ui/activities/AddScheduleActivity.java b/app/src/main/java/com/espressif/ui/activities/AddScheduleActivity.java index 96306e3..06053e4 100644 --- a/app/src/main/java/com/espressif/ui/activities/AddScheduleActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/AddScheduleActivity.java @@ -23,6 +23,8 @@ import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.view.animation.LinearInterpolator; @@ -51,6 +53,7 @@ import com.espressif.ui.models.Param; import com.espressif.ui.models.Schedule; import com.espressif.ui.models.Service; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.google.gson.Gson; import com.google.gson.JsonArray; @@ -72,7 +75,6 @@ public class AddScheduleActivity extends AppCompatActivity { private RelativeLayout rlScheduleName, rlActions, rlRepeat; private TextView tvScheduleName, tvActionDevices; - private TextView tvTitle, tvBack, tvDone; private TimePicker timePicker; private MaterialCardView btnRemoveSchedule; private TextView txtRemoveScheduleBtn; @@ -180,18 +182,41 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } } - private void initViews() { + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_save).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvDone = findViewById(R.id.btn_cancel); + case 1: + saveSchedule(); + return true; - tvTitle.setText(R.string.title_activity_add_schedule); - tvDone.setText(R.string.btn_save); - tvBack.setVisibility(View.VISIBLE); - tvDone.setVisibility(View.VISIBLE); - tvBack.setOnClickListener(backBtnClickListener); - tvDone.setOnClickListener(doneBtnClickListener); + default: + return super.onOptionsItemSelected(item); + } + } + + private void initViews() { + + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_add_schedule); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); btnRemoveSchedule = findViewById(R.id.btn_remove_schedule); txtRemoveScheduleBtn = findViewById(R.id.text_btn); @@ -227,7 +252,7 @@ private void initViews() { operation = AppConstants.KEY_OPERATION_EDIT; scheduleName = schedule.getName(); - tvTitle.setText(R.string.title_activity_schedule_details); + getSupportActionBar().setTitle(R.string.title_activity_schedule_details); HashMap triggers = schedule.getTriggers(); int daysValue = triggers.get(AppConstants.KEY_DAYS); @@ -356,22 +381,6 @@ public void onClick(View v) { } }; - private View.OnClickListener doneBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - saveSchedule(); - } - }; - - private View.OnClickListener backBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - finish(); - } - }; - private View.OnClickListener removeScheduleBtnClickListener = new View.OnClickListener() { @Override @@ -447,7 +456,7 @@ private void confirmForRemoveSchedule() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.dialog_title_remove); - builder.setMessage(R.string.dialog_msg_remove_schedule); + builder.setMessage(R.string.dialog_msg_confirmation); // Set up the buttons builder.setPositiveButton(R.string.btn_confirm, new DialogInterface.OnClickListener() { @@ -517,7 +526,16 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Failure"); + exception.printStackTrace(); + hideRemoveScheduleLoading(); + String errMsg = getString(R.string.error_schedule_remove) + " " + deviceName; + Toast.makeText(AddScheduleActivity.this, errMsg, Toast.LENGTH_LONG).show(); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Failure"); exception.printStackTrace(); hideRemoveScheduleLoading(); @@ -776,7 +794,22 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + Log.e(TAG, "Failed to add schedule for few devices"); + exception.printStackTrace(); + runOnUiThread(new Runnable() { + @Override + public void run() { + + Toast.makeText(AddScheduleActivity.this, R.string.error_schedule_add, Toast.LENGTH_LONG).show(); + hideAddScheduleLoading(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Failed to add schedule for few devices"); exception.printStackTrace(); diff --git a/app/src/main/java/com/espressif/ui/activities/BLEProvisionLanding.java b/app/src/main/java/com/espressif/ui/activities/BLEProvisionLanding.java index 11d8e16..f809509 100644 --- a/app/src/main/java/com/espressif/ui/activities/BLEProvisionLanding.java +++ b/app/src/main/java/com/espressif/ui/activities/BLEProvisionLanding.java @@ -25,17 +25,12 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.LayoutInflater; import android.view.View; -import android.widget.AdapterView; import android.widget.EditText; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -43,6 +38,10 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; +import androidx.core.widget.ContentLoadingProgressBar; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.espressif.AppConstants; import com.espressif.provisioning.DeviceConnectionEvent; @@ -81,9 +80,8 @@ public class BLEProvisionLanding extends AppCompatActivity { private MaterialCardView btnScan; private TextView btnPrefix; private TextView txtScanBtn; - private ImageView arrowImage; - private ListView listView; - private ProgressBar progressBar; + private RecyclerView rvBleDevices; + private ContentLoadingProgressBar progressBar; private RelativeLayout prefixLayout; private TextView textPrefix; @@ -106,10 +104,11 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bleprovision_landing); - MaterialToolbar toolbar = findViewById(R.id.toolbar); - toolbar.setTitle(R.string.title_activity_connect_device); - setSupportActionBar(toolbar); - securityType = getIntent().getStringExtra(AppConstants.KEY_SECURITY_TYPE); + + securityType = AppConstants.SECURITY_1; + if (AppConstants.SECURITY_0.equalsIgnoreCase(BuildConfig.SECURITY)) { + securityType = AppConstants.SECURITY_0; + } // Use this check to determine whether BLE is supported on the device. Then you can // selectively disable BLE-related features. @@ -250,13 +249,27 @@ public void onEvent(DeviceConnectionEvent event) { private void initViews() { + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_connect_device); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ESPProvisionManager provisionManager = ESPProvisionManager.getInstance(getApplicationContext()); + provisionManager.getEspDevice().disconnectDevice(); + finish(); + } + }); + btnScan = findViewById(R.id.btn_scan); txtScanBtn = findViewById(R.id.text_btn); - arrowImage = findViewById(R.id.iv_arrow); + findViewById(R.id.iv_arrow).setVisibility(View.GONE); txtScanBtn.setText(R.string.btn_scan_again); - arrowImage.setVisibility(View.GONE); - listView = findViewById(R.id.ble_devices_list); + rvBleDevices = findViewById(R.id.rv_device_list); progressBar = findViewById(R.id.ble_landing_progress_indicator); prefixLayout = findViewById(R.id.prefix_layout); prefixLayout.setVisibility(View.GONE); @@ -273,11 +286,15 @@ private void initViews() { prefixLayout.setVisibility(View.GONE); } - adapter = new BleDeviceListAdapter(this, R.layout.item_ble_scan, deviceList); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext()); + linearLayoutManager.setOrientation(RecyclerView.VERTICAL); + rvBleDevices.setLayoutManager(linearLayoutManager); + DividerItemDecoration itemDecor = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); + rvBleDevices.addItemDecoration(itemDecor); + + adapter = new BleDeviceListAdapter(this, deviceList); + rvBleDevices.setAdapter(adapter); - // Assign adapter to ListView - listView.setAdapter(adapter); - listView.setOnItemClickListener(onDeviceCLickListener); btnScan.setOnClickListener(btnScanClickListener); btnPrefix.setOnClickListener(btnPrefixChangeClickListener); } @@ -298,23 +315,17 @@ private boolean hasPermissions() { } private void requestBluetoothEnable() { - Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); Log.d(TAG, "Requested user enables Bluetooth."); } private boolean hasLocationPermissions() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - } - return true; + return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } private void requestLocationPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); - } + requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); } private void startScan() { @@ -363,14 +374,14 @@ private void updateProgressAndScanBtn() { btnScan.setEnabled(false); btnScan.setAlpha(0.5f); progressBar.setVisibility(View.VISIBLE); - listView.setVisibility(View.GONE); + rvBleDevices.setVisibility(View.GONE); } else { btnScan.setEnabled(true); btnScan.setAlpha(1f); progressBar.setVisibility(View.GONE); - listView.setVisibility(View.VISIBLE); + rvBleDevices.setVisibility(View.VISIBLE); } } @@ -446,7 +457,7 @@ private void checkDeviceCapabilities() { public void onClick(View v) { bluetoothDevices.clear(); - adapter.clear(); + adapter.notifyDataSetChanged(); startScan(); } }; @@ -479,7 +490,7 @@ public void onPeripheralFound(BluetoothDevice device, ScanResult scanResult) { bleDevice.setName(scanResult.getScanRecord().getDeviceName()); bleDevice.setBluetoothDevice(device); - listView.setVisibility(View.VISIBLE); + rvBleDevices.setVisibility(View.VISIBLE); bluetoothDevices.put(device, serviceUuid); deviceList.add(bleDevice); adapter.notifyDataSetChanged(); @@ -499,31 +510,38 @@ public void onFailure(Exception e) { } }; - private AdapterView.OnItemClickListener onDeviceCLickListener = new AdapterView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView adapterView, View view, int position, long l) { + public void deviceClick(int deviceClickedPosition) { - stopScan(); - isConnecting = true; - isDeviceConnected = false; - btnScan.setVisibility(View.GONE); - listView.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - BLEProvisionLanding.this.position = position; - BleDevice bleDevice = adapter.getItem(position); - String uuid = bluetoothDevices.get(bleDevice.getBluetoothDevice()); - Log.d(TAG, "=================== Connect to device : " + bleDevice.getName() + " UUID : " + uuid); - - if (ActivityCompat.checkSelfPermission(BLEProvisionLanding.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { - provisionManager.getEspDevice().connectBLEDevice(bleDevice.getBluetoothDevice(), uuid); - handler.postDelayed(disconnectDeviceTask, DEVICE_CONNECT_TIMEOUT); + stopScan(); + isConnecting = true; + isDeviceConnected = false; + btnScan.setVisibility(View.GONE); + rvBleDevices.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + this.position = deviceClickedPosition; + BleDevice bleDevice = deviceList.get(deviceClickedPosition); + String uuid = bluetoothDevices.get(bleDevice.getBluetoothDevice()); + Log.d(TAG, "=================== Connect to device : " + bleDevice.getName() + " UUID : " + uuid); + + if (ActivityCompat.checkSelfPermission(BLEProvisionLanding.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + + boolean isSec1 = true; + if (AppConstants.SECURITY_0.equalsIgnoreCase(BuildConfig.SECURITY)) { + isSec1 = false; + } + if (isSec1) { + provisionManager.createESPDevice(ESPConstants.TransportType.TRANSPORT_BLE, ESPConstants.SecurityType.SECURITY_1); } else { - Log.e(TAG, "Not able to connect device as Location permission is not granted."); - Toast.makeText(BLEProvisionLanding.this, "Please give location permission to connect device", Toast.LENGTH_LONG).show(); + provisionManager.createESPDevice(ESPConstants.TransportType.TRANSPORT_BLE, ESPConstants.SecurityType.SECURITY_0); } + + provisionManager.getEspDevice().connectBLEDevice(bleDevice.getBluetoothDevice(), uuid); + handler.postDelayed(disconnectDeviceTask, DEVICE_CONNECT_TIMEOUT); + } else { + Log.e(TAG, "Not able to connect device as Location permission is not granted."); + Toast.makeText(BLEProvisionLanding.this, "Please give location permission to connect device", Toast.LENGTH_LONG).show(); } - }; + } private Runnable disconnectDeviceTask = new Runnable() { @@ -591,32 +609,32 @@ public void onClick(DialogInterface dialog, int which) { } private void goToPopActivity() { - finish(); Intent popIntent = new Intent(getApplicationContext(), ProofOfPossessionActivity.class); popIntent.putExtra(AppConstants.KEY_DEVICE_NAME, deviceList.get(position).getName()); + popIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(popIntent); } private void goToWifiScanListActivity() { - finish(); Intent wifiListIntent = new Intent(getApplicationContext(), WiFiScanActivity.class); wifiListIntent.putExtra(AppConstants.KEY_DEVICE_NAME, deviceList.get(position).getName()); + wifiListIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiListIntent); } private void goToWiFiConfigActivity() { - finish(); Intent wifiConfigIntent = new Intent(getApplicationContext(), WiFiConfigActivity.class); + wifiConfigIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiConfigIntent); } private void goToClaimingActivity() { - finish(); Intent claimingIntent = new Intent(getApplicationContext(), ClaimingActivity.class); + claimingIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(claimingIntent); } } diff --git a/app/src/main/java/com/espressif/ui/activities/ClaimingActivity.java b/app/src/main/java/com/espressif/ui/activities/ClaimingActivity.java index 7354b48..465e959 100644 --- a/app/src/main/java/com/espressif/ui/activities/ClaimingActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/ClaimingActivity.java @@ -24,6 +24,7 @@ import com.espressif.provisioning.ESPProvisionManager; import com.espressif.provisioning.listeners.ResponseListener; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.google.gson.Gson; import com.google.gson.JsonObject; @@ -42,8 +43,6 @@ public class ClaimingActivity extends AppCompatActivity { private static final String TAG = ClaimingActivity.class.getSimpleName(); - private TextView tvTitle, tvBack, tvCancel; - private MaterialCardView btnOk; private TextView txtOkBtn; @@ -54,6 +53,7 @@ public class ClaimingActivity extends AppCompatActivity { private String certificateData = ""; private StringBuilder csrData = new StringBuilder(); private boolean isClaimingAborted = false; + private boolean shouldSendClaimAbortReq = false; private Handler handler; private ApiManager apiManager; @@ -115,37 +115,41 @@ public void onClick(View v) { } }; - private View.OnClickListener cancelBtnClickListener = new View.OnClickListener() { + private void initViews() { - @Override - public void onClick(View v) { + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_claiming); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { - sendClaimAbortRequest(); + @Override + public void onClick(View v) { - handler.postDelayed(new Runnable() { + if (shouldSendClaimAbortReq) { + sendClaimAbortRequest(); - @Override - public void run() { + handler.postDelayed(new Runnable() { + + @Override + public void run() { + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } + finish(); + } + }, 2000); + } else { if (provisionManager.getEspDevice() != null) { provisionManager.getEspDevice().disconnectDevice(); } finish(); } - }, 2000); - } - }; - - private void initViews() { - - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_claiming); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.GONE); - tvCancel.setOnClickListener(cancelBtnClickListener); + } + }); tvClaimProgress = findViewById(R.id.tv_claiming_progress); tvClaimError = findViewById(R.id.tv_claiming_error); @@ -528,7 +532,27 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception e) { + public void onResponseFailure(Exception e) { + + final String errMsg = e.getMessage(); + Log.e(TAG, "Failed to start claiming. Error : " + errMsg); + e.printStackTrace(); + + runOnUiThread(new Runnable() { + + @Override + public void run() { + + sendClaimAbortRequest(); + tvClaimProgress.setText(R.string.error_claiming_progress); + tvClaimError.setText(errMsg); + displayError(); + } + }); + } + + @Override + public void onNetworkFailure(Exception e) { final String errMsg = e.getMessage(); Log.e(TAG, "Failed to start claiming. Error : " + errMsg); @@ -569,7 +593,27 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception e) { + public void onResponseFailure(Exception e) { + + final String errMsg = e.getMessage(); + Log.e(TAG, "Failed to verify claiming. Error : " + errMsg); + e.printStackTrace(); + + runOnUiThread(new Runnable() { + + @Override + public void run() { + + sendClaimAbortRequest(); + tvClaimProgress.setText(R.string.error_claiming_progress); + tvClaimError.setText(errMsg); + displayError(); + } + }); + } + + @Override + public void onNetworkFailure(Exception e) { final String errMsg = e.getMessage(); Log.e(TAG, "Failed to verify claiming. Error : " + errMsg); @@ -593,12 +637,14 @@ public void run() { private void goToWiFiScanActivity() { finish(); Intent wifiListIntent = new Intent(getApplicationContext(), WiFiScanActivity.class); + wifiListIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiListIntent); } private void goToWiFiConfigActivity() { finish(); Intent wifiConfigIntent = new Intent(getApplicationContext(), WiFiConfigActivity.class); + wifiConfigIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiConfigIntent); } @@ -629,7 +675,7 @@ private void displayError() { @Override public void run() { - tvCancel.setVisibility(View.VISIBLE); + shouldSendClaimAbortReq = true; } }; diff --git a/app/src/main/java/com/espressif/ui/activities/EspDeviceActivity.java b/app/src/main/java/com/espressif/ui/activities/EspDeviceActivity.java index a1c4625..43cacb1 100644 --- a/app/src/main/java/com/espressif/ui/activities/EspDeviceActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/EspDeviceActivity.java @@ -18,8 +18,11 @@ import android.os.Bundle; import android.os.Handler; import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; -import android.widget.ImageView; +import android.view.WindowManager; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; @@ -40,14 +43,13 @@ import com.espressif.ui.adapters.ParamAdapter; import com.espressif.ui.models.Device; import com.espressif.ui.models.Param; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.snackbar.Snackbar; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import static com.espressif.EspApplication.GetDataStatus; - public class EspDeviceActivity extends AppCompatActivity { private static final String TAG = EspDeviceActivity.class.getSimpleName(); @@ -55,8 +57,7 @@ public class EspDeviceActivity extends AppCompatActivity { private static final int NODE_DETAILS_ACTIVITY_REQUEST = 10; private static final int UPDATE_INTERVAL = 5000; - private TextView tvTitle, tvBack, tvNoParam, tvNodeOffline; - private ImageView ivNodeInfo; + private TextView tvNoParam, tvNodeOffline; private RecyclerView paramRecyclerView; private RecyclerView attrRecyclerView; private SwipeRefreshLayout swipeRefreshLayout; @@ -73,8 +74,9 @@ public class EspDeviceActivity extends AppCompatActivity { private ContentLoadingProgressBar progressBar; private boolean isNodeOnline; private long timeStampOfStatus; - private boolean isNetworkAvailable = false; + private boolean isNetworkAvailable = true; private boolean shouldGetParams = true; + private RelativeLayout rlProgress, rlParam; @Override protected void onCreate(Bundle savedInstanceState) { @@ -114,6 +116,27 @@ protected void onDestroy() { super.onDestroy(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_info).setIcon(R.drawable.ic_node_info).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + + case 1: + goToNodeDetailsActivity(); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); @@ -124,7 +147,7 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } public void updateDeviceNameInTitle(String deviceName) { - tvTitle.setText(deviceName); + getSupportActionBar().setTitle(deviceName); } public boolean isNodeOnline() { @@ -142,25 +165,11 @@ public void stopUpdateValueTask() { handler.removeCallbacks(updateValuesTask); } - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - finish(); - } - }; - - private View.OnClickListener infoBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - Intent intent = new Intent(EspDeviceActivity.this, NodeDetailsActivity.class); - intent.putExtra(AppConstants.KEY_NODE_ID, device.getNodeId()); - startActivityForResult(intent, NODE_DETAILS_ACTIVITY_REQUEST); - } - }; + private void goToNodeDetailsActivity() { + Intent intent = new Intent(EspDeviceActivity.this, NodeDetailsActivity.class); + intent.putExtra(AppConstants.KEY_NODE_ID, device.getNodeId()); + startActivityForResult(intent, NODE_DETAILS_ACTIVITY_REQUEST); + } private Runnable updateValuesTask = new Runnable() { @@ -174,33 +183,40 @@ public void run() { private void initViews() { - tvTitle = findViewById(R.id.esp_toolbar_title); - tvBack = findViewById(R.id.btn_back); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + tvNoParam = findViewById(R.id.tv_no_params); - ivNodeInfo = findViewById(R.id.btn_info); progressBar = findViewById(R.id.progress_get_params); tvNodeOffline = findViewById(R.id.tv_device_offline); - tvTitle.setText(device.getUserVisibleName()); - tvBack.setVisibility(View.VISIBLE); + rlParam = findViewById(R.id.params_parent_layout); + rlProgress = findViewById(R.id.rl_progress); + + getSupportActionBar().setTitle(device.getUserVisibleName()); paramRecyclerView = findViewById(R.id.rv_dynamic_param_list); attrRecyclerView = findViewById(R.id.rv_static_param_list); swipeRefreshLayout = findViewById(R.id.swipe_container); - tvBack.setOnClickListener(backButtonClickListener); - ivNodeInfo.setOnClickListener(infoBtnClickListener); - - // set a LinearLayoutManager with default orientation LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext()); linearLayoutManager.setOrientation(RecyclerView.VERTICAL); - paramRecyclerView.setLayoutManager(linearLayoutManager); // set LayoutManager to RecyclerView + paramRecyclerView.setLayoutManager(linearLayoutManager); LinearLayoutManager linearLayoutManager1 = new LinearLayoutManager(getApplicationContext()); linearLayoutManager1.setOrientation(RecyclerView.VERTICAL); - attrRecyclerView.setLayoutManager(linearLayoutManager1); // set LayoutManager to RecyclerView + attrRecyclerView.setLayoutManager(linearLayoutManager1); - paramAdapter = new ParamAdapter(this, device.getNodeId(), device.getDeviceName(), paramList); + paramAdapter = new ParamAdapter(this, device, paramList); paramRecyclerView.setAdapter(paramAdapter); attrAdapter = new AttrParamAdapter(this, device.getNodeId(), device.getDeviceName(), attributeList); @@ -240,7 +256,22 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + isNetworkAvailable = true; + hideLoading(); + snackbar.dismiss(); + swipeRefreshLayout.setRefreshing(false); + if (exception instanceof CloudException) { + Toast.makeText(EspDeviceActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(EspDeviceActivity.this, "Failed to get node details", Toast.LENGTH_SHORT).show(); + } + updateUi(); + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); swipeRefreshLayout.setRefreshing(false); @@ -265,7 +296,6 @@ public void onSuccess(Bundle data) { @Override public void run() { - isNetworkAvailable = true; hideLoading(); swipeRefreshLayout.setRefreshing(false); @@ -276,7 +306,22 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + stopUpdateValueTask(); + isNetworkAvailable = true; + hideLoading(); + swipeRefreshLayout.setRefreshing(false); + if (exception instanceof CloudException) { + Toast.makeText(EspDeviceActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(EspDeviceActivity.this, "Failed to get param values", Toast.LENGTH_SHORT).show(); + } + updateUi(); + } + + @Override + public void onNetworkFailure(Exception exception) { stopUpdateValueTask(); hideLoading(); @@ -375,7 +420,7 @@ private void updateUi() { if (!isNodeOnline) { - if (espApp.getCurrentStatus().equals(GetDataStatus.GET_DATA_SUCCESS)) { + if (espApp.getAppState().equals(EspApplication.AppState.GET_DATA_SUCCESS)) { tvNodeOffline.setVisibility(View.VISIBLE); @@ -411,7 +456,6 @@ private void updateUi() { tvNodeOffline.setText(offlineText); } } - } else { tvNodeOffline.setVisibility(View.INVISIBLE); } @@ -445,9 +489,9 @@ private void updateUi() { attrRecyclerView.setVisibility(View.VISIBLE); } - tvTitle.setText(device.getUserVisibleName()); + getSupportActionBar().setTitle(device.getUserVisibleName()); - if (espApp.getCurrentStatus().equals(GetDataStatus.GET_DATA_FAILED) && !isNetworkAvailable) { + if (!isNetworkAvailable) { if (!snackbar.isShown()) { snackbar = Snackbar.make(findViewById(R.id.params_parent_layout), R.string.msg_no_internet, Snackbar.LENGTH_INDEFINITE); } @@ -466,4 +510,19 @@ private void hideLoading() { progressBar.setVisibility(View.GONE); swipeRefreshLayout.setVisibility(View.VISIBLE); } + + public void showParamUpdateLoading(String msg) { + rlParam.setAlpha(0.3f); + rlProgress.setVisibility(View.VISIBLE); + TextView progressText = findViewById(R.id.tv_loading); + progressText.setText(msg); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + } + + public void hideParamUpdateLoading() { + rlParam.setAlpha(1); + rlProgress.setVisibility(View.GONE); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + } } diff --git a/app/src/main/java/com/espressif/ui/activities/EspMainActivity.java b/app/src/main/java/com/espressif/ui/activities/EspMainActivity.java index 52dc2bc..5780cf4 100644 --- a/app/src/main/java/com/espressif/ui/activities/EspMainActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/EspMainActivity.java @@ -26,24 +26,25 @@ import android.text.TextUtils; import android.util.Log; import android.view.HapticFeedbackConstants; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; -import android.view.View; -import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.viewpager.widget.ViewPager; import com.espressif.AppConstants; import com.espressif.EspApplication; -import com.espressif.db.EspDatabase; import com.espressif.JsonDataParser; import com.espressif.cloudapi.ApiManager; import com.espressif.cloudapi.ApiResponseListener; +import com.espressif.db.EspDatabase; import com.espressif.mdns.mDNSApiManager; import com.espressif.mdns.mDNSDevice; import com.espressif.mdns.mDNSManager; @@ -54,11 +55,11 @@ import com.espressif.ui.adapters.HomeScreenPagerAdapter; import com.espressif.ui.fragments.DevicesFragment; import com.espressif.ui.fragments.SchedulesFragment; -import com.espressif.ui.models.Device; +import com.espressif.ui.fragments.UserProfileFragment; import com.espressif.ui.models.EspNode; import com.espressif.ui.models.Group; -import com.espressif.ui.models.Schedule; import com.espressif.ui.models.UpdateEvent; +import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.snackbar.Snackbar; @@ -69,9 +70,6 @@ import org.json.JSONObject; import java.util.ArrayList; -import java.util.Map; - -import static com.espressif.EspApplication.GetDataStatus; public class EspMainActivity extends AppCompatActivity { @@ -79,22 +77,21 @@ public class EspMainActivity extends AppCompatActivity { private static final int REQUEST_LOCATION = 1; + private CollapsingToolbarLayout collapsingToolbarLayout; + private Toolbar appbar; private BottomNavigationView bottomNavigationView; private ViewPager viewPager; - private TextView tvTitle; - private ImageView ivAddDevice, ivUserProfile; private Fragment deviceFragment; private Fragment scheduleFragment; private MenuItem prevMenuItem; private HomeScreenPagerAdapter pagerAdapter; private Snackbar snackbar; + private MenuItem menuAdd; private ApiManager apiManager; private EspApplication espApp; private ArrayList updateListenerArrayList = new ArrayList<>(); - private ArrayList devices; - private ArrayList schedules; private mDNSManager mdnsManager; @@ -104,41 +101,24 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_esp_main); - devices = new ArrayList<>(); - schedules = new ArrayList<>(); espApp = (EspApplication) getApplicationContext(); - apiManager = ApiManager.getInstance(getApplicationContext()); + snackbar = Snackbar.make(findViewById(R.id.frame_container), R.string.msg_no_internet, Snackbar.LENGTH_INDEFINITE); if (BuildConfig.isLocalControlSupported) { mdnsManager = mDNSManager.getInstance(getApplicationContext(), AppConstants.MDNS_SERVICE_TYPE, listener); mdnsManager.initializeNsd(); } initViews(); - - snackbar = Snackbar.make(findViewById(R.id.frame_container), R.string.msg_fetch_data, Snackbar.LENGTH_INDEFINITE); - snackbar.show(); - loadDataFromLocalStorage(); - - if (BuildConfig.isLocalControlSupported) { - startLocalDeviceDiscovery(); - } - getSupportedVersions(); } @Override protected void onResume() { super.onResume(); - EventBus.getDefault().register(this); - - if (!espApp.getCurrentStatus().equals(GetDataStatus.FETCHING_DATA)) { - getNodes(); - } else { - updateUi(); - } + getNodes(); } @Override @@ -149,7 +129,6 @@ protected void onPause() { @Override protected void onDestroy() { - if (updateListenerArrayList != null) { updateListenerArrayList.clear(); } @@ -159,6 +138,54 @@ protected void onDestroy() { super.onDestroy(); } + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_toolbar, menu); + menuAdd = menu.findItem(R.id.action_add); + + if (espApp.nodeMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + + case R.id.action_add: + addDeviceBtnCLick(); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + + private void addDeviceBtnCLick() { + + Vibrator vib = (Vibrator) getSystemService(VIBRATOR_SERVICE); + vib.vibrate(HapticFeedbackConstants.VIRTUAL_KEY); + + if (viewPager.getCurrentItem() == 0) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + + if (!isLocationEnabled()) { + askForLocation(); + return; + } + } + goToAddDeviceActivity(); + } else { + goToAddScheduleActivity(); + } + } + @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(UpdateEvent event) { @@ -171,10 +198,21 @@ public void onEvent(UpdateEvent event) { refreshDeviceList(); break; - case EVENT_DEVICE_STATUS_UPDATE: - if (!espApp.getCurrentStatus().equals(GetDataStatus.FETCHING_DATA)) { - updateUi(); + case EVENT_STATE_CHANGE_UPDATE: + Bundle data = event.getData(); + if (data != null) { + String errMsg = data.getString(AppConstants.KEY_ERROR_MSG); + if (!TextUtils.isEmpty(errMsg)) { + Toast.makeText(EspMainActivity.this, errMsg, Toast.LENGTH_SHORT).show(); + } } + updateUi(); + break; + + case EVENT_DEVICE_STATUS_UPDATE: +// if (!espApp.getCurrentStatus().equals(GetDataStatus.FETCHING_DATA)) { +// updateUi(); +// } break; } } @@ -197,29 +235,6 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { } } - View.OnClickListener addDeviceBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - Vibrator vib = (Vibrator) getSystemService(VIBRATOR_SERVICE); - vib.vibrate(HapticFeedbackConstants.VIRTUAL_KEY); - - if (tvTitle.getText().toString().equals(getString(R.string.title_activity_devices))) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - - if (!isLocationEnabled()) { - askForLocation(); - return; - } - } - goToAddDeviceActivity(); - } else { - goToAddScheduleActivity(); - } - } - }; - BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @Override @@ -228,14 +243,31 @@ public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) { switch (menuItem.getItemId()) { case R.id.action_devices: - tvTitle.setText(pagerAdapter.getPageTitle(0)); + collapsingToolbarLayout.setTitle(pagerAdapter.getPageTitle(0)); viewPager.setCurrentItem(0); + if (espApp.nodeMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } updateUi(); return true; case R.id.action_schedules: - tvTitle.setText(pagerAdapter.getPageTitle(1)); + collapsingToolbarLayout.setTitle(pagerAdapter.getPageTitle(1)); viewPager.setCurrentItem(1); + if (espApp.scheduleMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + updateUi(); + return true; + + case R.id.action_user: + collapsingToolbarLayout.setTitle(pagerAdapter.getPageTitle(2)); + viewPager.setCurrentItem(2); + menuAdd.setVisible(false); updateUi(); return true; } @@ -252,36 +284,46 @@ public void removeUpdateListener(UiUpdateListener updateListener) { } public void refreshDeviceList() { - - espApp.setCurrentStatus(GetDataStatus.DATA_REFRESHING); getNodes(); } - private void initViews() { + public void updateActionBar() { - tvTitle = findViewById(R.id.esp_toolbar_title); - ivAddDevice = findViewById(R.id.btn_add_device); - ivUserProfile = findViewById(R.id.btn_user_profile); - bottomNavigationView = findViewById(R.id.bottom_navigation_view); - viewPager = findViewById(R.id.view_pager); - - tvTitle.setText(R.string.title_activity_devices); - ivAddDevice.setOnClickListener(addDeviceBtnClickListener); + if (menuAdd != null) { + switch (viewPager.getCurrentItem()) { + case 0: + if (espApp.nodeMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + break; - ivUserProfile.setOnClickListener(new View.OnClickListener() { + case 1: + if (espApp.scheduleMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + break; - @Override - public void onClick(View v) { - startActivity(new Intent(EspMainActivity.this, UserProfileActivity.class)); + default: + menuAdd.setVisible(false); + break; } - }); + } + } - if (BuildConfig.isScheduleSupported) { + private void initViews() { - bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener); - } else { - bottomNavigationView.setVisibility(View.GONE); - } + collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar_layout); + collapsingToolbarLayout.setTitle(getResources().getString(R.string.devices_title)); + appbar = findViewById(R.id.appbar); + setSupportActionBar(appbar); + + bottomNavigationView = findViewById(R.id.bottom_navigation_view); + viewPager = findViewById(R.id.view_pager); + bottomNavigationView.setOnNavigationItemSelectedListener(navigationItemSelectedListener); setupViewPager(); } @@ -312,7 +354,29 @@ public void onPageSelected(int position) { } bottomNavigationView.getMenu().getItem(position).setChecked(true); prevMenuItem = bottomNavigationView.getMenu().getItem(position); - tvTitle.setText(pagerAdapter.getPageTitle(position)); + collapsingToolbarLayout.setTitle(pagerAdapter.getPageTitle(position)); + + switch (position) { + case 0: + if (espApp.nodeMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + break; + + case 1: + if (espApp.scheduleMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); + } + break; + + case 2: + menuAdd.setVisible(false); + break; + } updateUi(); } @@ -321,139 +385,63 @@ public void onPageScrollStateChanged(int state) { } }); } + pagerAdapter.addFragment(new UserProfileFragment()); viewPager.setAdapter(pagerAdapter); } - private void loadDataFromLocalStorage() { - - EspDatabase espDatabase = EspDatabase.getInstance(getApplicationContext()); - ArrayList nodeList = (ArrayList) espDatabase.getNodeDao().getNodesFromStorage(); - Log.d(TAG, "Node list from Local storage : " + nodeList.size()); - devices.clear(); - - for (int nodeIndex = 0; nodeIndex < nodeList.size(); nodeIndex++) { - - EspNode node = nodeList.get(nodeIndex); - - if (node != null) { - - String configData = node.getConfigData(); - String paramData = node.getParamData(); - - try { - node = JsonDataParser.setNodeConfig(node, new JSONObject(configData)); - JSONObject paramsJson = new JSONObject(paramData); - JsonDataParser.setAllParams(espApp, node, paramsJson); - espApp.nodeMap.put(node.getNodeId(), node); - - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - - // Set all devices offline - for (Map.Entry entry : espApp.nodeMap.entrySet()) { - - String key = entry.getKey(); - EspNode node = entry.getValue(); - - if (node != null) { - node.setOnline(false); - ArrayList espDevices = node.getDevices(); - devices.addAll(espDevices); - } - } - - if (BuildConfig.isNodeGroupingSupported) { - ArrayList groupList = (ArrayList) espDatabase.getGroupDao().getGroupsFromStorage(); - for (int groupIndex = 0; groupIndex < groupList.size(); groupIndex++) { - - Group group = groupList.get(groupIndex); - if (group != null) { - espApp.groupMap.put(group.getGroupId(), group); - } - } - } - Log.d(TAG, "Device list size from local storage : " + devices.size()); - } - private void updateUi() { - switch (espApp.getCurrentStatus()) { + switch (espApp.getAppState()) { - case FETCHING_DATA: - if (devices.size() > 0) { - ivAddDevice.setVisibility(View.VISIBLE); - } else { - ivAddDevice.setVisibility(View.GONE); + case NO_INTERNET: + if (snackbar == null) { + snackbar = Snackbar.make(findViewById(R.id.frame_container), R.string.msg_no_internet, Snackbar.LENGTH_INDEFINITE); } + Log.e(TAG, "Display No internet"); + snackbar.show(); break; case GET_DATA_SUCCESS: snackbar.dismiss(); - if (viewPager.getCurrentItem() == 0) { - - devices.clear(); - for (Map.Entry entry : espApp.nodeMap.entrySet()) { - - String key = entry.getKey(); - EspNode node = entry.getValue(); - - if (node != null) { - ArrayList espDevices = node.getDevices(); - devices.addAll(espDevices); + if (viewPager.getCurrentItem() == 0) { + if (menuAdd != null) { + if (espApp.nodeMap.size() > 0) { + menuAdd.setVisible(true); + } else { + menuAdd.setVisible(false); } } - if (devices.size() > 0) { - ivAddDevice.setVisibility(View.VISIBLE); - } else { - ivAddDevice.setVisibility(View.GONE); - } - } else if (viewPager.getCurrentItem() == 1) { - - schedules.clear(); - - for (Map.Entry entry : espApp.scheduleMap.entrySet()) { - - String key = entry.getKey(); - Schedule schedule = entry.getValue(); - - if (schedule != null) { - schedules.add(schedule); - } - } - - if (schedules.size() > 0) { - ivAddDevice.setVisibility(View.VISIBLE); + if (espApp.scheduleMap.size() > 0) { + menuAdd.setVisible(true); } else { - ivAddDevice.setVisibility(View.GONE); + menuAdd.setVisible(false); } } break; case GET_DATA_FAILED: + snackbar.dismiss(); + // TODO Display toast +// for (Map.Entry entry : espApp.nodeMap.entrySet()) { +// +// EspNode node = entry.getValue(); +// +// if (node != null && !espApp.mDNSDeviceMap.containsKey(node.getNodeId())) { +//// node.setOnline(false); +// } +// } + break; - for (Map.Entry entry : espApp.nodeMap.entrySet()) { - - EspNode node = entry.getValue(); - - if (node != null && !espApp.mDNSDeviceMap.containsKey(node.getNodeId())) { - node.setOnline(false); - } - } - - TextView tvSnackbarText = snackbar.getView().findViewById(com.google.android.material.R.id.snackbar_text); - tvSnackbarText.setText(R.string.msg_no_internet); - - if (!snackbar.isShown()) { - snackbar = Snackbar.make(findViewById(R.id.frame_container), R.string.msg_no_internet, Snackbar.LENGTH_INDEFINITE); - snackbar.show(); - } + case GETTING_DATA: + case REFRESH_DATA: break; + + case NO_USER_LOGIN: + finish(); + return; } if (updateListenerArrayList != null) { @@ -501,15 +489,19 @@ public void onSuccess(Bundle data) { } } } - getNodes(); } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Bundle data = new Bundle(); + data.putString(AppConstants.KEY_ERROR_MSG, exception.getMessage()); + espApp.changeAppState(EspApplication.AppState.GET_DATA_FAILED, data); + } - espApp.setCurrentStatus(GetDataStatus.GET_DATA_FAILED); - updateUi(); + @Override + public void onNetworkFailure(Exception exception) { + espApp.changeAppState(EspApplication.AppState.NO_INTERNET, null); } }); } @@ -521,70 +513,72 @@ private int getVersionNumber(String versionString) { return version; } - private void getNodes() { + private void loadDataFromLocalStorage() { - if (BuildConfig.isLocalControlSupported) { - startLocalDeviceDiscovery(); - } + EspDatabase espDatabase = EspDatabase.getInstance(getApplicationContext()); + ArrayList nodeList = (ArrayList) espDatabase.getNodeDao().getNodesFromStorage(); - if (apiManager.isTokenExpired()) { + for (int nodeIndex = 0; nodeIndex < nodeList.size(); nodeIndex++) { - apiManager.getNewToken(new ApiResponseListener() { + EspNode node = nodeList.get(nodeIndex); - @Override - public void onSuccess(Bundle data) { + if (node != null) { - getNodesFromCloud(); - } + String configData = node.getConfigData(); + String paramData = node.getParamData(); - @Override - public void onFailure(Exception exception) { - exception.printStackTrace(); - espApp.setCurrentStatus(GetDataStatus.GET_DATA_FAILED); - updateUi(); - } - }); + if (configData != null) { + try { + node = JsonDataParser.setNodeConfig(node, new JSONObject(configData)); + if (paramData != null) { + JSONObject paramsJson = new JSONObject(paramData); + JsonDataParser.setAllParams(espApp, node, paramsJson); + } else { + Log.e(TAG, "Param configuration is not available."); + } + espApp.nodeMap.put(node.getNodeId(), node); - } else { - getNodesFromCloud(); + } catch (JSONException e) { + e.printStackTrace(); + } + } else { + Log.e(TAG, "Node configuration is not available."); + } + } } - } - private void getNodesFromCloud() { - - apiManager.getNodes(apiResponseListener); - } - - private ApiResponseListener apiResponseListener = new ApiResponseListener() { - - @Override - public void onSuccess(Bundle data) { - - if (BuildConfig.isNodeGroupingSupported) { - apiManager.getUserGroups(null, new ApiResponseListener() { + // Set all devices offline +// for (Map.Entry entry : espApp.nodeMap.entrySet()) { +// +// String key = entry.getKey(); +// EspNode node = entry.getValue(); +// +// if (node != null) { +// node.setOnline(false); +// ArrayList espDevices = node.getDevices(); +// devices.addAll(espDevices); +// } +// } - @Override - public void onSuccess(Bundle data) { - updateUi(); - } + if (BuildConfig.isNodeGroupingSupported) { + ArrayList groupList = (ArrayList) espDatabase.getGroupDao().getGroupsFromStorage(); + for (int groupIndex = 0; groupIndex < groupList.size(); groupIndex++) { - @Override - public void onFailure(Exception exception) { - exception.printStackTrace(); - updateUi(); - } - }); - } else { - updateUi(); + Group group = groupList.get(groupIndex); + if (group != null) { + espApp.groupMap.put(group.getGroupId(), group); + } } } + Log.d(TAG, "Node list size from local storage : " + espApp.nodeMap.size()); + } - @Override - public void onFailure(Exception exception) { - exception.printStackTrace(); - updateUi(); + private void getNodes() { + if (BuildConfig.isLocalControlSupported) { + startLocalDeviceDiscovery(); } - }; + espApp.refreshData(); + } private void goToAddDeviceActivity() { @@ -716,7 +710,6 @@ public void onClick(DialogInterface dialog, int which) { } } }); - builder.show(); } @@ -886,7 +879,12 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + // Nothing to do + } + + @Override + public void onNetworkFailure(Exception exception) { // Nothing to do } }); @@ -894,7 +892,12 @@ public void onFailure(Exception exception) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + // Nothing to do + } + + @Override + public void onNetworkFailure(Exception exception) { // Nothing to do } }); diff --git a/app/src/main/java/com/espressif/ui/activities/GroupDetailActivity.java b/app/src/main/java/com/espressif/ui/activities/GroupDetailActivity.java index b73800f..aecffaf 100644 --- a/app/src/main/java/com/espressif/ui/activities/GroupDetailActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/GroupDetailActivity.java @@ -50,6 +50,7 @@ import com.espressif.ui.models.Device; import com.espressif.ui.models.EspNode; import com.espressif.ui.models.Group; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -61,22 +62,12 @@ public class GroupDetailActivity extends AppCompatActivity { private static final int REQ_ADD_NODE_SELECTION = 10; private static final int REQ_EDIT_NODE_SELECTION = 11; - private EspApplication espApp; - private ApiManager apiManager; - - private TextView tvTitle, tvBack, tvCancel; - + private MaterialToolbar toolbar; private TextView tvGroupName; private RelativeLayout rlGroupName, rlAddDevice, rlDevices; - private String groupName; private CardView btnNext; private TextView txtNextBtn; private RecyclerView rvDevices, rvNodes; - private ArrayList nodes = new ArrayList<>(); - private ArrayList devices = new ArrayList<>(); - private GroupDeviceAdapter deviceAdapter; - private GroupNodeAdapter nodeAdapter; - private Group group; private RelativeLayout layoutProgress; private ConstraintLayout layoutGroupDetail; @@ -85,6 +76,16 @@ public class GroupDetailActivity extends AppCompatActivity { private ImageView removeGroupImage; private ContentLoadingProgressBar progressBar; + private GroupDeviceAdapter deviceAdapter; + private GroupNodeAdapter nodeAdapter; + + private EspApplication espApp; + private ApiManager apiManager; + private Group group; + private String groupName; + private ArrayList nodes = new ArrayList<>(); + private ArrayList devices = new ArrayList<>(); + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -97,14 +98,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { updateUI(); } - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - finish(); - } - }; - private View.OnClickListener nextBtnClickListener = new View.OnClickListener() { @Override @@ -166,14 +159,18 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_create_group); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.GONE); - tvBack.setText(R.string.btn_cancel); + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_create_group); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); layoutGroupDetail = findViewById(R.id.layout_group_detail); layoutProgress = findViewById(R.id.layout_progress); @@ -195,7 +192,6 @@ private void initViews() { progressBar = btnRemoveGroup.findViewById(R.id.progress_indicator); btnRemoveGroup.setVisibility(View.GONE); - tvBack.setOnClickListener(backButtonClickListener); rlAddDevice.setOnClickListener(addDeviceClickListener); rlGroupName.setOnClickListener(groupNameClickListener); btnRemoveGroup.setOnClickListener(removeGroupBtnClickListener); @@ -217,14 +213,14 @@ private void initViews() { private void updateUI() { if (group == null) { - tvTitle.setText(R.string.title_activity_create_group); + getSupportActionBar().setTitle(R.string.title_activity_create_group); rlAddDevice.setVisibility(View.GONE); rlDevices.setVisibility(View.GONE); btnRemoveGroup.setVisibility(View.GONE); btnNext.setVisibility(View.VISIBLE); setEnableNextBtn(false); } else { - tvTitle.setText(R.string.title_activity_edit_group); + getSupportActionBar().setTitle(R.string.title_activity_edit_group); groupName = group.getGroupName(); tvGroupName.setText(groupName); rlAddDevice.setVisibility(View.VISIBLE); @@ -300,7 +296,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + hideLoading(); + if (exception instanceof CloudException) { + Toast.makeText(GroupDetailActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GroupDetailActivity.this, R.string.error_group_name_update, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); if (exception instanceof CloudException) { Toast.makeText(GroupDetailActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); @@ -367,7 +373,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + hideLoading(); + if (exception instanceof CloudException) { + Toast.makeText(GroupDetailActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GroupDetailActivity.this, R.string.error_group_device_remove, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); if (exception instanceof CloudException) { Toast.makeText(GroupDetailActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); @@ -391,7 +407,18 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + exception.printStackTrace(); + hideRemoveGroupLoading(); + if (exception instanceof CloudException) { + Toast.makeText(GroupDetailActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GroupDetailActivity.this, R.string.error_group_remove, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { exception.printStackTrace(); hideRemoveGroupLoading(); if (exception instanceof CloudException) { @@ -407,7 +434,7 @@ private void confirmRemoveGroup() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.dialog_title_remove); - builder.setMessage(R.string.dialog_msg_remove_group); + builder.setMessage(R.string.dialog_msg_confirmation); // Set up the buttons builder.setPositiveButton(R.string.btn_confirm, new DialogInterface.OnClickListener() { diff --git a/app/src/main/java/com/espressif/ui/activities/GroupNodeSelectionActivity.java b/app/src/main/java/com/espressif/ui/activities/GroupNodeSelectionActivity.java index 12f7c01..056b59c 100644 --- a/app/src/main/java/com/espressif/ui/activities/GroupNodeSelectionActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/GroupNodeSelectionActivity.java @@ -15,6 +15,8 @@ package com.espressif.ui.activities; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.RelativeLayout; @@ -40,6 +42,7 @@ import com.espressif.ui.models.Device; import com.espressif.ui.models.EspNode; import com.espressif.ui.models.Group; +import com.google.android.material.appbar.MaterialToolbar; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -48,9 +51,6 @@ public class GroupNodeSelectionActivity extends AppCompatActivity { - private final String TAG = "GroupNodeSelection"; - - private TextView tvTitle, tvBack, tvCancel; private String groupName; private ArrayList nodes = new ArrayList<>(); private ArrayList devices = new ArrayList<>(); @@ -71,35 +71,41 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { initViews(); } - private View.OnClickListener cancelBtnClickListener = new View.OnClickListener() { + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_done).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } - @Override - public void onClick(View v) { - finish(); - } - }; + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { - private View.OnClickListener doneBtnClickListener = new View.OnClickListener() { + case 1: + saveSelectedDevices(); + return true; - @Override - public void onClick(View v) { - saveSelectedDevices(); + default: + return super.onOptionsItemSelected(item); } - }; + } private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_select_devices); - tvBack.setText(R.string.btn_back); - tvCancel.setText(R.string.btn_done); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.VISIBLE); - tvBack.setOnClickListener(cancelBtnClickListener); - tvCancel.setOnClickListener(doneBtnClickListener); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_select_devices); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); rvDevices = findViewById(R.id.rv_device_list); rvNodes = findViewById(R.id.rv_node_list); @@ -192,7 +198,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + hideLoading(); + if (exception instanceof CloudException) { + Toast.makeText(GroupNodeSelectionActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GroupNodeSelectionActivity.this, R.string.error_group_create, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); if (exception instanceof CloudException) { Toast.makeText(GroupNodeSelectionActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); @@ -214,7 +230,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + hideLoading(); + if (exception instanceof CloudException) { + Toast.makeText(GroupNodeSelectionActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GroupNodeSelectionActivity.this, R.string.error_group_update, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); if (exception instanceof CloudException) { Toast.makeText(GroupNodeSelectionActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/com/espressif/ui/activities/GroupsActivity.java b/app/src/main/java/com/espressif/ui/activities/GroupsActivity.java index bdd1261..d459946 100644 --- a/app/src/main/java/com/espressif/ui/activities/GroupsActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/GroupsActivity.java @@ -14,12 +14,11 @@ package com.espressif.ui.activities; -import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.os.Vibrator; import android.util.Log; -import android.view.HapticFeedbackConstants; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; @@ -37,6 +36,7 @@ import com.espressif.rainmaker.R; import com.espressif.ui.adapters.GroupAdapter; import com.espressif.ui.models.Group; +import com.google.android.material.appbar.MaterialToolbar; import java.util.ArrayList; import java.util.Collections; @@ -47,13 +47,11 @@ public class GroupsActivity extends AppCompatActivity { private static final String TAG = GroupsActivity.class.getSimpleName(); - private TextView tvTitle, tvBack, tvCancel; - private RecyclerView rvGroups; private TextView tvNoGroups; private RelativeLayout rlNoGroups; private SwipeRefreshLayout swipeRefreshLayout; - private ImageView ivNoGroups, ivAddGroup; + private ImageView ivNoGroups; private EspApplication espApp; private GroupAdapter groupAdapter; @@ -82,38 +80,41 @@ protected void onResume() { getGroups(); } - View.OnClickListener addGroupBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_add).setIcon(R.drawable.ic_menu_add).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } - Vibrator vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); - vib.vibrate(HapticFeedbackConstants.VIRTUAL_KEY); - goToGroupDetailActivity(); - } - }; + @Override + public boolean onOptionsItemSelected(MenuItem item) { - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { + switch (item.getItemId()) { - @Override - public void onClick(View v) { + case 1: + goToGroupDetailActivity(); + return true; - finish(); + default: + return super.onOptionsItemSelected(item); } - }; + } private void init() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - ivAddGroup = findViewById(R.id.btn_add); - ivAddGroup.setVisibility(View.VISIBLE); - - tvTitle.setText(R.string.title_activity_manage_groups); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.GONE); - tvBack.setText(R.string.btn_back); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_manage_groups); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); rlNoGroups = findViewById(R.id.rl_no_group); tvNoGroups = findViewById(R.id.tv_no_group); @@ -121,9 +122,6 @@ private void init() { rvGroups = findViewById(R.id.rv_group_list); swipeRefreshLayout = findViewById(R.id.swipe_container); - tvBack.setOnClickListener(backButtonClickListener); - ivAddGroup.setOnClickListener(addGroupBtnClickListener); - groupAdapter = new GroupAdapter(this, groups); rvGroups.setLayoutManager(new LinearLayoutManager(this)); rvGroups.setAdapter(groupAdapter); @@ -186,28 +184,6 @@ private void refreshGroupList() { private void getGroups() { - ApiManager apiManager = ApiManager.getInstance(this); - if (apiManager.isTokenExpired()) { - - apiManager.getNewToken(new ApiResponseListener() { - - @Override - public void onSuccess(Bundle data) { - getGroupsFromCloud(); - } - - @Override - public void onFailure(Exception exception) { - exception.printStackTrace(); - } - }); - - } else { - getGroupsFromCloud(); - } - } - - private void getGroupsFromCloud() { ApiManager apiManager = ApiManager.getInstance(this); apiManager.getUserGroups(null, new ApiResponseListener() { @@ -218,7 +194,13 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception e) { + e.printStackTrace(); + swipeRefreshLayout.setRefreshing(false); + } + + @Override + public void onNetworkFailure(Exception exception) { exception.printStackTrace(); swipeRefreshLayout.setRefreshing(false); } diff --git a/app/src/main/java/com/espressif/ui/activities/MainActivity.java b/app/src/main/java/com/espressif/ui/activities/MainActivity.java index c9d9acd..a253116 100755 --- a/app/src/main/java/com/espressif/ui/activities/MainActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/MainActivity.java @@ -39,6 +39,7 @@ import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.VerificationHandler; import com.amazonaws.services.cognitoidentityprovider.model.UserNotConfirmedException; import com.espressif.AppConstants; +import com.espressif.EspApplication; import com.espressif.cloudapi.ApiManager; import com.espressif.rainmaker.R; import com.espressif.ui.adapters.TabsPagerAdapter; @@ -112,7 +113,7 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten } public void launchHomeScreen() { - + ((EspApplication) getApplicationContext()).changeAppState(EspApplication.AppState.GETTING_DATA, null); Intent espMainActivity = new Intent(getApplicationContext(), EspMainActivity.class); espMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(espMainActivity); @@ -120,7 +121,6 @@ public void launchHomeScreen() { } private void launchSignUpConfirmActivity(CognitoUserCodeDeliveryDetails cognitoUserCodeDeliveryDetails) { - Intent intent = new Intent(this, SignUpConfirmActivity.class); intent.putExtra("name", email); intent.putExtra("password", password); diff --git a/app/src/main/java/com/espressif/ui/activities/NodeDetailsActivity.java b/app/src/main/java/com/espressif/ui/activities/NodeDetailsActivity.java index 25def18..50dab82 100644 --- a/app/src/main/java/com/espressif/ui/activities/NodeDetailsActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/NodeDetailsActivity.java @@ -17,10 +17,11 @@ import android.content.DialogInterface; import android.os.Bundle; import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.WindowManager; import android.widget.RelativeLayout; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; @@ -41,13 +42,14 @@ import com.espressif.ui.adapters.NodeDetailsAdapter; import com.espressif.ui.models.EspNode; import com.espressif.ui.models.Param; +import com.espressif.ui.models.Service; import com.espressif.ui.models.SharingRequest; +import com.google.android.material.appbar.MaterialToolbar; import java.util.ArrayList; public class NodeDetailsActivity extends AppCompatActivity { - private TextView tvTitle, tvBack, tvCancel; private RecyclerView nodeInfoRecyclerView; private ContentLoadingProgressBar progressBarNodeDetails; private ConstraintLayout layoutNodeDetails; @@ -85,23 +87,26 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } } - private View.OnClickListener removeDeviceBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_remove).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } - confirmForRemoveNode(); - } - }; + @Override + public boolean onOptionsItemSelected(MenuItem item) { - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { + switch (item.getItemId()) { - @Override - public void onClick(View v) { + case 1: + confirmForRemoveNode(); + return true; - finish(); + default: + return super.onOptionsItemSelected(item); } - }; + } public void addPendingRequest(SharingRequest request) { pendingRequests.add(request); @@ -115,14 +120,18 @@ public void clearPendingRequest() { private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_node_details); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.VISIBLE); - tvCancel.setText(R.string.btn_remove); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_node_details); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); nodeInfoRecyclerView = findViewById(R.id.rv_node_details_list); progressBarNodeDetails = findViewById(R.id.progress_get_node_details); @@ -135,28 +144,40 @@ private void initViews() { nodeDetailsAdapter = new NodeDetailsAdapter(this, nodeInfoList, nodeInfoValueList, node, pendingRequests); nodeInfoRecyclerView.setAdapter(nodeDetailsAdapter); - - tvBack.setOnClickListener(backButtonClickListener); - tvCancel.setOnClickListener(removeDeviceBtnClickListener); } private void setNodeInfo() { nodeInfoList.clear(); nodeInfoValueList.clear(); - nodeInfoList.add(getString(R.string.node_id)); nodeInfoValueList.add(node.getNodeId()); - nodeInfoList.add(getString(R.string.node_name)); - nodeInfoValueList.add(node.getNodeName()); - nodeInfoList.add(getString(R.string.node_type)); nodeInfoValueList.add(node.getNodeType()); nodeInfoList.add(getString(R.string.node_fw_version)); nodeInfoValueList.add(node.getFwVersion()); + // Display time zone of device. + ArrayList services = node.getServices(); + Service tzService = null; + + for (int i = 0; i < services.size(); i++) { + + Service s = services.get(i); + if (!TextUtils.isEmpty(s.getType()) && s.getType().equals(AppConstants.SERVICE_TYPE_TIME)) { + tzService = s; + break; + } + } + + if (tzService != null) { + nodeInfoList.add(getString(R.string.node_timezone)); + nodeInfoValueList.add(getString(R.string.node_timezone));// TODO + } + + // Attributes ArrayList attributes = node.getAttributes(); if (attributes != null && attributes.size() > 0) { @@ -167,6 +188,7 @@ private void setNodeInfo() { } } + // Sharing information if (BuildConfig.isNodeSharingSupported) { boolean shouldDisplaySharingView = true; @@ -218,7 +240,13 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception e) { + setNodeInfo(); + progressBarNodeDetails.setVisibility(View.GONE); + } + + @Override + public void onNetworkFailure(Exception exception) { setNodeInfo(); progressBarNodeDetails.setVisibility(View.GONE); } @@ -248,7 +276,13 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception e) { + setNodeInfo(); + progressBarNodeDetails.setVisibility(View.GONE); + } + + @Override + public void onNetworkFailure(Exception exception) { setNodeInfo(); progressBarNodeDetails.setVisibility(View.GONE); } @@ -316,7 +350,18 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + hideLoading(); + exception.printStackTrace(); + if (exception instanceof CloudException) { + Toast.makeText(NodeDetailsActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(NodeDetailsActivity.this, R.string.error_delete_node, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { hideLoading(); exception.printStackTrace(); if (exception instanceof CloudException) { diff --git a/app/src/main/java/com/espressif/ui/activities/ProofOfPossessionActivity.java b/app/src/main/java/com/espressif/ui/activities/ProofOfPossessionActivity.java index fd80065..94e9d8a 100644 --- a/app/src/main/java/com/espressif/ui/activities/ProofOfPossessionActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/ProofOfPossessionActivity.java @@ -34,6 +34,7 @@ import com.espressif.provisioning.ESPProvisionManager; import com.espressif.rainmaker.BuildConfig; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import org.greenrobot.eventbus.EventBus; @@ -49,7 +50,6 @@ public class ProofOfPossessionActivity extends AppCompatActivity { private static final String TAG = ProofOfPossessionActivity.class.getSimpleName(); - private TextView tvTitle, tvBack, tvCancel; private MaterialCardView btnNext; private TextView txtNextBtn; @@ -137,32 +137,27 @@ public void onClick(View v) { } }; - private View.OnClickListener cancelBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { + private void initViews() { - if (provisionManager.getEspDevice() != null) { - provisionManager.getEspDevice().disconnectDevice(); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_pop); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } + finish(); } - finish(); - } - }; - - private void initViews() { + }); - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); tvPopInstruction = findViewById(R.id.tv_pop); etPop = findViewById(R.id.et_pop); - tvTitle.setText(R.string.title_activity_pop); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); - - tvCancel.setOnClickListener(cancelBtnClickListener); - btnNext = findViewById(R.id.btn_next); txtNextBtn = findViewById(R.id.text_btn); @@ -217,6 +212,7 @@ private void nextBtnClick() { private void goToClaimingActivity() { Intent claimingIntent = new Intent(getApplicationContext(), ClaimingActivity.class); + claimingIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(claimingIntent); finish(); } @@ -224,6 +220,7 @@ private void goToClaimingActivity() { private void goToWiFiScanListActivity() { Intent wifiListIntent = new Intent(getApplicationContext(), WiFiScanActivity.class); + wifiListIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiListIntent); finish(); } @@ -231,6 +228,7 @@ private void goToWiFiScanListActivity() { private void goToWiFiConfigActivity() { Intent wifiConfigIntent = new Intent(getApplicationContext(), WiFiConfigActivity.class); + wifiConfigIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiConfigIntent); finish(); } diff --git a/app/src/main/java/com/espressif/ui/activities/ProvisionActivity.java b/app/src/main/java/com/espressif/ui/activities/ProvisionActivity.java index 6da2d1e..ea04120 100644 --- a/app/src/main/java/com/espressif/ui/activities/ProvisionActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/ProvisionActivity.java @@ -43,6 +43,7 @@ import com.espressif.ui.models.Param; import com.espressif.ui.models.Service; import com.espressif.ui.models.UpdateEvent; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.google.gson.JsonObject; import com.google.protobuf.InvalidProtocolBufferException; @@ -64,7 +65,6 @@ public class ProvisionActivity extends AppCompatActivity { private static final long ADD_DEVICE_REQ_TIME = 5000; private static final long NODE_STATUS_REQ_TIME = 35000; - private TextView tvTitle, tvBack, tvCancel; private ImageView tick1, tick2, tick3, tick4, tick5; private ContentLoadingProgressBar progress1, progress2, progress3, progress4, progress5; private TextView tvErrAtStep1, tvErrAtStep2, tvErrAtStep3, tvErrAtStep4, tvErrAtStep5, tvProvError; @@ -112,6 +112,8 @@ public void onBackPressed() { protected void onDestroy() { apiManager.cancelRequestStatusPollingTask(); + handler.removeCallbacks(getNodeStatusTask); + handler.removeCallbacks(nodeStatusReqFailed); EventBus.getDefault().unregister(this); super.onDestroy(); } @@ -164,9 +166,11 @@ public void onClick(View v) { private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(false); + getSupportActionBar().setDisplayShowHomeEnabled(false); + getSupportActionBar().setTitle(R.string.title_activity_provisioning); tick1 = findViewById(R.id.iv_tick_1); tick2 = findViewById(R.id.iv_tick_2); @@ -187,10 +191,6 @@ private void initViews() { tvErrAtStep5 = findViewById(R.id.tv_prov_error_5); tvProvError = findViewById(R.id.tv_prov_error); - tvTitle.setText(R.string.title_activity_provisioning); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.GONE); - btnOk = findViewById(R.id.btn_ok); txtOkBtn = findViewById(R.id.text_btn); btnOk.findViewById(R.id.iv_arrow).setVisibility(View.GONE); @@ -245,6 +245,7 @@ private void doStep4() { private void doStep5() { Log.d(TAG, "================= Do step 5 ================="); + Log.d(TAG, "Received node id : " + receivedNodeId); tick4.setImageResource(R.drawable.ic_checkbox_on); tick4.setVisibility(View.VISIBLE); progress4.setVisibility(View.GONE); @@ -252,17 +253,23 @@ private void doStep5() { progress5.setVisibility(View.VISIBLE); handler.postDelayed(nodeStatusReqFailed, NODE_STATUS_REQ_TIME); - apiManager.getNodes(new ApiResponseListener() { + apiManager.getNodeDetails(receivedNodeId, new ApiResponseListener() { @Override public void onSuccess(Bundle data) { - Log.e(TAG, "Get nodes - success"); + Log.e(TAG, "Get node details - success"); + handler.postDelayed(getNodeStatusTask, 1000); + } + + @Override + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Get node details - failure"); handler.postDelayed(getNodeStatusTask, 1000); } @Override - public void onFailure(Exception exception) { - Log.e(TAG, "Get nodes - failure"); + public void onNetworkFailure(Exception exception) { + Log.e(TAG, "Get node details - failure"); handler.postDelayed(getNodeStatusTask, 1000); } }); @@ -493,6 +500,7 @@ public void run() { private void addDeviceToCloud(final ApiResponseListener responseListener) { + Log.d(TAG, "Add device to cloud, count : " + addDeviceReqCount); apiManager.addNode(receivedNodeId, secretKey, new ApiResponseListener() { @Override @@ -501,9 +509,15 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + exception.printStackTrace(); + responseListener.onNetworkFailure(exception); + } + + @Override + public void onNetworkFailure(Exception exception) { exception.printStackTrace(); - responseListener.onFailure(exception); + responseListener.onNetworkFailure(exception); } }); } @@ -530,7 +544,31 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + if (addDeviceReqCount == 7) { + + runOnUiThread(new Runnable() { + + @Override + public void run() { + + tick3.setImageResource(R.drawable.ic_error); + tick3.setVisibility(View.VISIBLE); + progress3.setVisibility(View.GONE); + tvErrAtStep3.setVisibility(View.VISIBLE); + tvErrAtStep3.setText(R.string.error_prov_step_3); + tvProvError.setVisibility(View.VISIBLE); + hideLoading(); + } + }); + } else { + handler.postDelayed(addDeviceTask, ADD_DEVICE_REQ_TIME); + } + } + + @Override + public void onNetworkFailure(Exception exception) { if (addDeviceReqCount == 7) { @@ -623,7 +661,16 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Log.e(TAG, "Failed to send time zone value"); + handler.removeCallbacks(getNodeStatusTask); + tick5.setImageResource(R.drawable.ic_alert); + tick5.setVisibility(View.VISIBLE); + progress5.setVisibility(View.GONE); + } + + @Override + public void onNetworkFailure(Exception exception) { Log.e(TAG, "Failed to send time zone value"); handler.removeCallbacks(getNodeStatusTask); tick5.setImageResource(R.drawable.ic_alert); @@ -647,7 +694,13 @@ public void onFailure(Exception exception) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + handler.removeCallbacks(getNodeStatusTask); + handler.postDelayed(getNodeStatusTask, 2000); + } + + @Override + public void onNetworkFailure(Exception exception) { handler.removeCallbacks(getNodeStatusTask); handler.postDelayed(getNodeStatusTask, 2000); } diff --git a/app/src/main/java/com/espressif/ui/activities/ProvisionLanding.java b/app/src/main/java/com/espressif/ui/activities/ProvisionLanding.java index 067a44f..82d0b81 100644 --- a/app/src/main/java/com/espressif/ui/activities/ProvisionLanding.java +++ b/app/src/main/java/com/espressif/ui/activities/ProvisionLanding.java @@ -24,7 +24,6 @@ import android.text.TextUtils; import android.util.Log; import android.view.View; -import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; @@ -38,6 +37,7 @@ import com.espressif.provisioning.ESPConstants; import com.espressif.provisioning.ESPProvisionManager; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import org.greenrobot.eventbus.EventBus; @@ -56,10 +56,8 @@ public class ProvisionLanding extends AppCompatActivity { private static final int REQUEST_FINE_LOCATION = 10; private static final int WIFI_SETTINGS_ACTIVITY_REQUEST = 11; - private TextView tvTitle, tvBack, tvCancel; private MaterialCardView btnConnect; private TextView txtConnectBtn; - private ImageView arrowImage; private TextView tvConnectDeviceInstruction, tvDeviceName; private ContentLoadingProgressBar progressBar; @@ -134,7 +132,6 @@ public void onEvent(DeviceConnectionEvent event) { btnConnect.setAlpha(1f); txtConnectBtn.setText(R.string.btn_connect); progressBar.setVisibility(View.GONE); - arrowImage.setVisibility(View.VISIBLE); checkDeviceCapabilities(); break; @@ -145,7 +142,6 @@ public void onEvent(DeviceConnectionEvent event) { btnConnect.setAlpha(1f); txtConnectBtn.setText(R.string.btn_connect); progressBar.setVisibility(View.GONE); - arrowImage.setVisibility(View.VISIBLE); Toast.makeText(this, R.string.error_device_connect_failed, Toast.LENGTH_SHORT).show(); break; } @@ -166,7 +162,6 @@ private void connectDevice() { btnConnect.setAlpha(0.5f); txtConnectBtn.setText(R.string.btn_connecting); progressBar.setVisibility(View.VISIBLE); - arrowImage.setVisibility(View.GONE); if (ActivityCompat.checkSelfPermission(ProvisionLanding.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { @@ -177,33 +172,28 @@ private void connectDevice() { } } - private View.OnClickListener cancelButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - if (provisionManager.getEspDevice() != null) { - provisionManager.getEspDevice().disconnectDevice(); - } - finish(); - } - }; - private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_connect_device); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { - tvTitle.setText(R.string.title_activity_connect_device); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); - - tvCancel.setOnClickListener(cancelButtonClickListener); + @Override + public void onClick(View v) { + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } + finish(); + } + }); btnConnect = findViewById(R.id.btn_connect); txtConnectBtn = findViewById(R.id.text_btn); - arrowImage = findViewById(R.id.iv_arrow); + findViewById(R.id.iv_arrow).setVisibility(View.GONE); progressBar = findViewById(R.id.progress_indicator); tvConnectDeviceInstruction = findViewById(R.id.tv_connect_device_instruction); tvDeviceName = findViewById(R.id.tv_device_name); @@ -294,6 +284,7 @@ private void goToPopActivity() { finish(); Intent popIntent = new Intent(getApplicationContext(), ProofOfPossessionActivity.class); + popIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(popIntent); } @@ -301,6 +292,7 @@ private void goToWifiScanListActivity() { finish(); Intent wifiListIntent = new Intent(getApplicationContext(), WiFiScanActivity.class); + wifiListIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiListIntent); } @@ -308,6 +300,7 @@ private void goToWiFiConfigActivity() { finish(); Intent wifiConfigIntent = new Intent(getApplicationContext(), WiFiConfigActivity.class); + wifiConfigIntent.putExtra(AppConstants.KEY_SSID, getIntent().getStringExtra(AppConstants.KEY_SSID)); startActivity(wifiConfigIntent); } @@ -322,16 +315,11 @@ private boolean hasPermissions() { } private boolean hasLocationPermissions() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - } - return true; + return checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; } private void requestLocationPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); - } + requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); } private void alertForClaimingNotSupported() { diff --git a/app/src/main/java/com/espressif/ui/activities/ScheduleActionsActivity.java b/app/src/main/java/com/espressif/ui/activities/ScheduleActionsActivity.java index 6002585..c3a21d5 100644 --- a/app/src/main/java/com/espressif/ui/activities/ScheduleActionsActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/ScheduleActionsActivity.java @@ -16,8 +16,9 @@ import android.content.Intent; import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; -import android.widget.TextView; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -29,6 +30,7 @@ import com.espressif.rainmaker.R; import com.espressif.ui.adapters.ScheduleActionAdapter; import com.espressif.ui.models.Device; +import com.google.android.material.appbar.MaterialToolbar; import java.util.ArrayList; import java.util.Collections; @@ -40,8 +42,6 @@ public class ScheduleActionsActivity extends AppCompatActivity { private ArrayList devices; private ScheduleActionAdapter adapter; - private TextView tvTitle, tvBack, tvDone; - @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -88,18 +88,53 @@ public int compare(Device d1, Device d2) { initViews(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + menu.add(Menu.NONE, 1, Menu.NONE, R.string.btn_done).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + + case 1: + Iterator itr = devices.iterator(); + while (itr.hasNext()) { + + Device d = (Device) itr.next(); + if (d.getSelectedState() == 0) { + itr.remove(); + } + } + Intent intent = getIntent(); + intent.putParcelableArrayListExtra(AppConstants.KEY_ACTIONS, devices); + setResult(RESULT_OK, intent); + finish(); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvDone = findViewById(R.id.btn_cancel); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_actions); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { - tvTitle.setText(R.string.title_activity_actions); - tvDone.setText(R.string.btn_done); - tvBack.setVisibility(View.VISIBLE); - tvDone.setVisibility(View.VISIBLE); - tvBack.setOnClickListener(backBtnClickListener); - tvDone.setOnClickListener(doneBtnClickListener); + @Override + public void onClick(View v) { + finish(); + } + }); RecyclerView recyclerView = findViewById(R.id.rv_device_schedule); ((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); @@ -109,33 +144,4 @@ private void initViews() { recyclerView.setAdapter(adapter); recyclerView.setHasFixedSize(true); } - - private View.OnClickListener backBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - finish(); - } - }; - - private View.OnClickListener doneBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - Iterator itr = devices.iterator(); - while (itr.hasNext()) { - - Device d = (Device) itr.next(); - if (d.getSelectedState() == 0) { - itr.remove(); - } - } - Intent intent = getIntent(); - intent.putParcelableArrayListExtra(AppConstants.KEY_ACTIONS, devices); - setResult(RESULT_OK, intent); - finish(); - } - }; } diff --git a/app/src/main/java/com/espressif/ui/activities/SharingRequestsActivity.java b/app/src/main/java/com/espressif/ui/activities/SharingRequestsActivity.java index 96e3dce..759e5c0 100644 --- a/app/src/main/java/com/espressif/ui/activities/SharingRequestsActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/SharingRequestsActivity.java @@ -35,6 +35,7 @@ import com.espressif.rainmaker.R; import com.espressif.ui.adapters.SharingRequestAdapter; import com.espressif.ui.models.SharingRequest; +import com.google.android.material.appbar.MaterialToolbar; import java.util.ArrayList; @@ -42,7 +43,6 @@ public class SharingRequestsActivity extends AppCompatActivity { private static final String TAG = SharingRequestsActivity.class.getSimpleName(); - private TextView tvTitle, tvBack, tvCancel; private RecyclerView recyclerView; private TextView tvNoRequest; private RelativeLayout rlNoRequest; @@ -67,24 +67,20 @@ public void onCreate(Bundle savedInstanceState) { getSharingRequests(); } - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - finish(); - } - }; - private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_sharing_requests); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.GONE); - tvBack.setOnClickListener(backButtonClickListener); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_sharing_requests); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); progressBar = findViewById(R.id.progress_get_sharing_requests); rlNoRequest = findViewById(R.id.rl_no_request); @@ -162,7 +158,18 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + progressBar.setVisibility(View.GONE); + swipeRefreshLayout.setRefreshing(false); + if (exception instanceof CloudException) { + Toast.makeText(SharingRequestsActivity.this, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(SharingRequestsActivity.this, R.string.error_get_sharing_request, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { progressBar.setVisibility(View.GONE); swipeRefreshLayout.setRefreshing(false); if (exception instanceof CloudException) { diff --git a/app/src/main/java/com/espressif/ui/activities/SplashActivity.java b/app/src/main/java/com/espressif/ui/activities/SplashActivity.java old mode 100755 new mode 100644 index 2858871..5010ec8 --- a/app/src/main/java/com/espressif/ui/activities/SplashActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/SplashActivity.java @@ -14,55 +14,43 @@ package com.espressif.ui.activities; +import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; -import android.os.Handler; import android.text.TextUtils; import android.util.Log; -import androidx.appcompat.app.AppCompatActivity; - import com.espressif.AppConstants; +import com.espressif.EspApplication; import com.espressif.rainmaker.R; import com.espressif.ui.user_module.AppHelper; -public class SplashActivity extends AppCompatActivity { +public class SplashActivity extends Activity { private static final String TAG = SplashActivity.class.getSimpleName(); - private String email; - private String accessToken; - - private Handler handler; - private SharedPreferences sharedPreferences; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); - handler = new Handler(); - sharedPreferences = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE); - email = sharedPreferences.getString(AppConstants.KEY_EMAIL, ""); - accessToken = sharedPreferences.getString(AppConstants.KEY_ACCESS_TOKEN, ""); - - Log.d(TAG, "Email : " + email); + SharedPreferences sharedPreferences = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE); + String email = sharedPreferences.getString(AppConstants.KEY_EMAIL, ""); + String accessToken = sharedPreferences.getString(AppConstants.KEY_ACCESS_TOKEN, ""); if (TextUtils.isEmpty(email) || TextUtils.isEmpty(accessToken)) { - - handler.postDelayed(launchLoginScreenTask, 1500); - + Log.d(TAG, "Email : " + email); + launchLoginScreen(); } else { - AppHelper.setUser(email); - handler.postDelayed(launchHomeScreenTask, 1500); + launchHomeScreen(); } } public void launchHomeScreen() { - + ((EspApplication) getApplicationContext()).changeAppState(EspApplication.AppState.GETTING_DATA, null); Intent espMainActivity = new Intent(getApplicationContext(), EspMainActivity.class); espMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(espMainActivity); @@ -70,26 +58,9 @@ public void launchHomeScreen() { } public void launchLoginScreen() { - Intent espMainActivity = new Intent(getApplicationContext(), MainActivity.class); espMainActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); startActivity(espMainActivity); finish(); } - - private Runnable launchLoginScreenTask = new Runnable() { - - @Override - public void run() { - launchLoginScreen(); - } - }; - - private Runnable launchHomeScreenTask = new Runnable() { - - @Override - public void run() { - launchHomeScreen(); - } - }; -} +} \ No newline at end of file diff --git a/app/src/main/java/com/espressif/ui/activities/VoiceServicesActivity.java b/app/src/main/java/com/espressif/ui/activities/VoiceServicesActivity.java new file mode 100644 index 0000000..2f02bec --- /dev/null +++ b/app/src/main/java/com/espressif/ui/activities/VoiceServicesActivity.java @@ -0,0 +1,80 @@ +// Copyright 2021 Espressif Systems (Shanghai) PTE LTD +// +// 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. + +package com.espressif.ui.activities; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.RelativeLayout; + +import androidx.appcompat.app.AppCompatActivity; + +import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; + +public class VoiceServicesActivity extends AppCompatActivity { + + private RelativeLayout rlAlexa, rlGva; + + @Override + public void onCreate(Bundle savedInstanceState) { + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_voice_services); + initViews(); + } + + private void initViews() { + + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_voice_services); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + rlAlexa = findViewById(R.id.rl_alexa); + rlGva = findViewById(R.id.rl_gva); + rlAlexa.setOnClickListener(alexaClickListener); + rlGva.setOnClickListener(gvaClickListener); + } + + private View.OnClickListener alexaClickListener = new View.OnClickListener() { + + @Override + public void onClick(View v) { + String url = "https://rainmaker.espressif.com/docs/3rd-party.html#enabling-alexa"; + Intent openURL = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(openURL); + } + }; + + private View.OnClickListener gvaClickListener = new View.OnClickListener() { + + @Override + public void onClick(View v) { + String url = "https://rainmaker.espressif.com/docs/3rd-party.html#enabling-google-voice-assistant-gva"; + Intent openURL = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); + startActivity(openURL); + } + }; +} diff --git a/app/src/main/java/com/espressif/ui/activities/WiFiConfigActivity.java b/app/src/main/java/com/espressif/ui/activities/WiFiConfigActivity.java index 51a164a..2119b38 100644 --- a/app/src/main/java/com/espressif/ui/activities/WiFiConfigActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/WiFiConfigActivity.java @@ -31,6 +31,7 @@ import com.espressif.provisioning.ESPConstants; import com.espressif.provisioning.ESPProvisionManager; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import org.greenrobot.eventbus.EventBus; @@ -41,7 +42,6 @@ public class WiFiConfigActivity extends AppCompatActivity { private static final String TAG = WiFiConfigActivity.class.getSimpleName(); - private TextView tvTitle, tvBack, tvCancel; private MaterialCardView btnNext; private TextView txtNextBtn; @@ -102,20 +102,24 @@ public void onClick(View v) { } }; - private View.OnClickListener cancelBtnClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - provisionManager.getEspDevice().disconnectDevice(); - finish(); - } - }; - private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle(R.string.title_activity_wifi_config); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } + finish(); + } + }); + etSsid = findViewById(R.id.et_ssid_input); etPassword = findViewById(R.id.et_password_input); @@ -126,11 +130,6 @@ private void initViews() { tvInstructionMsg.setText(msg); } - tvTitle.setText(R.string.title_activity_wifi_config); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); - tvCancel.setOnClickListener(cancelBtnClickListener); - btnNext = findViewById(R.id.btn_next); txtNextBtn = findViewById(R.id.text_btn); txtNextBtn.setText(R.string.btn_next); diff --git a/app/src/main/java/com/espressif/ui/activities/WiFiScanActivity.java b/app/src/main/java/com/espressif/ui/activities/WiFiScanActivity.java index ac8dcb7..c2bea15 100644 --- a/app/src/main/java/com/espressif/ui/activities/WiFiScanActivity.java +++ b/app/src/main/java/com/espressif/ui/activities/WiFiScanActivity.java @@ -14,24 +14,40 @@ package com.espressif.ui.activities; +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.net.wifi.ScanResult; +import android.net.wifi.SupplicantState; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; import android.util.Log; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; +import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.widget.AdapterView; +import android.widget.ArrayAdapter; import android.widget.EditText; -import android.widget.ImageView; -import android.widget.ListView; -import android.widget.ProgressBar; +import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; import com.espressif.AppConstants; import com.espressif.provisioning.DeviceConnectionEvent; @@ -39,85 +55,72 @@ import com.espressif.provisioning.ESPProvisionManager; import com.espressif.provisioning.WiFiAccessPoint; import com.espressif.provisioning.listeners.WiFiScanListener; +import com.espressif.rainmaker.BuildConfig; import com.espressif.rainmaker.R; -import com.espressif.ui.adapters.WiFiListAdapter; +import com.espressif.ui.widgets.EspDropDown; import com.google.android.material.appbar.MaterialToolbar; -import com.google.android.material.textfield.TextInputLayout; +import com.google.android.material.card.MaterialCardView; +import com.google.android.material.checkbox.MaterialCheckBox; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textview.MaterialTextView; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.util.ArrayList; +import java.util.List; public class WiFiScanActivity extends AppCompatActivity { private static final String TAG = WiFiScanActivity.class.getSimpleName(); - private ProgressBar progressBar; + private static final int REQUEST_ACCESS_FINE_LOCATION = 1; + + private MaterialCardView btnNext, btnRescan; + private TextView txtNextBtn; + private TextView txtRescanBtn; + private EspDropDown spinnerNetworks; + private MaterialTextView tvOtherNetwork; + private TextInputEditText etPassword; + private MaterialCheckBox cbSavePwd; + private RelativeLayout rlProgress, rlWiFiScan; + + private ESPProvisionManager provisionManager; + private String ssid, password; + private WifiManager wifiManager; + private List results; private ArrayList wifiAPList; - private WiFiListAdapter adapter; - private ListView wifiListView; - private ImageView ivRefresh; + private ArrayList spinnerValues = new ArrayList<>(); + private ArrayAdapter dataAdapter; + private SharedPreferences sharedPreferences; + private boolean shouldSavePassword; private Handler handler; - private ESPProvisionManager provisionManager; + private String previousNetwork; @Override - protected void onCreate(Bundle savedInstanceState) { + protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_wifi_scan_list); - MaterialToolbar toolbar = findViewById(R.id.toolbar); - toolbar.setTitle(R.string.title_activity_wifi_scan_list); - setSupportActionBar(toolbar); - - ivRefresh = findViewById(R.id.btn_refresh); - wifiListView = findViewById(R.id.wifi_ap_list); - progressBar = findViewById(R.id.wifi_progress_indicator); - - progressBar.setVisibility(View.VISIBLE); - wifiAPList = new ArrayList<>(); - handler = new Handler(); provisionManager = ESPProvisionManager.getInstance(getApplicationContext()); + shouldSavePassword = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE) + .getBoolean(AppConstants.KEY_SHOULD_SAVE_PWD, true); - String deviceName = provisionManager.getEspDevice().getDeviceName(); - String wifiMsg = String.format(getString(R.string.setup_instructions), deviceName); - TextView tvWifiMsg = findViewById(R.id.wifi_message); - tvWifiMsg.setText(wifiMsg); - - ivRefresh.setOnClickListener(refreshClickListener); - - adapter = new WiFiListAdapter(this, R.id.tv_wifi_name, wifiAPList); - - // Assign adapter to ListView - wifiListView.setAdapter(adapter); - wifiListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - - @Override - public void onItemClick(AdapterView adapterView, View view, int pos, long l) { - - Log.d(TAG, "Device to be connected -" + wifiAPList.get(pos)); - String ssid = wifiAPList.get(pos).getWifiName(); - - if (ssid.equals(getString(R.string.join_other_network))) { - askForNetwork(wifiAPList.get(pos).getWifiName(), wifiAPList.get(pos).getSecurity()); - } else if (wifiAPList.get(pos).getSecurity() == ESPConstants.WIFI_OPEN) { - goToProvisionActivity(wifiAPList.get(pos).getWifiName(), ""); - } else { - askForNetwork(wifiAPList.get(pos).getWifiName(), wifiAPList.get(pos).getSecurity()); - } - } - }); - - wifiListView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { - - @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { - } - }); - + sharedPreferences = getSharedPreferences(AppConstants.PREF_FILE_WIFI_NETWORKS, Context.MODE_PRIVATE); + handler = new Handler(); + wifiAPList = new ArrayList<>(); + previousNetwork = getIntent().getStringExtra(AppConstants.KEY_SSID); + initViews(); EventBus.getDefault().register(this); - startWifiScan(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + + ActivityCompat.requestPermissions(this, new + String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_ACCESS_FINE_LOCATION); + } else { + startScan(); + } } @Override @@ -128,7 +131,9 @@ protected void onDestroy() { @Override public void onBackPressed() { - provisionManager.getEspDevice().disconnectDevice(); + if (provisionManager.getEspDevice() != null) { + provisionManager.getEspDevice().disconnectDevice(); + } super.onBackPressed(); } @@ -147,18 +152,145 @@ public void onEvent(DeviceConnectionEvent event) { } } - private void startWifiScan() { + private void initViews() { - Log.d(TAG, "Start Wi-Fi Scan"); - wifiAPList.clear(); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_wifi_scan_list); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ESPProvisionManager provisionManager = ESPProvisionManager.getInstance(getApplicationContext()); + provisionManager.getEspDevice().disconnectDevice(); + finish(); + } + }); - runOnUiThread(new Runnable() { + spinnerNetworks = findViewById(R.id.spinner_networks); + etPassword = findViewById(R.id.et_password); + tvOtherNetwork = findViewById(R.id.tv_add_network); + cbSavePwd = findViewById(R.id.cb_save_pwd); + cbSavePwd.setChecked(shouldSavePassword); + + spinnerValues.add(0, getString(R.string.select_network)); + dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, spinnerValues); + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + spinnerNetworks.setAdapter(dataAdapter); + + btnNext = findViewById(R.id.btn_start); + txtNextBtn = btnNext.findViewById(R.id.text_btn); + txtNextBtn.setText(R.string.btn_start); + btnNext.findViewById(R.id.iv_arrow).setVisibility(View.GONE); + + btnRescan = findViewById(R.id.btn_rescan); + btnRescan.setStrokeColor(getColor(android.R.color.transparent)); + txtRescanBtn = btnRescan.findViewById(R.id.text_btn); + txtRescanBtn.setText(R.string.btn_scan_again); + + rlWiFiScan = findViewById(R.id.rl_wifi_scan); + rlProgress = findViewById(R.id.rl_progress); + + btnNext.setOnClickListener(startBtnClickListener); + btnRescan.setOnClickListener(scanAgainClickListener); + tvOtherNetwork.setOnClickListener(otherNetworkClickListener); + + spinnerNetworks.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void run() { - updateProgressAndScanBtn(true); + public void onItemSelected(AdapterView parent, View view, int position, long id) { + ssid = spinnerValues.get(position); + if (shouldSavePassword) { + if (sharedPreferences.contains(ssid)) { + String password = sharedPreferences.getString(ssid, ""); + etPassword.setText(password); + etPassword.setSelection(etPassword.getText().length()); + } else { + etPassword.setText(""); + } + } + } + + @Override + public void onNothingSelected(AdapterView parent) { } }); + etPassword.setOnEditorActionListener(new TextView.OnEditorActionListener() { + + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + + if (actionId == EditorInfo.IME_ACTION_GO) { + startBtnClick(); + } + return false; + } + }); + + if (BuildConfig.WIFI_SCAN_SRC.equals(AppConstants.WIFI_SCAN_FROM_PHONE)) { + IntentFilter intentFilter = new IntentFilter(); + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); + registerReceiver(wifiScanReceiver, intentFilter); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, + @NonNull int[] grantResults) { + + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + Log.e(TAG, "onRequestPermissionsResult , requestCode : " + requestCode); + + if (requestCode == REQUEST_ACCESS_FINE_LOCATION) { + startScan(); + } + } + + private void startScan() { + + updateProgressAndScanBtn(true); + if (BuildConfig.WIFI_SCAN_SRC.equals(AppConstants.WIFI_SCAN_FROM_DEVICE)) { + showLoading(); + startWifiScanUsingDevice(); + } else { + displayWifiList(); + boolean success = wifiManager.startScan(); + if (!success) { + Log.e(TAG, "Failed to start Wi-Fi Scanning using phone"); + } + } + } + + private void startBtnClick() { + + String password = etPassword.getText().toString(); + + // Store save password setting in main preferences file. + SharedPreferences.Editor mainPrefEditor = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE).edit(); + mainPrefEditor.putBoolean(AppConstants.KEY_SHOULD_SAVE_PWD, cbSavePwd.isChecked()); + mainPrefEditor.apply(); + + SharedPreferences.Editor networksPrefEditor = sharedPreferences.edit(); + if (cbSavePwd.isChecked()) { + networksPrefEditor.putString(ssid, password); + } else { + networksPrefEditor.remove(ssid); + } + networksPrefEditor.apply(); + + if (TextUtils.isEmpty(ssid) || ssid.equals(getString(R.string.select_network))) { + Toast.makeText(WiFiScanActivity.this, R.string.error_network_select, Toast.LENGTH_LONG).show(); + } else { + goToProvisionActivity(ssid, password); + } + } + + private void startWifiScanUsingDevice() { + + Log.d(TAG, "Start Wi-Fi Scan"); + wifiAPList.clear(); handler.postDelayed(stopScanningTask, 15000); provisionManager.getEspDevice().scanNetworks(new WiFiScanListener() { @@ -169,7 +301,7 @@ public void onWifiListReceived(final ArrayList wifiList) { @Override public void run() { wifiAPList.addAll(wifiList); - completeWifiList(); + displayWifiList(); } }); } @@ -177,7 +309,6 @@ public void run() { @Override public void onWiFiScanFailed(Exception e) { - // TODO Log.e(TAG, "onWiFiScanFailed"); e.printStackTrace(); runOnUiThread(new Runnable() { @@ -191,25 +322,118 @@ public void run() { }); } - private void completeWifiList() { + private View.OnClickListener startBtnClickListener = new View.OnClickListener() { + + @Override + public void onClick(View v) { + startBtnClick(); + } + }; + + View.OnClickListener otherNetworkClickListener = new View.OnClickListener() { + + @Override + public void onClick(View v) { + askForNetwork(); + } + }; + + View.OnClickListener scanAgainClickListener = new View.OnClickListener() { + + @Override + public void onClick(View v) { + startScan(); + } + }; + + private Runnable stopScanningTask = new Runnable() { + + @Override + public void run() { + updateProgressAndScanBtn(false); + } + }; + + BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context c, Intent intent) { + + boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false); + if (success) { + displayWifiList(); + } else { + Log.e(TAG, "Failed to start Wi-Fi Scanning using phone"); + } + } + }; + + private void displayWifiList() { runOnUiThread(new Runnable() { @Override public void run() { - // Add "Join network" Option as a list item - WiFiAccessPoint wifiAp = new WiFiAccessPoint(); - wifiAp.setWifiName(getString(R.string.join_other_network)); - wifiAPList.add(wifiAp); + hideLoading(); + spinnerValues.clear(); + handler.removeCallbacks(stopScanningTask); + ssid = getConnectedNetwork(); + if (!TextUtils.isEmpty(previousNetwork) + && provisionManager.getEspDevice().getTransportType().equals(ESPConstants.TransportType.TRANSPORT_SOFTAP)) { + ssid = previousNetwork; + } + + if (BuildConfig.WIFI_SCAN_SRC.equals(AppConstants.WIFI_SCAN_FROM_DEVICE)) { + + for (int i = 0; i < wifiAPList.size(); i++) { + WiFiAccessPoint wifiAp = wifiAPList.get(i); + String wifiName = wifiAp.getWifiName(); + if (!spinnerValues.contains(wifiName)) { + spinnerValues.add(wifiName); + } + } + + if (!TextUtils.isEmpty(ssid) && spinnerValues.contains(ssid)) { + spinnerValues.remove(ssid); + spinnerValues.add(0, ssid); + } else { + spinnerValues.add(0, getString(R.string.select_network)); + } + } else { + + results = wifiManager.getScanResults(); + if (!TextUtils.isEmpty(ssid) && !provisionManager.getEspDevice().getTransportType(). + equals(ESPConstants.TransportType.TRANSPORT_SOFTAP)) { + spinnerValues.add(0, ssid); + } else { + spinnerValues.add(0, getString(R.string.select_network)); + } + + for (int i = 0; i < results.size(); i++) { + ScanResult network = results.get(i); + String networkName = network.SSID; + Log.e(TAG, "Network name : " + networkName); + networkName = networkName.replace("\"", ""); + if (!spinnerValues.contains(networkName)) { + spinnerValues.add(networkName); + } + } + } + dataAdapter.notifyDataSetChanged(); + + if (shouldSavePassword && sharedPreferences.contains(ssid)) { + String password = sharedPreferences.getString(ssid, ""); + etPassword.setText(password); + etPassword.setSelection(etPassword.getText().length()); + } updateProgressAndScanBtn(false); - handler.removeCallbacks(stopScanningTask); } }); } - private void askForNetwork(final String ssid, final int authMode) { + private void askForNetwork() { final AlertDialog.Builder builder = new AlertDialog.Builder(this); LayoutInflater inflater = this.getLayoutInflater(); @@ -218,16 +442,7 @@ private void askForNetwork(final String ssid, final int authMode) { final EditText etSsid = dialogView.findViewById(R.id.et_ssid); final EditText etPassword = dialogView.findViewById(R.id.et_password); - - if (ssid.equals(getString(R.string.join_other_network))) { - - builder.setTitle(R.string.dialog_title_network_info); - - } else { - - builder.setTitle(ssid); - etSsid.setVisibility(View.GONE); - } + builder.setTitle(R.string.dialog_title_network_info); builder.setPositiveButton(R.string.btn_join, new DialogInterface.OnClickListener() { @@ -235,44 +450,16 @@ private void askForNetwork(final String ssid, final int authMode) { public void onClick(DialogInterface dialog, int which) { String password = etPassword.getText().toString(); + String networkName = etSsid.getText().toString(); - if (ssid.equals(getString(R.string.join_other_network))) { + if (TextUtils.isEmpty(networkName)) { - String networkName = etSsid.getText().toString(); - - if (TextUtils.isEmpty(networkName)) { - - etSsid.setError(getString(R.string.error_ssid_empty)); - - } else { - - dialog.dismiss(); - goToProvisionActivity(networkName, password); - } + etSsid.setError(getString(R.string.error_ssid_empty)); } else { - if (TextUtils.isEmpty(password)) { - - if (authMode != ESPConstants.WIFI_OPEN) { - - TextInputLayout passwordLayout = dialogView.findViewById(R.id.layout_password); - passwordLayout.setError(getString(R.string.error_password_empty)); - - } else { - - dialog.dismiss(); - goToProvisionActivity(ssid, password); - } - - } else { - - if (authMode == ESPConstants.WIFI_OPEN) { - password = ""; - } - dialog.dismiss(); - goToProvisionActivity(ssid, password); - } + dialog.dismiss(); + goToProvisionActivity(networkName, password); } } }); @@ -290,50 +477,43 @@ public void onClick(DialogInterface dialog, int which) { alertDialog.show(); } - private void goToProvisionActivity(String ssid, String password) { + private void goToProvisionActivity(String networkName, String password) { finish(); Intent provisionIntent = new Intent(getApplicationContext(), ProvisionActivity.class); provisionIntent.putExtras(getIntent()); - provisionIntent.putExtra(AppConstants.KEY_SSID, ssid); + provisionIntent.putExtra(AppConstants.KEY_SSID, networkName); provisionIntent.putExtra(AppConstants.KEY_PASSWORD, password); startActivity(provisionIntent); } - private View.OnClickListener refreshClickListener = new View.OnClickListener() { + private String getConnectedNetwork() { - @Override - public void onClick(View v) { + String connectedNetwork = null; + wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); - startWifiScan(); + if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) { + connectedNetwork = wifiInfo.getSSID(); } - }; - - private Runnable stopScanningTask = new Runnable() { - @Override - public void run() { - - updateProgressAndScanBtn(false); + if (!TextUtils.isEmpty(connectedNetwork)) { + connectedNetwork = connectedNetwork.replace("\"", ""); } - }; + return connectedNetwork; + } /** * This method will update UI (Scan button enable / disable and progressbar visibility) */ private void updateProgressAndScanBtn(boolean isScanning) { + btnRescan.setEnabled(!isScanning); if (isScanning) { - - progressBar.setVisibility(View.VISIBLE); - wifiListView.setVisibility(View.GONE); - ivRefresh.setVisibility(View.GONE); - + txtRescanBtn.setText("Scanning Networks..."); +// btnRescan.setAlpha(0.3f); } else { - - progressBar.setVisibility(View.GONE); - wifiListView.setVisibility(View.VISIBLE); - ivRefresh.setVisibility(View.VISIBLE); - adapter.notifyDataSetChanged(); + txtRescanBtn.setText(R.string.btn_scan_again); +// btnRescan.setAlpha(1f); } } @@ -355,4 +535,17 @@ public void onClick(DialogInterface dialog, int which) { }); builder.show(); } + + private void showLoading() { + rlWiFiScan.setAlpha(0.3f); + rlProgress.setVisibility(View.VISIBLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, + WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + } + + private void hideLoading() { + rlWiFiScan.setAlpha(1); + rlProgress.setVisibility(View.GONE); + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); + } } diff --git a/app/src/main/java/com/espressif/ui/adapters/BleDeviceListAdapter.java b/app/src/main/java/com/espressif/ui/adapters/BleDeviceListAdapter.java index 9c7449a..c75acb4 100644 --- a/app/src/main/java/com/espressif/ui/adapters/BleDeviceListAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/BleDeviceListAdapter.java @@ -15,40 +15,66 @@ package com.espressif.ui.adapters; import android.app.Activity; -import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + import com.espressif.rainmaker.R; +import com.espressif.ui.activities.BLEProvisionLanding; import com.espressif.ui.models.BleDevice; import java.util.ArrayList; -public class BleDeviceListAdapter extends ArrayAdapter { +public class BleDeviceListAdapter extends RecyclerView.Adapter { - private Context context; + private Activity context; private ArrayList bluetoothDevices; - public BleDeviceListAdapter(Context context, int resource, ArrayList bluetoothDevices) { - super(context, resource, bluetoothDevices); + public BleDeviceListAdapter(Activity context, ArrayList bluetoothDevices) { this.context = context; this.bluetoothDevices = bluetoothDevices; } - public View getView(int position, View convertView, ViewGroup parent) { + @Override + public BLEDeviceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + + LayoutInflater layoutInflater = LayoutInflater.from(context); + View v = layoutInflater.inflate(R.layout.item_ble_scan, parent, false); + BLEDeviceViewHolder vh = new BLEDeviceViewHolder(v); // pass the view to View Holder + return vh; + } + + @Override + public void onBindViewHolder(@NonNull final BLEDeviceViewHolder holder, int position) { + + BleDevice bleDevice = bluetoothDevices.get(position); + holder.tvBleDeviceName.setText(bleDevice.getName()); - BleDevice btDevice = bluetoothDevices.get(position); + holder.itemView.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + ((BLEProvisionLanding) context).deviceClick(holder.getAdapterPosition()); + } + }); + } + + @Override + public int getItemCount() { + return bluetoothDevices.size(); + } - //get the inflater and inflate the XML layout for each item - LayoutInflater inflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); - View view = inflater.inflate(R.layout.item_ble_scan, null); + static class BLEDeviceViewHolder extends RecyclerView.ViewHolder { - TextView bleDeviceNameText = view.findViewById(R.id.tv_ble_device_name); - bleDeviceNameText.setText(btDevice.getName()); + TextView tvBleDeviceName; - return view; + public BLEDeviceViewHolder(View itemView) { + super(itemView); + tvBleDeviceName = itemView.findViewById(R.id.tv_ble_device_name); + } } } diff --git a/app/src/main/java/com/espressif/ui/adapters/EspDeviceAdapter.java b/app/src/main/java/com/espressif/ui/adapters/EspDeviceAdapter.java index 2167f1b..9db7e73 100644 --- a/app/src/main/java/com/espressif/ui/adapters/EspDeviceAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/EspDeviceAdapter.java @@ -44,7 +44,7 @@ import java.util.ArrayList; import java.util.Calendar; -public class EspDeviceAdapter extends RecyclerView.Adapter { +public class EspDeviceAdapter extends RecyclerView.Adapter { private Context context; private NetworkApiManager networkApiManager; @@ -57,70 +57,72 @@ public EspDeviceAdapter(Context context, ArrayList deviceList) { } @Override - public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public DeviceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - // infalte the item Layout LayoutInflater layoutInflater = LayoutInflater.from(context); View v = layoutInflater.inflate(R.layout.item_esp_device, parent, false); - // set the view's size, margins, paddings and layout parameters - MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder + DeviceViewHolder vh = new DeviceViewHolder(v); return vh; } @Override - public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { + public void onBindViewHolder(@NonNull final DeviceViewHolder deviceVh, final int position) { final Device device = deviceList.get(position); EspApplication espApp = (EspApplication) context.getApplicationContext(); EspNode node = espApp.nodeMap.get(device.getNodeId()); // set the data in items - myViewHolder.tvDeviceName.setText(device.getUserVisibleName()); + deviceVh.tvDeviceName.setText(device.getUserVisibleName()); if (TextUtils.isEmpty(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device); } else { if (AppConstants.ESP_DEVICE_BULB.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_bulb); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_bulb); } else if (AppConstants.ESP_DEVICE_BULB_CCT.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_bulb_cct); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_bulb_cct); } else if (AppConstants.ESP_DEVICE_BULB_RGB.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_bulb_rgb); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_bulb_rgb); } else if (AppConstants.ESP_DEVICE_SWITCH.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_switch); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_switch); } else if (AppConstants.ESP_DEVICE_LOCK.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_lock); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_lock); } else if (AppConstants.ESP_DEVICE_THERMOSTAT.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_thermostat); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_thermostat); } else if (AppConstants.ESP_DEVICE_FAN.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_fan); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_fan); } else if (AppConstants.ESP_DEVICE_SENSOR.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device); } else if (AppConstants.ESP_DEVICE_TEMP_SENSOR.equals(device.getDeviceType())) { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_temp_sensor); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_temp_sensor); + + } else if (AppConstants.ESP_DEVICE_OUTLET.equals(device.getDeviceType())) { + + deviceVh.ivDevice.setImageResource(R.drawable.ic_device_outlet); } else { - myViewHolder.ivDevice.setImageResource(R.drawable.ic_device); + deviceVh.ivDevice.setImageResource(R.drawable.ic_device); } } @@ -147,25 +149,25 @@ public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int if (TextUtils.isEmpty(dataType)) { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.GONE); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.GONE); } else if (AppConstants.UI_TYPE_TOGGLE.equalsIgnoreCase(param.getUiType())) { - myViewHolder.ivDeviceStatus.setVisibility(View.VISIBLE); - myViewHolder.tvStringValue.setVisibility(View.GONE); + deviceVh.ivDeviceStatus.setVisibility(View.VISIBLE); + deviceVh.tvStringValue.setVisibility(View.GONE); final boolean isOn = param.getSwitchStatus(); if (isOn) { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); } else { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); } if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { - myViewHolder.ivDeviceStatus.setOnClickListener(new View.OnClickListener() { + deviceVh.ivDeviceStatus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -173,9 +175,9 @@ public void onClick(View v) { final boolean status = param.getSwitchStatus(); if (status) { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); } else { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); } JsonObject jsonParam = new JsonObject(); @@ -192,7 +194,12 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Toast.makeText(context, R.string.error_param_update, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onNetworkFailure(Exception exception) { Toast.makeText(context, R.string.error_param_update, Toast.LENGTH_SHORT).show(); } }); @@ -202,8 +209,8 @@ public void onFailure(Exception exception) { } else if (dataType.equalsIgnoreCase("bool") || dataType.equalsIgnoreCase("boolean")) { - myViewHolder.ivDeviceStatus.setVisibility(View.VISIBLE); - myViewHolder.tvStringValue.setVisibility(View.GONE); + deviceVh.ivDeviceStatus.setVisibility(View.VISIBLE); + deviceVh.tvStringValue.setVisibility(View.GONE); String value = param.getLabelValue(); boolean isOn = false; @@ -213,14 +220,14 @@ public void onFailure(Exception exception) { } if (isOn) { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); } else { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); } if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { - myViewHolder.ivDeviceStatus.setOnClickListener(new View.OnClickListener() { + deviceVh.ivDeviceStatus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -245,16 +252,21 @@ public void onClick(View v) { public void onSuccess(Bundle data) { if (finalIsOn1) { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_off); param.setLabelValue("false"); } else { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_on); param.setLabelValue("true"); } } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + Toast.makeText(context, R.string.error_param_update, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onNetworkFailure(Exception exception) { Toast.makeText(context, R.string.error_param_update, Toast.LENGTH_SHORT).show(); } }); @@ -264,46 +276,48 @@ public void onFailure(Exception exception) { } else if (dataType.equalsIgnoreCase("int") || dataType.equalsIgnoreCase("integer")) { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.VISIBLE); - myViewHolder.tvStringValue.setText(param.getLabelValue()); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.VISIBLE); + deviceVh.tvStringValue.setText(param.getLabelValue()); } else if (dataType.equalsIgnoreCase("float") || dataType.equalsIgnoreCase("double")) { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.VISIBLE); - myViewHolder.tvStringValue.setText(param.getLabelValue()); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.VISIBLE); + deviceVh.tvStringValue.setText(param.getLabelValue()); } else if (dataType.equalsIgnoreCase("string")) { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.VISIBLE); - myViewHolder.tvStringValue.setText(param.getLabelValue()); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.VISIBLE); + deviceVh.tvStringValue.setText(param.getLabelValue()); } } else { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.GONE); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.GONE); } } else { - myViewHolder.ivDeviceStatus.setVisibility(View.GONE); - myViewHolder.tvStringValue.setVisibility(View.GONE); + deviceVh.ivDeviceStatus.setVisibility(View.GONE); + deviceVh.tvStringValue.setVisibility(View.GONE); } if (node != null && !node.isOnline()) { - myViewHolder.ivDeviceStatus.setImageResource(R.drawable.ic_output_disable); - myViewHolder.ivDeviceStatus.setOnClickListener(null); + deviceVh.itemView.setAlpha(0.8f); + deviceVh.ivDeviceStatus.setImageResource(R.drawable.ic_output_disable); + deviceVh.ivDeviceStatus.setOnClickListener(null); - if (espApp.getCurrentStatus().equals(EspApplication.GetDataStatus.GET_DATA_SUCCESS) - || espApp.getCurrentStatus().equals(EspApplication.GetDataStatus.DATA_REFRESHING)) { + if (espApp.getAppState().equals(EspApplication.AppState.GET_DATA_SUCCESS) + || espApp.getAppState().equals(EspApplication.AppState.REFRESH_DATA) + || espApp.getAppState().equals(EspApplication.AppState.GET_DATA_FAILED)) { - myViewHolder.llOffline.setVisibility(View.VISIBLE); - myViewHolder.ivOffline.setVisibility(View.VISIBLE); + deviceVh.llOffline.setVisibility(View.VISIBLE); + deviceVh.ivOffline.setVisibility(View.VISIBLE); String offlineText = context.getString(R.string.status_offline); - myViewHolder.tvOffline.setText(offlineText); - myViewHolder.tvOffline.setTextColor(context.getColor(R.color.colorAccent)); + deviceVh.tvOffline.setText(offlineText); + deviceVh.tvOffline.setTextColor(context.getColor(R.color.colorAccent)); if (node.getTimeStampOfStatus() != 0) { @@ -325,26 +339,27 @@ public void onFailure(Exception exception) { String time = formatter.format(calendar.getTime()); offlineText = context.getString(R.string.offline_at) + " " + time; } - myViewHolder.tvOffline.setText(offlineText); + deviceVh.tvOffline.setText(offlineText); } } else { - myViewHolder.llOffline.setVisibility(View.INVISIBLE); + deviceVh.llOffline.setVisibility(View.INVISIBLE); } } else { - myViewHolder.llOffline.setVisibility(View.INVISIBLE); + deviceVh.itemView.setAlpha(1f); + deviceVh.llOffline.setVisibility(View.INVISIBLE); } String nodeId = device.getNodeId(); if (espApp.mDNSDeviceMap.containsKey(nodeId)) { - myViewHolder.llOffline.setVisibility(View.VISIBLE); - myViewHolder.ivOffline.setVisibility(View.GONE); - myViewHolder.tvOffline.setText(R.string.local_device_text); - myViewHolder.tvOffline.setTextColor(context.getColor(R.color.colorPrimaryDark)); + deviceVh.llOffline.setVisibility(View.VISIBLE); + deviceVh.ivOffline.setVisibility(View.GONE); + deviceVh.tvOffline.setText(R.string.local_device_text); + deviceVh.tvOffline.setTextColor(context.getColor(R.color.colorPrimaryDark)); } // implement setOnClickListener event on item view. - myViewHolder.itemView.setOnClickListener(new View.OnClickListener() { + deviceVh.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -365,17 +380,15 @@ public void updateList(ArrayList updatedDeviceList) { notifyDataSetChanged(); } - public class MyViewHolder extends RecyclerView.ViewHolder { + static class DeviceViewHolder extends RecyclerView.ViewHolder { - // init the item view's TextView tvDeviceName, tvStringValue, tvOffline; ImageView ivDevice, ivDeviceStatus, ivOffline; LinearLayout llOffline; - public MyViewHolder(View itemView) { + public DeviceViewHolder(View itemView) { super(itemView); - // get the reference of item view's tvDeviceName = itemView.findViewById(R.id.tv_device_name); ivDevice = itemView.findViewById(R.id.iv_device); llOffline = itemView.findViewById(R.id.ll_offline); diff --git a/app/src/main/java/com/espressif/ui/adapters/GroupAdapter.java b/app/src/main/java/com/espressif/ui/adapters/GroupAdapter.java index e7e2663..61afb59 100644 --- a/app/src/main/java/com/espressif/ui/adapters/GroupAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/GroupAdapter.java @@ -16,7 +16,6 @@ import android.app.Activity; import android.content.Intent; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; diff --git a/app/src/main/java/com/espressif/ui/adapters/GroupDeviceAdapter.java b/app/src/main/java/com/espressif/ui/adapters/GroupDeviceAdapter.java index 8af822e..9aac7e6 100644 --- a/app/src/main/java/com/espressif/ui/adapters/GroupDeviceAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/GroupDeviceAdapter.java @@ -31,7 +31,6 @@ import com.espressif.ui.activities.GroupDetailActivity; import com.espressif.ui.models.Device; import com.espressif.ui.models.Group; -import com.espressif.ui.models.Param; import com.google.android.material.checkbox.MaterialCheckBox; import java.util.ArrayList; @@ -126,6 +125,10 @@ public void onBindViewHolder(@NonNull final GroupDeviceVH myViewHolder, final in myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_temp_sensor); + } else if (AppConstants.ESP_DEVICE_OUTLET.equals(device.getDeviceType())) { + + myViewHolder.ivDevice.setImageResource(R.drawable.ic_device_outlet); + } else { myViewHolder.ivDevice.setImageResource(R.drawable.ic_device); } @@ -166,7 +169,7 @@ public int getItemCount() { return deviceList.size(); } - public static class GroupDeviceVH extends RecyclerView.ViewHolder { + static class GroupDeviceVH extends RecyclerView.ViewHolder { TextView tvDeviceName; ImageView ivDevice, ivRemove; diff --git a/app/src/main/java/com/espressif/ui/adapters/GroupNodeAdapter.java b/app/src/main/java/com/espressif/ui/adapters/GroupNodeAdapter.java index 0d619fe..6adbd28 100644 --- a/app/src/main/java/com/espressif/ui/adapters/GroupNodeAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/GroupNodeAdapter.java @@ -38,13 +38,13 @@ public class GroupNodeAdapter extends RecyclerView.Adapter nodedList; + private ArrayList nodeList; private boolean isSelection; - public GroupNodeAdapter(Activity context, Group group, ArrayList nodedList, boolean isSelection) { + public GroupNodeAdapter(Activity context, Group group, ArrayList nodeList, boolean isSelection) { this.context = context; this.group = group; - this.nodedList = nodedList; + this.nodeList = nodeList; this.isSelection = isSelection; } @@ -58,55 +58,58 @@ public GroupNodeVH onCreateViewHolder(ViewGroup parent, int viewType) { } @Override - public void onBindViewHolder(@NonNull final GroupNodeVH myViewHolder, final int position) { + public void onBindViewHolder(@NonNull final GroupNodeVH groupNodeVh, final int position) { - EspNode node = nodedList.get(position); - myViewHolder.tvNodeName.setText(node.getNodeName()); + EspNode node = nodeList.get(position); + groupNodeVh.tvNodeName.setText(node.getNodeName()); if (isSelection) { - myViewHolder.cbDevice.setVisibility(View.VISIBLE); - myViewHolder.ivRemove.setVisibility(View.GONE); + groupNodeVh.cbDevice.setVisibility(View.VISIBLE); + groupNodeVh.ivRemove.setVisibility(View.GONE); } else { - myViewHolder.cbDevice.setVisibility(View.GONE); - myViewHolder.ivRemove.setVisibility(View.VISIBLE); + groupNodeVh.cbDevice.setVisibility(View.GONE); + groupNodeVh.ivRemove.setVisibility(View.VISIBLE); } - myViewHolder.ivRemove.setOnClickListener(new View.OnClickListener() { + GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); + groupNodeVh.rvDevices.setLayoutManager(linearLayoutManager); + + groupNodeVh.ivRemove.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (context instanceof GroupDetailActivity) { - String nodeId = nodedList.get(myViewHolder.getAdapterPosition()).getNodeId(); + String nodeId = nodeList.get(groupNodeVh.getAdapterPosition()).getNodeId(); ((GroupDetailActivity) context).removeDevice(nodeId); } } }); - myViewHolder.cbDevice.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + groupNodeVh.cbDevice.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - nodedList.get(myViewHolder.getAdapterPosition()).setSelected(isChecked); + nodeList.get(groupNodeVh.getAdapterPosition()).setSelected(isChecked); } }); - myViewHolder.itemView.setOnClickListener(new View.OnClickListener() { + groupNodeVh.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - myViewHolder.cbDevice.toggle(); + groupNodeVh.cbDevice.toggle(); } }); GroupDeviceAdapter adapter = new GroupDeviceAdapter(context, group, node.getDevices(), isSelection, false); - myViewHolder.rvDevices.setAdapter(adapter); + groupNodeVh.rvDevices.setAdapter(adapter); } @Override public int getItemCount() { - return nodedList.size(); + return nodeList.size(); } - public class GroupNodeVH extends RecyclerView.ViewHolder { + static class GroupNodeVH extends RecyclerView.ViewHolder { TextView tvNodeName; ImageView ivRemove; @@ -120,9 +123,6 @@ public GroupNodeVH(View itemView) { ivRemove = itemView.findViewById(R.id.iv_remove); cbDevice = itemView.findViewById(R.id.cb_node); rvDevices = itemView.findViewById(R.id.rv_device_list); - - GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); - rvDevices.setLayoutManager(linearLayoutManager); } } } diff --git a/app/src/main/java/com/espressif/ui/adapters/GroupsPageAdapter.java b/app/src/main/java/com/espressif/ui/adapters/GroupsPageAdapter.java index f1b709b..1f422ed 100644 --- a/app/src/main/java/com/espressif/ui/adapters/GroupsPageAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/GroupsPageAdapter.java @@ -90,6 +90,23 @@ public void onBindViewHolder(@NonNull GroupPageViewHolder viewHolder, int positi ArrayList devices = new ArrayList<>(); ArrayList nodes = new ArrayList<>(); + GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); + viewHolder.rvDevices.setLayoutManager(linearLayoutManager); + viewHolder.rvDevices.setHasFixedSize(true); + + viewHolder.rvNodes.setLayoutManager(new LinearLayoutManager(context)); + viewHolder.rvNodes.setHasFixedSize(true); + + viewHolder.swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { + + @Override + public void onRefresh() { + isRefreshing = true; + notifyDataSetChanged(); + ((EspMainActivity) context).refreshDeviceList(); + } + }); + EspDeviceAdapter deviceAdapter = new EspDeviceAdapter(context, devices); viewHolder.rvDevices.setAdapter(deviceAdapter); @@ -130,7 +147,6 @@ public void onBindViewHolder(@NonNull GroupPageViewHolder viewHolder, int positi if (devices.size() <= 0 && nodes.size() <= 0) { - viewHolder.ivNoDevice.setVisibility(View.VISIBLE); viewHolder.tvNoDevice.setText(R.string.no_devices); viewHolder.rlNoDevices.setVisibility(View.VISIBLE); viewHolder.tvNoDevice.setVisibility(View.VISIBLE); @@ -139,7 +155,7 @@ public void onBindViewHolder(@NonNull GroupPageViewHolder viewHolder, int positi viewHolder.rvNodes.setVisibility(View.GONE); if (position == 0) { - + viewHolder.ivNoDevice.setVisibility(View.VISIBLE); viewHolder.btnAddDevice.setVisibility(View.VISIBLE); viewHolder.btnAddDevice.setOnClickListener(new View.OnClickListener() { @Override @@ -159,6 +175,7 @@ public void onClick(View v) { } }); } else { + viewHolder.ivNoDevice.setVisibility(View.GONE); viewHolder.btnAddDevice.setVisibility(View.GONE); } } else { @@ -192,7 +209,7 @@ public int getItemCount() { return groups.size(); } - public class GroupPageViewHolder extends RecyclerView.ViewHolder { + static class GroupPageViewHolder extends RecyclerView.ViewHolder { private CardView btnAddDevice; private TextView txtAddDeviceBtn; @@ -225,22 +242,6 @@ public GroupPageViewHolder(View pageView) { ((SimpleItemAnimator) rvDevices.getItemAnimator()).setSupportsChangeAnimations(false); ((SimpleItemAnimator) rvNodes.getItemAnimator()).setSupportsChangeAnimations(false); - - GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); - rvDevices.setLayoutManager(linearLayoutManager); - rvDevices.setHasFixedSize(true); - - rvNodes.setLayoutManager(new LinearLayoutManager(context)); - rvNodes.setHasFixedSize(true); - - swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { - - @Override - public void onRefresh() { - isRefreshing = true; - ((EspMainActivity) context).refreshDeviceList(); - } - }); } } diff --git a/app/src/main/java/com/espressif/ui/adapters/HomeScreenPagerAdapter.java b/app/src/main/java/com/espressif/ui/adapters/HomeScreenPagerAdapter.java index ac878ca..8fe0ec6 100644 --- a/app/src/main/java/com/espressif/ui/adapters/HomeScreenPagerAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/HomeScreenPagerAdapter.java @@ -44,11 +44,15 @@ public Fragment getItem(int position) { @Override public CharSequence getPageTitle(int position) { - if (position == 0) { - return context.getString(R.string.title_activity_devices); - } else { - return context.getString(R.string.title_activity_schedules); + switch (position) { + case 0: + return context.getString(R.string.devices_title); + case 1: + return context.getString(R.string.title_activity_schedules); + case 2: + return context.getString(R.string.title_activity_user_profile); } + return ""; } @Override diff --git a/app/src/main/java/com/espressif/ui/adapters/NodeAdapter.java b/app/src/main/java/com/espressif/ui/adapters/NodeAdapter.java index e6c1d46..bc16686 100644 --- a/app/src/main/java/com/espressif/ui/adapters/NodeAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/NodeAdapter.java @@ -46,11 +46,9 @@ public NodeAdapter(Context context, ArrayList deviceList) { @Override public NodeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - // infalte the item Layout LayoutInflater layoutInflater = LayoutInflater.from(context); View v = layoutInflater.inflate(R.layout.item_node, parent, false); - // set the view's size, margins, paddings and layout parameters - NodeViewHolder vh = new NodeViewHolder(v); // pass the view to View Holder + NodeViewHolder vh = new NodeViewHolder(v); return vh; } @@ -60,6 +58,8 @@ public void onBindViewHolder(@NonNull final NodeViewHolder myViewHolder, final i final EspNode node = nodedList.get(position); myViewHolder.tvDeviceName.setText(node.getNodeName()); + GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); + myViewHolder.rvDevices.setLayoutManager(linearLayoutManager); EspDeviceAdapter adapter = new EspDeviceAdapter(context, node.getDevices()); myViewHolder.rvDevices.setAdapter(adapter); @@ -92,9 +92,8 @@ public void updateList(ArrayList updatedNodeList) { notifyDataSetChanged(); } - public class NodeViewHolder extends RecyclerView.ViewHolder { + static class NodeViewHolder extends RecyclerView.ViewHolder { - // init the item view's TextView tvDeviceName; ImageView ivDevice; RecyclerView rvDevices; @@ -103,14 +102,10 @@ public class NodeViewHolder extends RecyclerView.ViewHolder { public NodeViewHolder(View itemView) { super(itemView); - // get the reference of item view's tvDeviceName = itemView.findViewById(R.id.tv_node_name); ivDevice = itemView.findViewById(R.id.iv_device); rvDevices = itemView.findViewById(R.id.rv_device_list); ivNodeInfo = itemView.findViewById(R.id.btn_info); - - GridLayoutManager linearLayoutManager = new GridLayoutManager(context, 2); - rvDevices.setLayoutManager(linearLayoutManager); // set LayoutManager to RecyclerView } } } diff --git a/app/src/main/java/com/espressif/ui/adapters/NodeDetailsAdapter.java b/app/src/main/java/com/espressif/ui/adapters/NodeDetailsAdapter.java index 087d8ae..04fa540 100644 --- a/app/src/main/java/com/espressif/ui/adapters/NodeDetailsAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/NodeDetailsAdapter.java @@ -14,34 +14,51 @@ package com.espressif.ui.adapters; -import android.content.Context; +import android.app.Activity; +import android.os.Bundle; import android.text.TextUtils; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.core.widget.ContentLoadingProgressBar; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.espressif.AppConstants; +import com.espressif.NetworkApiManager; +import com.espressif.cloudapi.ApiResponseListener; +import com.espressif.cloudapi.CloudException; import com.espressif.rainmaker.R; import com.espressif.ui.models.EspNode; +import com.espressif.ui.models.Param; +import com.espressif.ui.models.Service; import com.espressif.ui.models.SharingRequest; +import com.espressif.ui.widgets.EspDropDown; +import com.google.gson.JsonObject; import java.util.ArrayList; +import java.util.Arrays; public class NodeDetailsAdapter extends RecyclerView.Adapter { - private Context context; + private final String TAG = NodeDetailsAdapter.class.getSimpleName(); + + private Activity context; private ArrayList nodeInfoList; private ArrayList nodeInfoValueList; private ArrayList sharingRequests; private SharedUserAdapter userAdapter; private EspNode node; - public NodeDetailsAdapter(Context context, ArrayList nodeInfoList, ArrayList nodeValueList, + public NodeDetailsAdapter(Activity context, ArrayList nodeInfoList, ArrayList nodeValueList, EspNode node, ArrayList sharingRequests) { this.context = context; this.nodeInfoList = nodeInfoList; @@ -60,45 +77,190 @@ public NodeDetailViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { } @Override - public void onBindViewHolder(@NonNull NodeDetailViewHolder myViewHolder, final int position) { + public void onBindViewHolder(@NonNull final NodeDetailViewHolder nodeDetailVh, final int position) { // set the data in items - myViewHolder.tvNodeInfoLabel.setText(nodeInfoList.get(position)); + nodeDetailVh.tvNodeInfoLabel.setText(nodeInfoList.get(position)); if (nodeInfoList.get(position).equals(context.getString(R.string.node_shared_with)) || nodeInfoList.get(position).equals(context.getString(R.string.node_shared_by))) { - myViewHolder.rvSharedUsers.setVisibility(View.VISIBLE); - myViewHolder.tvNodeInfoValue.setVisibility(View.GONE); + nodeDetailVh.rvSharedUsers.setVisibility(View.VISIBLE); + nodeDetailVh.tvNodeInfoValue.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setVisibility(View.GONE); - // set a LinearLayoutManager with default orientation LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); linearLayoutManager.setOrientation(RecyclerView.VERTICAL); - myViewHolder.rvSharedUsers.setLayoutManager(linearLayoutManager); - DividerItemDecoration itemDecor = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL); - myViewHolder.rvSharedUsers.addItemDecoration(itemDecor); + nodeDetailVh.rvSharedUsers.setLayoutManager(linearLayoutManager); userAdapter = new SharedUserAdapter(context, node, sharingRequests, false); - myViewHolder.rvSharedUsers.setAdapter(userAdapter); + nodeDetailVh.rvSharedUsers.setAdapter(userAdapter); } else if (nodeInfoList.get(position).equals(context.getString(R.string.pending_requests))) { - myViewHolder.rvSharedUsers.setVisibility(View.VISIBLE); - myViewHolder.tvNodeInfoValue.setVisibility(View.GONE); + nodeDetailVh.rvSharedUsers.setVisibility(View.VISIBLE); + nodeDetailVh.tvNodeInfoValue.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setVisibility(View.GONE); - // set a LinearLayoutManager with default orientation LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); linearLayoutManager.setOrientation(RecyclerView.VERTICAL); - myViewHolder.rvSharedUsers.setLayoutManager(linearLayoutManager); - DividerItemDecoration itemDecor = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL); - myViewHolder.rvSharedUsers.addItemDecoration(itemDecor); + nodeDetailVh.rvSharedUsers.setLayoutManager(linearLayoutManager); userAdapter = new SharedUserAdapter(context, node, sharingRequests, true); - myViewHolder.rvSharedUsers.setAdapter(userAdapter); + nodeDetailVh.rvSharedUsers.setAdapter(userAdapter); + + } else if (nodeInfoList.get(position).equals(context.getString(R.string.node_timezone))) { + + nodeDetailVh.rvSharedUsers.setVisibility(View.GONE); + nodeDetailVh.tvNodeInfoValue.setVisibility(View.GONE); + nodeDetailVh.rlTimezone.setVisibility(View.VISIBLE); + nodeDetailVh.dropDownTimezone.setVisibility(View.VISIBLE); + nodeDetailVh.dropDownTimezone.setEnabled(false); + nodeDetailVh.dropDownTimezone.setOnItemSelectedListener(null); + + ArrayList services = node.getServices(); + Service tzService = null; + String tzValue = null, tzPosixValue = null; + String tzParamName = null; + + for (int i = 0; i < services.size(); i++) { + Service s = services.get(i); + if (!TextUtils.isEmpty(s.getType()) && s.getType().equals(AppConstants.SERVICE_TYPE_TIME)) { + tzService = s; + break; + } + } + + if (tzService != null) { + ArrayList tzParams = tzService.getParams(); + if (tzParams != null) { + for (int paramIdx = 0; paramIdx < tzParams.size(); paramIdx++) { + Param timeParam = tzParams.get(paramIdx); + if (AppConstants.PARAM_TYPE_TZ.equalsIgnoreCase(timeParam.getParamType())) { + tzValue = timeParam.getLabelValue(); + tzParamName = timeParam.getName(); + } else if (AppConstants.PARAM_TYPE_TZ_POSIX.equalsIgnoreCase(timeParam.getParamType())) { + tzPosixValue = timeParam.getLabelValue(); + } + } + } + + String[] timeZoneArray = context.getResources().getStringArray(R.array.timezones); + ArrayList spinnerValues = new ArrayList<>(Arrays.asList(timeZoneArray)); + int tzValueIndex = -1; + Log.d(TAG, "TZ : " + tzValue); + Log.d(TAG, "TZ POSIX : " + tzPosixValue); + + if (TextUtils.isEmpty(tzValue) || TextUtils.isEmpty(tzPosixValue)) { + spinnerValues.add(0, context.getString(R.string.select_timezone)); + nodeDetailVh.dropDownTimezone.setTag(R.id.position, 0); + } else { + if (spinnerValues.contains(tzValue)) { + tzValueIndex = spinnerValues.indexOf(tzValue); + nodeDetailVh.dropDownTimezone.setTag(R.id.position, tzValueIndex); + } else { + spinnerValues.add(0, context.getString(R.string.select_timezone)); + nodeDetailVh.dropDownTimezone.setTag(R.id.position, 0); + } + } + + ArrayAdapter dataAdapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerValues); + dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + nodeDetailVh.dropDownTimezone.setAdapter(dataAdapter); + + if (tzValueIndex != -1) { + nodeDetailVh.dropDownTimezone.setSelection(tzValueIndex, true); + } + final Service finalTzService = tzService; + final String finalTzParamName = tzParamName; + final int oldTzValueIndex = tzValueIndex; + nodeDetailVh.dropDownTimezone.setEnabled(true); + + nodeDetailVh.dropDownTimezone.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + + @Override + public void onItemSelected(AdapterView parent, View view, final int position, long id) { + + if ((int) nodeDetailVh.dropDownTimezone.getTag(R.id.position) != position) { + + final String newValue = parent.getItemAtPosition(position).toString(); + nodeDetailVh.dropDownTimezone.setEnabled(false); + nodeDetailVh.tzProgress.setVisibility(View.VISIBLE); + Log.d(TAG, "New timezone value : " + newValue); + + JsonObject body = new JsonObject(); + JsonObject jsonParam = new JsonObject(); + jsonParam.addProperty(finalTzParamName, newValue); + body.add(finalTzService.getName(), jsonParam); + + NetworkApiManager networkApiManager = new NetworkApiManager(context.getApplicationContext()); + networkApiManager.updateParamValue(node.getNodeId(), body, new ApiResponseListener() { + + @Override + public void onSuccess(Bundle data) { + + context.runOnUiThread(new Runnable() { + @Override + public void run() { + + nodeDetailVh.tzProgress.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setEnabled(true); + nodeDetailVh.dropDownTimezone.setTag(R.id.position, position); + } + }); + } + + @Override + public void onResponseFailure(Exception exception) { + + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_update_timezone, Toast.LENGTH_SHORT).show(); + } + + context.runOnUiThread(new Runnable() { + @Override + public void run() { + nodeDetailVh.tzProgress.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setEnabled(true); + nodeDetailVh.dropDownTimezone.setSelection(oldTzValueIndex, true); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { + + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_update_timezone, Toast.LENGTH_SHORT).show(); + } + + context.runOnUiThread(new Runnable() { + @Override + public void run() { + nodeDetailVh.tzProgress.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setEnabled(true); + nodeDetailVh.dropDownTimezone.setSelection(oldTzValueIndex, true); + } + }); + } + }); + } + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + } } else if (!TextUtils.isEmpty(nodeInfoValueList.get(position))) { - myViewHolder.rvSharedUsers.setVisibility(View.GONE); - myViewHolder.tvNodeInfoValue.setVisibility(View.VISIBLE); - myViewHolder.tvNodeInfoValue.setText(nodeInfoValueList.get(position)); + nodeDetailVh.rvSharedUsers.setVisibility(View.GONE); + nodeDetailVh.dropDownTimezone.setVisibility(View.GONE); + nodeDetailVh.tvNodeInfoValue.setVisibility(View.VISIBLE); + nodeDetailVh.tvNodeInfoValue.setText(nodeInfoValueList.get(position)); } } @@ -111,6 +273,9 @@ static class NodeDetailViewHolder extends RecyclerView.ViewHolder { TextView tvNodeInfoLabel, tvNodeInfoValue; RecyclerView rvSharedUsers; + EspDropDown dropDownTimezone; + RelativeLayout rlTimezone; + ContentLoadingProgressBar tzProgress; public NodeDetailViewHolder(View itemView) { super(itemView); @@ -118,6 +283,9 @@ public NodeDetailViewHolder(View itemView) { tvNodeInfoLabel = itemView.findViewById(R.id.tv_node_label); tvNodeInfoValue = itemView.findViewById(R.id.tv_node_value); rvSharedUsers = itemView.findViewById(R.id.rv_users_list); + dropDownTimezone = itemView.findViewById(R.id.dropdown_time_zone); + rlTimezone = itemView.findViewById(R.id.rl_timezone); + tzProgress = itemView.findViewById(R.id.progress_indicator_timezone); } } } diff --git a/app/src/main/java/com/espressif/ui/adapters/ParamAdapter.java b/app/src/main/java/com/espressif/ui/adapters/ParamAdapter.java index f25b695..50ca9b6 100644 --- a/app/src/main/java/com/espressif/ui/adapters/ParamAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/ParamAdapter.java @@ -16,6 +16,7 @@ import android.app.Activity; import android.content.DialogInterface; +import android.graphics.Color; import android.os.Bundle; import android.text.InputFilter; import android.text.InputType; @@ -29,6 +30,7 @@ import android.widget.ArrayAdapter; import android.widget.CompoundButton; import android.widget.EditText; +import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Spinner; import android.widget.TextView; @@ -45,122 +47,359 @@ import com.espressif.cloudapi.ApiResponseListener; import com.espressif.rainmaker.R; import com.espressif.ui.activities.EspDeviceActivity; +import com.espressif.ui.models.Device; import com.espressif.ui.models.Param; import com.espressif.ui.widgets.EspDropDown; import com.espressif.ui.widgets.PaletteBar; import com.google.gson.JsonObject; +import com.larswerkman.holocolorpicker.ColorPicker; import com.warkiz.tickseekbar.OnSeekChangeListener; import com.warkiz.tickseekbar.SeekParams; import com.warkiz.tickseekbar.TickSeekBar; import java.util.ArrayList; -public class ParamAdapter extends RecyclerView.Adapter { +public class ParamAdapter extends RecyclerView.Adapter { private final String TAG = ParamAdapter.class.getSimpleName(); + private final int VIEW_TYPE_PARAM = 1; + private final int VIEW_TYPE_PUSH_BTN_BIG = 2; + private final int VIEW_TYPE_HUE = 3; + private Activity context; + private Device device; private ArrayList params; private NetworkApiManager networkApiManager; private String nodeId, deviceName; - public ParamAdapter(Activity context, String nodeId, String deviceName, ArrayList deviceList) { + public ParamAdapter(Activity context, Device device, ArrayList paramList) { this.context = context; - this.nodeId = nodeId; - this.deviceName = deviceName; - this.params = deviceList; + this.device = device; + this.nodeId = device.getNodeId(); + this.deviceName = device.getDeviceName(); networkApiManager = new NetworkApiManager(context.getApplicationContext()); + + int firstParamIndex = -1; + for (int i = 0; i < paramList.size(); i++) { + + Param param = paramList.get(i); + if (param != null && AppConstants.UI_TYPE_HUE_CIRCLE.equalsIgnoreCase(param.getUiType())) { + firstParamIndex = i; + break; + } + } + + if (firstParamIndex != -1) { + Param paramToBeMoved = paramList.remove(firstParamIndex); + paramList.add(0, paramToBeMoved); + } else { + + for (int i = 0; i < paramList.size(); i++) { + + Param param = paramList.get(i); + if (param != null) { + String dataType = param.getDataType(); + if (AppConstants.UI_TYPE_PUSH_BTN_BIG.equalsIgnoreCase(param.getUiType()) + && (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("bool") || dataType.equalsIgnoreCase("boolean")))) { + firstParamIndex = i; + break; + } + } + } + + if (firstParamIndex != -1) { + Param paramToBeMoved = paramList.remove(firstParamIndex); + paramList.add(0, paramToBeMoved); + } + } + this.params = paramList; } - @NonNull @Override - public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - // infalte the item Layout LayoutInflater layoutInflater = LayoutInflater.from(context); - View v = layoutInflater.inflate(R.layout.item_param, parent, false); - // set the view's size, margins, paddings and layout parameters - MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder - return vh; + switch (viewType) { + + case VIEW_TYPE_PUSH_BTN_BIG: + View switchView = layoutInflater.inflate(R.layout.item_param_switch, parent, false); + return new SwitchViewHolder(switchView); + + case VIEW_TYPE_HUE: + View hueView = layoutInflater.inflate(R.layout.item_param_hue, parent, false); + return new HueViewHolder(hueView); + + case VIEW_TYPE_PARAM: + default: + View paramView = layoutInflater.inflate(R.layout.item_param, parent, false); + return new ParamViewHolder(paramView); + } } @Override - public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int position) { + public int getItemViewType(int position) { - final Param param = params.get(position); + Param param = params.get(position); - if (AppConstants.UI_TYPE_SLIDER.equalsIgnoreCase(param.getUiType())) { + if (param != null) { String dataType = param.getDataType(); - if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") - || dataType.equalsIgnoreCase("integer") - || dataType.equalsIgnoreCase("float") - || dataType.equalsIgnoreCase("double"))) { + if (AppConstants.UI_TYPE_HUE_CIRCLE.equalsIgnoreCase(param.getUiType())) { + + return VIEW_TYPE_HUE; + + } else if (AppConstants.UI_TYPE_PUSH_BTN_BIG.equalsIgnoreCase(param.getUiType()) + && (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("bool") || dataType.equalsIgnoreCase("boolean")))) { + + return VIEW_TYPE_PUSH_BTN_BIG; + } + } + return VIEW_TYPE_PARAM; + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { + + final Param param = params.get(position); + + if (holder.getItemViewType() == VIEW_TYPE_PARAM) { - int max = param.getMaxBounds(); - int min = param.getMinBounds(); + final ParamViewHolder paramViewHolder = (ParamViewHolder) holder; - if ((min < max)) { + if (AppConstants.UI_TYPE_SLIDER.equalsIgnoreCase(param.getUiType())) { + + String dataType = param.getDataType(); + + if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") + || dataType.equalsIgnoreCase("integer") + || dataType.equalsIgnoreCase("float") + || dataType.equalsIgnoreCase("double"))) { + + int max = param.getMaxBounds(); + int min = param.getMinBounds(); + + if ((min < max)) { + + displaySlider(paramViewHolder, param, position); + } else { + displayLabel(paramViewHolder, param, position); + } + } + } else if (AppConstants.UI_TYPE_HUE_SLIDER.equalsIgnoreCase(param.getUiType())) { + + displayPalette(paramViewHolder, param, position); + } else if (AppConstants.UI_TYPE_TOGGLE.equalsIgnoreCase(param.getUiType())) { + + String dataType = param.getDataType(); + + if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("bool") + || dataType.equalsIgnoreCase("boolean"))) { + + displayToggle(paramViewHolder, param); - displaySlider(myViewHolder, param, position); } else { - displayLabel(myViewHolder, param, position); + displayLabel(paramViewHolder, param, position); } - } - } else if (AppConstants.UI_TYPE_HUE_SLIDER.equalsIgnoreCase(param.getUiType())) { + } else if (AppConstants.UI_TYPE_DROP_DOWN.equalsIgnoreCase(param.getUiType())) { - displayPalette(myViewHolder, param, position); - } else if (AppConstants.UI_TYPE_TOGGLE.equalsIgnoreCase(param.getUiType())) { + String dataType = param.getDataType(); - String dataType = param.getDataType(); + if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("string"))) { + + displaySpinner(paramViewHolder, param, position); - if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("bool") - || dataType.equalsIgnoreCase("boolean"))) { + } else if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") + || dataType.equalsIgnoreCase("integer"))) { - displayToggle(myViewHolder, param); + int max = param.getMaxBounds(); + int min = param.getMinBounds(); + int stepCount = (int) param.getStepCount(); + if (stepCount == 0) { + stepCount = 1; + } + ArrayList spinnerValues = new ArrayList<>(); + for (int i = min; i <= max; i = i + stepCount) { + spinnerValues.add(String.valueOf(i)); + } + if ((min < max)) { + displaySpinner(paramViewHolder, param, position); + } else { + if (spinnerValues.size() > 0) { + displaySpinner(paramViewHolder, param, position); + } else { + displayLabel(paramViewHolder, param, position); + } + } + } else { + displayLabel(paramViewHolder, param, position); + } } else { - displayLabel(myViewHolder, param, position); + displayLabel(paramViewHolder, param, position); } + } else if (holder.getItemViewType() == VIEW_TYPE_PUSH_BTN_BIG) { - } else if (AppConstants.UI_TYPE_DROP_DOWN.equalsIgnoreCase(param.getUiType())) { + final SwitchViewHolder switchViewHolder = (SwitchViewHolder) holder; - String dataType = param.getDataType(); + if (param.getSwitchStatus()) { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_on); + } else { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_off); + } + + if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { - if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("string"))) { + if (((EspDeviceActivity) context).isNodeOnline()) { - displaySpinner(myViewHolder, param, position); + switchViewHolder.ivSwitch.setAlpha(1f); + switchViewHolder.ivSwitch.setEnabled(true); - } else if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") - || dataType.equalsIgnoreCase("integer"))) { + switchViewHolder.ivSwitch.setOnClickListener(new View.OnClickListener() { - int max = param.getMaxBounds(); - int min = param.getMinBounds(); - int stepCount = (int) param.getStepCount(); - if (stepCount == 0) { - stepCount = 1; - } - ArrayList spinnerValues = new ArrayList<>(); - for (int i = min; i <= max; i = i + stepCount) { - spinnerValues.add(String.valueOf(i)); + @Override + public void onClick(View v) { + ((EspDeviceActivity) context).stopUpdateValueTask(); + ((EspDeviceActivity) context).showParamUpdateLoading("Updating..."); + + JsonObject jsonParam = new JsonObject(); + JsonObject body = new JsonObject(); + + jsonParam.addProperty(param.getName(), !param.getSwitchStatus()); + body.add(deviceName, jsonParam); + + networkApiManager.updateParamValue(nodeId, body, new ApiResponseListener() { + + @Override + public void onSuccess(Bundle data) { + param.setSwitchStatus(!param.getSwitchStatus()); + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + if (param.getSwitchStatus()) { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_on); + } else { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_off); + } + } + + @Override + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + if (param.getSwitchStatus()) { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_on); + } else { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_off); + } + } + + @Override + public void onNetworkFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + if (param.getSwitchStatus()) { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_on); + } else { + switchViewHolder.ivSwitch.setImageResource(R.drawable.ic_switch_off); + } + } + }); + } + }); + } else { + switchViewHolder.ivSwitch.setAlpha(0.5f); + switchViewHolder.ivSwitch.setEnabled(false); } + } else { + switchViewHolder.ivSwitch.setEnabled(false); + } + + } else if (holder.getItemViewType() == VIEW_TYPE_HUE) { + + final HueViewHolder hueViewHolder = (HueViewHolder) holder; + + int hueColor = (int) param.getValue(); + + float[] hsv = new float[3]; + hsv[0] = hueColor; + hsv[1] = 10.0f; + hsv[2] = 10.0f; + + Log.e(TAG, "hsv[0] : " + hsv[0]); + int mCurrentIntColor = Color.HSVToColor(hsv); + hueViewHolder.colorPickerView.setShowOldCenterColor(false); + hueViewHolder.colorPickerView.setColor(mCurrentIntColor); + + if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { + + if (((EspDeviceActivity) context).isNodeOnline()) { + + hueViewHolder.colorPickerView.setAlpha(1f); + hueViewHolder.colorPickerView.setEnabled(true); + + hueViewHolder.colorPickerView.setOnColorChangedListener(new ColorPicker.OnColorChangedListener() { + + @Override + public void onColorChanged(int color) { + Log.e(TAG, "====================== onColorChanged : Stop updates"); + ((EspDeviceActivity) context).stopUpdateValueTask(); + } + }); + + hueViewHolder.colorPickerView.setOnColorSelectedListener(new ColorPicker.OnColorSelectedListener() { + @Override + public void onColorSelected(int color) { + Log.e(TAG, "====================== onColorSelected : " + color); + Log.e(TAG, "Color : " + hueViewHolder.colorPickerView.getColor()); + float[] newHsv = new float[3]; + Color.colorToHSV(color, newHsv); + int hue = (int) newHsv[0]; + Log.e(TAG, "New Hue color : " + hue); + + JsonObject jsonParam = new JsonObject(); + JsonObject body = new JsonObject(); + jsonParam.addProperty(param.getName(), hue); + body.add(deviceName, jsonParam); + + ((EspDeviceActivity) context).stopUpdateValueTask(); + ((EspDeviceActivity) context).showParamUpdateLoading("Updating..."); + Log.e(TAG, "Body : " + body.toString()); + + networkApiManager.updateParamValue(nodeId, body, new ApiResponseListener() { + + @Override + public void onSuccess(Bundle data) { + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + } + + @Override + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + } - if ((min < max)) { - displaySpinner(myViewHolder, param, position); + @Override + public void onNetworkFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + ((EspDeviceActivity) context).hideParamUpdateLoading(); + } + }); + } + }); } else { - if (spinnerValues.size() > 0) { - displaySpinner(myViewHolder, param, position); - } else { - displayLabel(myViewHolder, param, position); - } + hueViewHolder.colorPickerView.setAlpha(0.5f); + hueViewHolder.colorPickerView.setEnabled(false); + hueViewHolder.colorPickerView.setOnColorChangedListener(null); + hueViewHolder.colorPickerView.setOnColorChangedListener(null); } } else { - displayLabel(myViewHolder, param, position); + hueViewHolder.colorPickerView.setEnabled(false); + hueViewHolder.colorPickerView.setOnColorChangedListener(null); + hueViewHolder.colorPickerView.setOnColorChangedListener(null); } - } else { - displayLabel(myViewHolder, param, position); } } @@ -169,29 +408,66 @@ public int getItemCount() { return params.size(); } - public void updateList(ArrayList updatedDeviceList) { - params = updatedDeviceList; + public void updateList(ArrayList paramList) { + + int firstParamIndex = -1; + for (int i = 0; i < paramList.size(); i++) { + + Param param = paramList.get(i); + if (param != null && AppConstants.UI_TYPE_HUE_SLIDER.equalsIgnoreCase(param.getUiType())) { + firstParamIndex = i; + break; + } + } + + if (firstParamIndex != -1) { + Param paramToBeMoved = paramList.remove(firstParamIndex); + paramList.add(0, paramToBeMoved); + } else { + + if (AppConstants.ESP_DEVICE_SWITCH.equals(device.getDeviceType())) { + + for (int i = 0; i < paramList.size(); i++) { + + Param param = paramList.get(i); + String dataType = param.getDataType(); + + if (param != null && AppConstants.PARAM_TYPE_POWER.equals(param.getParamType()) + && AppConstants.UI_TYPE_TOGGLE.equalsIgnoreCase(param.getUiType()) + && (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("bool") || dataType.equalsIgnoreCase("boolean")))) { + firstParamIndex = i; + break; + } + } + } + if (firstParamIndex != -1) { + Param paramToBeMoved = paramList.remove(firstParamIndex); + paramList.add(0, paramToBeMoved); + } + } + + this.params = paramList; notifyDataSetChanged(); } - private void displayPalette(MyViewHolder myViewHolder, final Param param, final int position) { + private void displayPalette(ParamViewHolder paramViewHolder, final Param param, final int position) { - myViewHolder.rvUiTypeSlider.setVisibility(View.GONE); - myViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); - myViewHolder.rvUiTypeLabel.setVisibility(View.GONE); - myViewHolder.rvPalette.setVisibility(View.VISIBLE); - myViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSlider.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); + paramViewHolder.rvUiTypeLabel.setVisibility(View.GONE); + paramViewHolder.rvPalette.setVisibility(View.VISIBLE); + paramViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); - myViewHolder.tvLabelPalette.setText(param.getName()); - myViewHolder.paletteBar.setColor((int) param.getValue()); - myViewHolder.paletteBar.setThumbCircleRadius(17); - myViewHolder.paletteBar.setTrackMarkHeight(10); + paramViewHolder.tvLabelPalette.setText(param.getName()); + paramViewHolder.paletteBar.setColor((int) param.getValue()); + paramViewHolder.paletteBar.setThumbCircleRadius(17); + paramViewHolder.paletteBar.setTrackMarkHeight(10); if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { if (((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.paletteBar.setEnabled(true); - myViewHolder.paletteBar.setListener(new PaletteBar.PaletteBarListener() { + paramViewHolder.paletteBar.setEnabled(true); + paramViewHolder.paletteBar.setListener(new PaletteBar.PaletteBarListener() { @Override public void onColorSelected(int colorInt) { @@ -209,60 +485,91 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + } + + @Override + public void onNetworkFailure(Exception exception) { ((EspDeviceActivity) context).startUpdateValueTask(); } }); } }); } else { - myViewHolder.paletteBar.setEnabled(false); + paramViewHolder.paletteBar.setEnabled(false); } } } - private void displaySlider(final MyViewHolder myViewHolder, final Param param, final int position) { + private void displaySlider(final ParamViewHolder paramViewHolder, final Param param, final int position) { - myViewHolder.rvUiTypeSlider.setVisibility(View.VISIBLE); - myViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); - myViewHolder.rvUiTypeLabel.setVisibility(View.GONE); - myViewHolder.rvPalette.setVisibility(View.GONE); - myViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSlider.setVisibility(View.VISIBLE); + paramViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); + paramViewHolder.rvUiTypeLabel.setVisibility(View.GONE); + paramViewHolder.rvPalette.setVisibility(View.GONE); + paramViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); double sliderValue = param.getValue(); - myViewHolder.tvSliderName.setText(param.getName()); + paramViewHolder.tvSliderName.setText(param.getName()); float max = param.getMaxBounds(); float min = param.getMinBounds(); String dataType = param.getDataType(); + if (AppConstants.PARAM_TYPE_CCT.equals(param.getParamType())) { + + paramViewHolder.ivSliderStart.setImageResource(R.drawable.ic_cct_low); + paramViewHolder.ivSliderEnd.setImageResource(R.drawable.ic_cct_high); + paramViewHolder.ivSliderStart.setVisibility(View.VISIBLE); + paramViewHolder.ivSliderEnd.setVisibility(View.VISIBLE); + + } else if (AppConstants.PARAM_TYPE_BRIGHTNESS.equals(param.getParamType())) { + + paramViewHolder.ivSliderStart.setImageResource(R.drawable.ic_brightness_low); + paramViewHolder.ivSliderEnd.setImageResource(R.drawable.ic_brightness_high); + paramViewHolder.ivSliderStart.setVisibility(View.VISIBLE); + paramViewHolder.ivSliderEnd.setVisibility(View.VISIBLE); + + } else if (AppConstants.PARAM_TYPE_SATURATION.equals(param.getParamType())) { + + paramViewHolder.ivSliderStart.setImageResource(R.drawable.ic_saturation_low); + paramViewHolder.ivSliderEnd.setImageResource(R.drawable.ic_saturation_high); + paramViewHolder.ivSliderStart.setVisibility(View.VISIBLE); + paramViewHolder.ivSliderEnd.setVisibility(View.VISIBLE); + + } else { + paramViewHolder.ivSliderStart.setVisibility(View.GONE); + paramViewHolder.ivSliderEnd.setVisibility(View.GONE); + } + if (dataType.equalsIgnoreCase("int") || dataType.equalsIgnoreCase("integer")) { - myViewHolder.intSlider.setVisibility(View.VISIBLE); - myViewHolder.floatSlider.setVisibility(View.GONE); + paramViewHolder.intSlider.setVisibility(View.VISIBLE); + paramViewHolder.floatSlider.setVisibility(View.GONE); - myViewHolder.intSlider.setMax(max); - myViewHolder.intSlider.setMin(min); - myViewHolder.intSlider.setTickCount(2); + paramViewHolder.intSlider.setMax(max); + paramViewHolder.intSlider.setMin(min); + paramViewHolder.intSlider.setTickCount(2); if (sliderValue < min) { - myViewHolder.intSlider.setProgress(min); + paramViewHolder.intSlider.setProgress(min); } else if (sliderValue > max) { - myViewHolder.intSlider.setProgress(max); + paramViewHolder.intSlider.setProgress(max); } else { - myViewHolder.intSlider.setProgress((int) sliderValue); + paramViewHolder.intSlider.setProgress((int) sliderValue); } if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { if (((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.intSlider.setEnabled(true); + paramViewHolder.intSlider.setEnabled(true); - myViewHolder.intSlider.setOnSeekChangeListener(new OnSeekChangeListener() { + paramViewHolder.intSlider.setOnSeekChangeListener(new OnSeekChangeListener() { @Override public void onSeeking(SeekParams seekParams) { @@ -293,7 +600,12 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + } + + @Override + public void onNetworkFailure(Exception exception) { ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -302,12 +614,12 @@ public void onFailure(Exception exception) { } else { - myViewHolder.intSlider.setEnabled(false); + paramViewHolder.intSlider.setEnabled(false); } } else { - myViewHolder.intSlider.setOnTouchListener(new View.OnTouchListener() { + paramViewHolder.intSlider.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; @@ -316,32 +628,32 @@ public boolean onTouch(View v, MotionEvent event) { } } else { - myViewHolder.intSlider.setVisibility(View.GONE); - myViewHolder.floatSlider.setVisibility(View.VISIBLE); + paramViewHolder.intSlider.setVisibility(View.GONE); + paramViewHolder.floatSlider.setVisibility(View.VISIBLE); - myViewHolder.floatSlider.setMax(max); - myViewHolder.floatSlider.setMin(min); - myViewHolder.floatSlider.setTickCount(2); + paramViewHolder.floatSlider.setMax(max); + paramViewHolder.floatSlider.setMin(min); + paramViewHolder.floatSlider.setTickCount(2); if (sliderValue < min) { - myViewHolder.floatSlider.setProgress(min); + paramViewHolder.floatSlider.setProgress(min); } else if (sliderValue > max) { - myViewHolder.floatSlider.setProgress(max); + paramViewHolder.floatSlider.setProgress(max); } else { - myViewHolder.floatSlider.setProgress((float) sliderValue); + paramViewHolder.floatSlider.setProgress((float) sliderValue); } if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { if (((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.floatSlider.setEnabled(true); + paramViewHolder.floatSlider.setEnabled(true); - myViewHolder.floatSlider.setOnSeekChangeListener(new OnSeekChangeListener() { + paramViewHolder.floatSlider.setOnSeekChangeListener(new OnSeekChangeListener() { @Override public void onSeeking(SeekParams seekParams) { @@ -372,7 +684,12 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + } + + @Override + public void onNetworkFailure(Exception exception) { ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -380,12 +697,12 @@ public void onFailure(Exception exception) { }); } else { - myViewHolder.floatSlider.setEnabled(false); + paramViewHolder.floatSlider.setEnabled(false); } } else { - myViewHolder.floatSlider.setOnTouchListener(new View.OnTouchListener() { + paramViewHolder.floatSlider.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; @@ -395,36 +712,36 @@ public boolean onTouch(View v, MotionEvent event) { } } - private void displayToggle(final MyViewHolder myViewHolder, final Param param) { + private void displayToggle(final ParamViewHolder paramViewHolder, final Param param) { - myViewHolder.rvUiTypeLabel.setVisibility(View.GONE); - myViewHolder.rvUiTypeSlider.setVisibility(View.GONE); - myViewHolder.rvUiTypeSwitch.setVisibility(View.VISIBLE); - myViewHolder.rvPalette.setVisibility(View.GONE); - myViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); + paramViewHolder.rvUiTypeLabel.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSlider.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSwitch.setVisibility(View.VISIBLE); + paramViewHolder.rvPalette.setVisibility(View.GONE); + paramViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); - myViewHolder.tvSwitchName.setText(param.getName()); - myViewHolder.tvSwitchStatus.setVisibility(View.VISIBLE); + paramViewHolder.tvSwitchName.setText(param.getName()); + paramViewHolder.tvSwitchStatus.setVisibility(View.VISIBLE); if (param.getSwitchStatus()) { - myViewHolder.tvSwitchStatus.setText(R.string.text_on); + paramViewHolder.tvSwitchStatus.setText(R.string.text_on); } else { - myViewHolder.tvSwitchStatus.setText(R.string.text_off); + paramViewHolder.tvSwitchStatus.setText(R.string.text_off); } if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE)) { - myViewHolder.toggleSwitch.setVisibility(View.VISIBLE); - myViewHolder.toggleSwitch.setOnCheckedChangeListener(null); - myViewHolder.toggleSwitch.setChecked(param.getSwitchStatus()); + paramViewHolder.toggleSwitch.setVisibility(View.VISIBLE); + paramViewHolder.toggleSwitch.setOnCheckedChangeListener(null); + paramViewHolder.toggleSwitch.setChecked(param.getSwitchStatus()); if (((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.toggleSwitch.setEnabled(true); + paramViewHolder.toggleSwitch.setEnabled(true); - myViewHolder.toggleSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + paramViewHolder.toggleSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { @@ -433,10 +750,10 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { - myViewHolder.tvSwitchStatus.setText(R.string.text_on); + paramViewHolder.tvSwitchStatus.setText(R.string.text_on); } else { - myViewHolder.tvSwitchStatus.setText(R.string.text_off); + paramViewHolder.tvSwitchStatus.setText(R.string.text_off); } JsonObject jsonParam = new JsonObject(); @@ -453,7 +770,12 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + ((EspDeviceActivity) context).startUpdateValueTask(); + } + + @Override + public void onNetworkFailure(Exception exception) { ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -461,57 +783,57 @@ public void onFailure(Exception exception) { }); } else { - myViewHolder.toggleSwitch.setEnabled(false); + paramViewHolder.toggleSwitch.setEnabled(false); } } else { - myViewHolder.toggleSwitch.setVisibility(View.GONE); + paramViewHolder.toggleSwitch.setVisibility(View.GONE); } } - private void displayLabel(final MyViewHolder myViewHolder, final Param param, final int position) { + private void displayLabel(final ParamViewHolder paramViewHolder, final Param param, final int position) { - myViewHolder.rvUiTypeSlider.setVisibility(View.GONE); - myViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); - myViewHolder.rvUiTypeLabel.setVisibility(View.VISIBLE); - myViewHolder.rvPalette.setVisibility(View.GONE); - myViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSlider.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); + paramViewHolder.rvUiTypeLabel.setVisibility(View.VISIBLE); + paramViewHolder.rvPalette.setVisibility(View.GONE); + paramViewHolder.rvUiTypeDropDown.setVisibility(View.GONE); - myViewHolder.tvLabelName.setText(param.getName()); - myViewHolder.tvLabelValue.setText(param.getLabelValue()); + paramViewHolder.tvLabelName.setText(param.getName()); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE) && ((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.btnEdit.setOnClickListener(new View.OnClickListener() { + paramViewHolder.btnEdit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - askForNewValue(myViewHolder, param, position); + askForNewValue(paramViewHolder, param, position); } }); } else { - myViewHolder.btnEdit.setVisibility(View.GONE); + paramViewHolder.btnEdit.setVisibility(View.GONE); } } - private void displaySpinner(final MyViewHolder myViewHolder, final Param param, final int position) { + private void displaySpinner(final ParamViewHolder paramViewHolder, final Param param, final int position) { - myViewHolder.rvUiTypeSlider.setVisibility(View.GONE); - myViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); - myViewHolder.rvUiTypeLabel.setVisibility(View.GONE); - myViewHolder.rvPalette.setVisibility(View.GONE); - myViewHolder.rvUiTypeDropDown.setVisibility(View.VISIBLE); + paramViewHolder.rvUiTypeSlider.setVisibility(View.GONE); + paramViewHolder.rvUiTypeSwitch.setVisibility(View.GONE); + paramViewHolder.rvUiTypeLabel.setVisibility(View.GONE); + paramViewHolder.rvPalette.setVisibility(View.GONE); + paramViewHolder.rvUiTypeDropDown.setVisibility(View.VISIBLE); - myViewHolder.tvSpinnerName.setText(param.getName()); - myViewHolder.spinner.setVisibility(View.VISIBLE); + paramViewHolder.tvSpinnerName.setText(param.getName()); + paramViewHolder.spinner.setVisibility(View.VISIBLE); - myViewHolder.spinner.setEnabled(false); - myViewHolder.spinner.setOnItemSelectedListener(null); + paramViewHolder.spinner.setEnabled(false); + paramViewHolder.spinner.setOnItemSelectedListener(null); final String dataType = param.getDataType(); @@ -523,7 +845,7 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, spinnerValues.addAll(param.getValidStrings()); ArrayAdapter dataAdapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerValues); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - myViewHolder.spinner.setAdapter(dataAdapter); + paramViewHolder.spinner.setAdapter(dataAdapter); boolean isValueFound = false; String value = param.getLabelValue(); @@ -533,8 +855,8 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, if (value.equals(param.getValidStrings().get(i))) { isValueFound = true; - myViewHolder.spinner.setSelection(i, false); - myViewHolder.spinner.setTag(R.id.position, i); + paramViewHolder.spinner.setSelection(i, false); + paramViewHolder.spinner.setTag(R.id.position, i); break; } } @@ -542,14 +864,14 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, if (!isValueFound) { spinnerValues.add(0, ""); - myViewHolder.spinner.setSelection(0, false); - myViewHolder.spinner.setTag(R.id.position, 0); + paramViewHolder.spinner.setSelection(0, false); + paramViewHolder.spinner.setTag(R.id.position, 0); dataAdapter.notifyDataSetChanged(); String strInvalidValue = "" + value + " (" + context.getString(R.string.invalid) + ")"; - myViewHolder.tvSpinnerValue.setText(strInvalidValue); - myViewHolder.tvSpinnerValue.setVisibility(View.VISIBLE); + paramViewHolder.tvSpinnerValue.setText(strInvalidValue); + paramViewHolder.tvSpinnerValue.setVisibility(View.VISIBLE); } else { - myViewHolder.tvSpinnerValue.setVisibility(View.GONE); + paramViewHolder.tvSpinnerValue.setVisibility(View.GONE); } } } else if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") @@ -572,18 +894,18 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, ArrayAdapter dataAdapter = new ArrayAdapter(context, android.R.layout.simple_spinner_item, spinnerValues); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - myViewHolder.spinner.setAdapter(dataAdapter); + paramViewHolder.spinner.setAdapter(dataAdapter); if (sliderValue < min) { - myViewHolder.spinner.setSelection(0); - myViewHolder.spinner.setTag(R.id.position, 0); + paramViewHolder.spinner.setSelection(0); + paramViewHolder.spinner.setTag(R.id.position, 0); } else if (sliderValue > max) { int lastPosition = spinnerValues.size() - 1; - myViewHolder.spinner.setSelection(lastPosition); - myViewHolder.spinner.setTag(R.id.position, lastPosition); + paramViewHolder.spinner.setSelection(lastPosition); + paramViewHolder.spinner.setTag(R.id.position, lastPosition); } else { @@ -595,22 +917,22 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, if (sliderValue == intValue) { isValueFound = true; - myViewHolder.spinner.setSelection(i, false); - myViewHolder.spinner.setTag(R.id.position, i); + paramViewHolder.spinner.setSelection(i, false); + paramViewHolder.spinner.setTag(R.id.position, i); break; } } if (!isValueFound) { spinnerValues.add(0, ""); - myViewHolder.spinner.setSelection(0, false); - myViewHolder.spinner.setTag(R.id.position, 0); + paramViewHolder.spinner.setSelection(0, false); + paramViewHolder.spinner.setTag(R.id.position, 0); dataAdapter.notifyDataSetChanged(); String strInvalidValue = "" + sliderValue + " (" + context.getString(R.string.invalid) + ")"; - myViewHolder.tvSpinnerValue.setText(strInvalidValue); - myViewHolder.tvSpinnerValue.setVisibility(View.VISIBLE); + paramViewHolder.tvSpinnerValue.setText(strInvalidValue); + paramViewHolder.tvSpinnerValue.setVisibility(View.VISIBLE); } else { - myViewHolder.tvSpinnerValue.setVisibility(View.GONE); + paramViewHolder.tvSpinnerValue.setVisibility(View.GONE); } } } else { @@ -620,7 +942,7 @@ private void displaySpinner(final MyViewHolder myViewHolder, final Param param, if (param.getProperties().contains(AppConstants.KEY_PROPERTY_WRITE) && ((EspDeviceActivity) context).isNodeOnline()) { - myViewHolder.spinner.setSpinnerEventsListener(new EspDropDown.OnSpinnerEventsListener() { + paramViewHolder.spinner.setSpinnerEventsListener(new EspDropDown.OnSpinnerEventsListener() { @Override public void onSpinnerOpened(Spinner spin) { @@ -633,18 +955,18 @@ public void onSpinnerClosed(Spinner spin) { } }); - myViewHolder.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + paramViewHolder.spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView parent, View view, final int pos, long id) { - Log.d(TAG, "Dropdown list item clicked position : " + myViewHolder.spinner.getTag(R.id.position)); + Log.d(TAG, "Dropdown list item clicked position : " + paramViewHolder.spinner.getTag(R.id.position)); - if ((int) myViewHolder.spinner.getTag(R.id.position) != pos) { + if ((int) paramViewHolder.spinner.getTag(R.id.position) != pos) { final String newValue = parent.getItemAtPosition(pos).toString(); - myViewHolder.spinner.setVisibility(View.GONE); - myViewHolder.progressBarSpinner.setVisibility(View.VISIBLE); + paramViewHolder.spinner.setVisibility(View.GONE); + paramViewHolder.progressBarSpinner.setVisibility(View.VISIBLE); ((EspDeviceActivity) context).stopUpdateValueTask(); @@ -671,20 +993,20 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.progressBarSpinner.setVisibility(View.GONE); - myViewHolder.spinner.setVisibility(View.VISIBLE); - myViewHolder.spinner.setTag(R.id.position, pos); + paramViewHolder.progressBarSpinner.setVisibility(View.GONE); + paramViewHolder.spinner.setVisibility(View.VISIBLE); + paramViewHolder.spinner.setTag(R.id.position, pos); if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("string"))) { params.get(position).setLabelValue(newValue); - myViewHolder.tvSpinnerValue.setVisibility(View.GONE); + paramViewHolder.tvSpinnerValue.setVisibility(View.GONE); } else if (!TextUtils.isEmpty(dataType) && (dataType.equalsIgnoreCase("int") || dataType.equalsIgnoreCase("integer"))) { params.get(position).setValue(Integer.parseInt(newValue)); - myViewHolder.tvSpinnerValue.setVisibility(View.GONE); + paramViewHolder.tvSpinnerValue.setVisibility(View.GONE); } ((EspDeviceActivity) context).startUpdateValueTask(); @@ -693,13 +1015,26 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + context.runOnUiThread(new Runnable() { + @Override + public void run() { + paramViewHolder.progressBarSpinner.setVisibility(View.GONE); + paramViewHolder.spinner.setVisibility(View.VISIBLE); + ((EspDeviceActivity) context).startUpdateValueTask(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { context.runOnUiThread(new Runnable() { @Override public void run() { - myViewHolder.progressBarSpinner.setVisibility(View.GONE); - myViewHolder.spinner.setVisibility(View.VISIBLE); + paramViewHolder.progressBarSpinner.setVisibility(View.GONE); + paramViewHolder.spinner.setVisibility(View.VISIBLE); ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -712,14 +1047,14 @@ public void run() { public void onNothingSelected(AdapterView parent) { } }); - myViewHolder.spinner.setEnabled(true); + paramViewHolder.spinner.setEnabled(true); } else { - myViewHolder.spinner.setOnItemSelectedListener(null); + paramViewHolder.spinner.setOnItemSelectedListener(null); } } - private void askForNewValue(final MyViewHolder myViewHolder, final Param param, final int position) { + private void askForNewValue(final ParamViewHolder paramViewHolder, final Param param, final int position) { final AlertDialog.Builder builder = new AlertDialog.Builder(context); LayoutInflater inflater = context.getLayoutInflater(); @@ -793,8 +1128,8 @@ public void onClick(DialogInterface dialog, int which) { isOn = true; } - myViewHolder.btnEdit.setVisibility(View.GONE); - myViewHolder.progressBar.setVisibility(View.VISIBLE); + paramViewHolder.btnEdit.setVisibility(View.GONE); + paramViewHolder.progressBar.setVisibility(View.VISIBLE); jsonParam.addProperty(param.getName(), isOn); body.add(deviceName, jsonParam); @@ -810,16 +1145,16 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); if (finalIsOn) { - myViewHolder.tvLabelValue.setText("true"); + paramViewHolder.tvLabelValue.setText("true"); params.get(position).setLabelValue("true"); } else { - myViewHolder.tvLabelValue.setText("false"); + paramViewHolder.tvLabelValue.setText("false"); params.get(position).setLabelValue("false"); } ((EspDeviceActivity) context).startUpdateValueTask(); @@ -828,16 +1163,32 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { context.runOnUiThread(new Runnable() { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(param.getLabelValue()); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); + ((EspDeviceActivity) context).startUpdateValueTask(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { + + context.runOnUiThread(new Runnable() { + + @Override + public void run() { + + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -871,9 +1222,9 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(value); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(value); params.get(position).setLabelValue(value); ((EspDeviceActivity) context).startUpdateValueTask(); } @@ -881,15 +1232,30 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { context.runOnUiThread(new Runnable() { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(param.getLabelValue()); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); + ((EspDeviceActivity) context).startUpdateValueTask(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { + + context.runOnUiThread(new Runnable() { + + @Override + public void run() { + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -912,9 +1278,9 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(value); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(value); params.get(position).setLabelValue(value); ((EspDeviceActivity) context).startUpdateValueTask(); } @@ -922,15 +1288,30 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + + context.runOnUiThread(new Runnable() { + + @Override + public void run() { + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); + ((EspDeviceActivity) context).startUpdateValueTask(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { context.runOnUiThread(new Runnable() { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(param.getLabelValue()); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -952,9 +1333,9 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(value); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(value); params.get(position).setLabelValue(value); if (params.get(position).getParamType() != null && params.get(position).getParamType().equals(AppConstants.PARAM_TYPE_NAME)) { @@ -966,15 +1347,30 @@ public void run() { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { context.runOnUiThread(new Runnable() { @Override public void run() { - myViewHolder.btnEdit.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); - myViewHolder.tvLabelValue.setText(param.getLabelValue()); + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); + ((EspDeviceActivity) context).startUpdateValueTask(); + } + }); + } + + @Override + public void onNetworkFailure(Exception exception) { + + context.runOnUiThread(new Runnable() { + + @Override + public void run() { + paramViewHolder.btnEdit.setVisibility(View.VISIBLE); + paramViewHolder.progressBar.setVisibility(View.GONE); + paramViewHolder.tvLabelValue.setText(param.getLabelValue()); ((EspDeviceActivity) context).startUpdateValueTask(); } }); @@ -997,9 +1393,9 @@ public void onClick(DialogInterface dialog, int which) { alertDialog.show(); } - public static class MyViewHolder extends RecyclerView.ViewHolder { + static class ParamViewHolder extends RecyclerView.ViewHolder { - // init the item view's + ImageView ivSliderStart, ivSliderEnd; TickSeekBar intSlider, floatSlider; SwitchCompat toggleSwitch; TextView tvSliderName, tvSwitchName, tvSwitchStatus, tvLabelName, tvLabelValue, tvLabelPalette, tvSpinnerName, tvSpinnerValue; @@ -1009,10 +1405,11 @@ public static class MyViewHolder extends RecyclerView.ViewHolder { PaletteBar paletteBar; EspDropDown spinner; - public MyViewHolder(View itemView) { + public ParamViewHolder(View itemView) { super(itemView); - // get the reference of item view's + ivSliderStart = itemView.findViewById(R.id.iv_slider_start); + ivSliderEnd = itemView.findViewById(R.id.iv_slider_end); intSlider = itemView.findViewById(R.id.card_int_slider); floatSlider = itemView.findViewById(R.id.card_float_slider); toggleSwitch = itemView.findViewById(R.id.card_switch); @@ -1036,4 +1433,24 @@ public MyViewHolder(View itemView) { spinner = itemView.findViewById(R.id.card_spinner); } } + + static class HueViewHolder extends RecyclerView.ViewHolder { + + ColorPicker colorPickerView; + + public HueViewHolder(View itemView) { + super(itemView); + colorPickerView = itemView.findViewById(R.id.hue_color_picker); + } + } + + static class SwitchViewHolder extends RecyclerView.ViewHolder { + + ImageView ivSwitch; + + public SwitchViewHolder(View itemView) { + super(itemView); + ivSwitch = itemView.findViewById(R.id.iv_switch); + } + } } diff --git a/app/src/main/java/com/espressif/ui/adapters/ScheduleActionAdapter.java b/app/src/main/java/com/espressif/ui/adapters/ScheduleActionAdapter.java index 66b895c..4008f6d 100644 --- a/app/src/main/java/com/espressif/ui/adapters/ScheduleActionAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/ScheduleActionAdapter.java @@ -15,7 +15,6 @@ package com.espressif.ui.adapters; import android.app.Activity; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -49,9 +48,7 @@ public ScheduleActionAdapter(Activity context, ArrayList list) { @Override public ActionViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View view = LayoutInflater - .from(parent.getContext()) - .inflate(R.layout.item_action, parent, false); + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_action, parent, false); return new ActionViewHolder(view); } @@ -75,6 +72,10 @@ public void onBindViewHolder(final ActionViewHolder holder, int position) { } } + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); + linearLayoutManager.setOrientation(RecyclerView.VERTICAL); + holder.paramRecyclerView.setLayoutManager(linearLayoutManager); + paramAdapter = new ScheduleParamAdapter(context, this, device, params); holder.paramRecyclerView.setAdapter(paramAdapter); @@ -123,6 +124,8 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { int selectedState = 0; if (isChecked) { selectedState = 1; + d.setExpanded(true); + holder.ivExpandArrow.animate().rotation(90).setInterpolator(new LinearInterpolator()).setDuration(200); } d.setSelectedState(selectedState); @@ -150,7 +153,7 @@ public int getItemCount() { return deviceList == null ? 0 : deviceList.size(); } - public class ActionViewHolder extends RecyclerView.ViewHolder { + static class ActionViewHolder extends RecyclerView.ViewHolder { private TextView tvDeviceName; private ImageView ivExpandArrow; @@ -164,11 +167,6 @@ public ActionViewHolder(View itemView) { ivExpandArrow = itemView.findViewById(R.id.iv_expand_arrow); ivDeviceSelect = itemView.findViewById(R.id.iv_device_select); paramRecyclerView = itemView.findViewById(R.id.rv_param_list); - - // set a LinearLayoutManager with default orientation - LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context); - linearLayoutManager.setOrientation(RecyclerView.VERTICAL); - paramRecyclerView.setLayoutManager(linearLayoutManager); // set LayoutManager to RecyclerView } private void bind(Device device) { diff --git a/app/src/main/java/com/espressif/ui/adapters/ScheduleAdapter.java b/app/src/main/java/com/espressif/ui/adapters/ScheduleAdapter.java index 6b89140..dabdeb2 100644 --- a/app/src/main/java/com/espressif/ui/adapters/ScheduleAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/ScheduleAdapter.java @@ -17,7 +17,6 @@ import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -46,7 +45,7 @@ import java.util.HashSet; import java.util.Set; -public class ScheduleAdapter extends RecyclerView.Adapter { +public class ScheduleAdapter extends RecyclerView.Adapter { private final String TAG = ScheduleAdapter.class.getSimpleName(); @@ -63,25 +62,25 @@ public ScheduleAdapter(Activity context, SchedulesFragment fragment, ArrayList triggers = schedule.getTriggers(); int daysValue = triggers.get(AppConstants.KEY_DAYS); - String days = getDaysText(daysValue); - scheduleTimeText.append(days); - int mins = triggers.get(AppConstants.KEY_MINUTES); int h = mins / 60; int m = mins % 60; if (h < 12) { - if (h < 10) { - scheduleTimeText.append(" at 0" + h + ":"); + scheduleTimeText.append("0" + h + ":"); } else { - scheduleTimeText.append(" at " + h + ":"); + scheduleTimeText.append(h + ":"); } if (m < 10) { @@ -124,14 +119,12 @@ public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int } else { scheduleTimeText.append(m + " AM"); } - } else { h = h - 12; - if (h < 10) { - scheduleTimeText.append(" at 0" + h + ":"); + scheduleTimeText.append("0" + h + ":"); } else { - scheduleTimeText.append(" at " + h + ":"); + scheduleTimeText.append(h + ":"); } if (m < 10) { @@ -140,30 +133,33 @@ public void onBindViewHolder(@NonNull final MyViewHolder myViewHolder, final int scheduleTimeText.append(m + " PM"); } } - myViewHolder.tvScheduleTime.setText(scheduleTimeText); - myViewHolder.itemView.setOnClickListener(new View.OnClickListener() { + scheduleViewHolder.tvScheduleTime.setText(scheduleTimeText); + String days = getDaysText(daysValue); + scheduleViewHolder.tvScheduleDays.setText(days); + + scheduleViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Schedule s = scheduleList.get(myViewHolder.getAdapterPosition()); + Schedule s = scheduleList.get(scheduleViewHolder.getAdapterPosition()); Intent intent = new Intent(context, AddScheduleActivity.class); intent.putExtra(AppConstants.KEY_SCHEDULE, s); context.startActivity(intent); } }); - myViewHolder.switchSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + scheduleViewHolder.switchSchedule.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - myViewHolder.switchSchedule.setVisibility(View.GONE); - myViewHolder.progressBar.setVisibility(View.VISIBLE); + scheduleViewHolder.switchSchedule.setVisibility(View.GONE); + scheduleViewHolder.progressBar.setVisibility(View.VISIBLE); Set nodeIdList = new HashSet<>(); - Schedule schedule = scheduleList.get(myViewHolder.getAdapterPosition()); + Schedule schedule = scheduleList.get(scheduleViewHolder.getAdapterPosition()); ArrayList actions = schedule.getActions(); String operation = AppConstants.KEY_OPERATION_DISABLE; @@ -206,15 +202,33 @@ public void onSuccess(Bundle data) { @Override public void run() { - myViewHolder.switchSchedule.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); + scheduleViewHolder.switchSchedule.setVisibility(View.VISIBLE); + scheduleViewHolder.progressBar.setVisibility(View.GONE); + fragment.updateScheduleList(); + } + }); + } + + @Override + public void onResponseFailure(Exception exception) { + + exception.printStackTrace(); + final String msg = exception.getMessage(); + + context.runOnUiThread(new Runnable() { + + @Override + public void run() { + scheduleViewHolder.switchSchedule.setVisibility(View.VISIBLE); + scheduleViewHolder.progressBar.setVisibility(View.GONE); + Toast.makeText(context, "" + msg, Toast.LENGTH_LONG).show(); fragment.updateScheduleList(); } }); } @Override - public void onFailure(final Exception exception) { + public void onNetworkFailure(final Exception exception) { exception.printStackTrace(); final String msg = exception.getMessage(); @@ -223,8 +237,8 @@ public void onFailure(final Exception exception) { @Override public void run() { - myViewHolder.switchSchedule.setVisibility(View.VISIBLE); - myViewHolder.progressBar.setVisibility(View.GONE); + scheduleViewHolder.switchSchedule.setVisibility(View.VISIBLE); + scheduleViewHolder.progressBar.setVisibility(View.GONE); Toast.makeText(context, "" + msg, Toast.LENGTH_LONG).show(); fragment.updateScheduleList(); } @@ -295,22 +309,21 @@ private String getDaysText(int days) { return daysText.toString(); } - public static class MyViewHolder extends RecyclerView.ViewHolder { + static class ScheduleViewHolder extends RecyclerView.ViewHolder { - // init the item view's SwitchCompat switchSchedule; - TextView tvScheduleName, tvActionDevices, tvScheduleTime; + TextView tvScheduleName, tvActionDevices, tvScheduleTime, tvScheduleDays; ContentLoadingProgressBar progressBar; - public MyViewHolder(View itemView) { + public ScheduleViewHolder(View itemView) { super(itemView); - // get the reference of item view's switchSchedule = itemView.findViewById(R.id.sch_enable_switch); tvScheduleName = itemView.findViewById(R.id.tv_schedule_name); progressBar = itemView.findViewById(R.id.sch_progress_indicator); tvActionDevices = itemView.findViewById(R.id.tv_action_devices); tvScheduleTime = itemView.findViewById(R.id.tv_schedule_time); + tvScheduleDays = itemView.findViewById(R.id.tv_schedule_days); } } } diff --git a/app/src/main/java/com/espressif/ui/adapters/SharedUserAdapter.java b/app/src/main/java/com/espressif/ui/adapters/SharedUserAdapter.java index a7db9e3..454ca5d 100644 --- a/app/src/main/java/com/espressif/ui/adapters/SharedUserAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/SharedUserAdapter.java @@ -282,7 +282,20 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + addMemberViewHolder.ivRightArrow.setVisibility(View.VISIBLE); + addMemberViewHolder.loadingAddMember.setVisibility(View.GONE); + exception.printStackTrace(); + + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_add_member, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { addMemberViewHolder.ivRightArrow.setVisibility(View.VISIBLE); addMemberViewHolder.loadingAddMember.setVisibility(View.GONE); exception.printStackTrace(); @@ -384,7 +397,19 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + memberViewHolder.ivRemoveMember.setVisibility(View.VISIBLE); + memberViewHolder.loadingRemoveMember.setVisibility(View.GONE); + exception.printStackTrace(); + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_remove_member, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { memberViewHolder.ivRemoveMember.setVisibility(View.VISIBLE); memberViewHolder.loadingRemoveMember.setVisibility(View.GONE); exception.printStackTrace(); @@ -416,7 +441,19 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + memberViewHolder.ivRemoveMember.setVisibility(View.VISIBLE); + memberViewHolder.loadingRemoveMember.setVisibility(View.GONE); + exception.printStackTrace(); + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_remove_sharing_req, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onNetworkFailure(Exception exception) { memberViewHolder.ivRemoveMember.setVisibility(View.VISIBLE); memberViewHolder.loadingRemoveMember.setVisibility(View.GONE); exception.printStackTrace(); diff --git a/app/src/main/java/com/espressif/ui/adapters/SharingRequestAdapter.java b/app/src/main/java/com/espressif/ui/adapters/SharingRequestAdapter.java index 17dc9f7..22aa81d 100644 --- a/app/src/main/java/com/espressif/ui/adapters/SharingRequestAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/SharingRequestAdapter.java @@ -55,6 +55,7 @@ public SharingRequestAdapter(Activity context, ArrayList pending this.apiManager = ApiManager.getInstance(context); } + @NonNull @Override public SharingRequestVH onCreateViewHolder(ViewGroup parent, int viewType) { @@ -65,7 +66,7 @@ public SharingRequestVH onCreateViewHolder(ViewGroup parent, int viewType) { } @Override - public void onBindViewHolder(@NonNull final SharingRequestVH myViewHolder, final int position) { + public void onBindViewHolder(@NonNull final SharingRequestVH sharingRequestVH, final int position) { SharingRequest sharingReq = pendingRequests.get(position); StringBuilder text = new StringBuilder(); @@ -84,35 +85,40 @@ public void onBindViewHolder(@NonNull final SharingRequestVH myViewHolder, final text.append(" "); text.append(context.getString(R.string.wants_to_share)); - text.append(" "); + ArrayList deviceNames = new ArrayList<>(); for (int i = 0; i < deviceJsonArray.length(); i++) { - JSONObject deviceObj = deviceJsonArray.optJSONObject(i); if (deviceObj != null) { - String deviceName = deviceObj.optString(AppConstants.KEY_NAME); + deviceNames.add(deviceName); + } + } - if (i != 0) { + int deviceListSize = deviceNames.size(); + if (deviceListSize == 0) { + text = new StringBuilder(); + text.append(displayGeneralText(sharingReq)); + } else if (deviceListSize == 1) { + text.append(" "); + text.append(deviceNames.get(0)); + } else { - if (i == (deviceJsonArray.length() - 1)) { - text.append(" "); - text.append(context.getString(R.string.and)); - text.append(" "); - } else { - text.append(", "); - } + for (int i = 0; i < deviceNames.size(); i++) { + text.append(" "); + if (i == (deviceListSize - 1)) { + text.append(context.getString(R.string.and)); + text.append(" "); + text.append(deviceNames.get(i)); + } else { + text.append(deviceNames.get(i)); + text.append(","); } - text.append(deviceName); - - } else { - text = new StringBuilder(); - text.append(displayGeneralText(sharingReq)); } } text.append(" "); - if (deviceJsonArray.length() > 1) { + if (deviceListSize > 1) { text.append(context.getString(R.string.devices)); } else { text.append(context.getString(R.string.device)); @@ -133,9 +139,9 @@ public void onBindViewHolder(@NonNull final SharingRequestVH myViewHolder, final text.append(displayGeneralText(sharingReq)); } - myViewHolder.tvUserName.setText(text.toString()); + sharingRequestVH.tvUserName.setText(text.toString()); - myViewHolder.layoutBtnAccept.setOnClickListener(new View.OnClickListener() { + sharingRequestVH.layoutBtnAccept.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -154,7 +160,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_get_sharing_request, Toast.LENGTH_SHORT).show(); + } + ((SharingRequestsActivity) context).hideLoading(); + } + + @Override + public void onNetworkFailure(Exception exception) { if (exception instanceof CloudException) { Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); } else { @@ -166,7 +182,7 @@ public void onFailure(Exception exception) { } }); - myViewHolder.layoutBtnDecline.setOnClickListener(new View.OnClickListener() { + sharingRequestVH.layoutBtnDecline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -184,7 +200,17 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + if (exception instanceof CloudException) { + Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, R.string.error_get_sharing_request, Toast.LENGTH_SHORT).show(); + } + ((SharingRequestsActivity) context).hideLoading(); + } + + @Override + public void onNetworkFailure(Exception exception) { if (exception instanceof CloudException) { Toast.makeText(context, exception.getMessage(), Toast.LENGTH_SHORT).show(); } else { @@ -205,6 +231,7 @@ private String displayGeneralText(SharingRequest request) { text.append(context.getString(R.string.wants_to_share)); text.append(" "); text.append(context.getString(R.string.node)); + text.append(" "); ArrayList nodeIds = request.getNodeIds(); for (int i = 0; i < nodeIds.size(); i++) { diff --git a/app/src/main/java/com/espressif/ui/adapters/UserProfileAdapter.java b/app/src/main/java/com/espressif/ui/adapters/UserProfileAdapter.java index 578edb7..1b052be 100644 --- a/app/src/main/java/com/espressif/ui/adapters/UserProfileAdapter.java +++ b/app/src/main/java/com/espressif/ui/adapters/UserProfileAdapter.java @@ -28,6 +28,7 @@ import com.espressif.rainmaker.BuildConfig; import com.espressif.rainmaker.R; import com.espressif.ui.activities.SharingRequestsActivity; +import com.espressif.ui.activities.VoiceServicesActivity; import com.espressif.ui.user_module.ChangePasswordActivity; import java.util.ArrayList; @@ -97,6 +98,10 @@ public void onClick(View v) { Intent openURL = new Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.TERMS_URL)); context.startActivity(openURL); + + } else if (str.equals(context.getString(R.string.voice_services))) { + + context.startActivity(new Intent(context, VoiceServicesActivity.class)); } } }); diff --git a/app/src/main/java/com/espressif/ui/fragments/DevicesFragment.java b/app/src/main/java/com/espressif/ui/fragments/DevicesFragment.java index 6afe35d..a380e11 100644 --- a/app/src/main/java/com/espressif/ui/fragments/DevicesFragment.java +++ b/app/src/main/java/com/espressif/ui/fragments/DevicesFragment.java @@ -131,21 +131,22 @@ public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) { private void updateDeviceUi() { - switch (espApp.getCurrentStatus()) { + switch (espApp.getAppState()) { - case FETCHING_DATA: + case NO_INTERNET: case GET_DATA_SUCCESS: case GET_DATA_FAILED: - updateUiOnSuccess(false); + updateUi(false); break; - case DATA_REFRESHING: - updateUiOnSuccess(true); + case GETTING_DATA: + case REFRESH_DATA: + updateUi(true); break; } } - private void updateUiOnSuccess(boolean isRefreshing) { + private void updateUi(boolean isRefreshing) { groups.clear(); diff --git a/app/src/main/java/com/espressif/ui/fragments/ForgotPasswordFragment.java b/app/src/main/java/com/espressif/ui/fragments/ForgotPasswordFragment.java index c1f8945..676993b 100644 --- a/app/src/main/java/com/espressif/ui/fragments/ForgotPasswordFragment.java +++ b/app/src/main/java/com/espressif/ui/fragments/ForgotPasswordFragment.java @@ -20,7 +20,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.EditText; -import android.widget.ImageView; import android.widget.TextView; import androidx.core.widget.ContentLoadingProgressBar; @@ -36,7 +35,6 @@ public class ForgotPasswordFragment extends Fragment { private EditText etEmail; private MaterialCardView btnResetPassword; private TextView txtResetPasswordBtn; - private ImageView arrowImage; private ContentLoadingProgressBar progressBar; private String email; @@ -59,7 +57,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, // Inflate the layout for this fragment View rootView = inflater.inflate(R.layout.fragment_forgot_password, container, false); Bundle extras = getArguments(); - init(rootView, extras); + initViews(rootView, extras); return rootView; } @@ -71,12 +69,12 @@ public void onClick(View v) { } }; - private void init(View view, Bundle extras) { + private void initViews(View view, Bundle extras) { etEmail = view.findViewById(R.id.et_email); btnResetPassword = view.findViewById(R.id.btn_reset_password); txtResetPasswordBtn = view.findViewById(R.id.text_btn); - arrowImage = view.findViewById(R.id.iv_arrow); + view.findViewById(R.id.iv_arrow).setVisibility(View.GONE); progressBar = view.findViewById(R.id.progress_indicator); if (extras != null) { @@ -114,7 +112,6 @@ private void showLoading() { btnResetPassword.setAlpha(0.5f); txtResetPasswordBtn.setText(R.string.btn_resetting_password); progressBar.setVisibility(View.VISIBLE); - arrowImage.setVisibility(View.GONE); } public void hideLoading() { @@ -123,6 +120,5 @@ public void hideLoading() { btnResetPassword.setAlpha(1f); txtResetPasswordBtn.setText(R.string.btn_reset_password); progressBar.setVisibility(View.GONE); - arrowImage.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/com/espressif/ui/fragments/LoginFragment.java b/app/src/main/java/com/espressif/ui/fragments/LoginFragment.java index 04c0635..6ddf88f 100644 --- a/app/src/main/java/com/espressif/ui/fragments/LoginFragment.java +++ b/app/src/main/java/com/espressif/ui/fragments/LoginFragment.java @@ -118,7 +118,14 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { +// hideGitHubLoginLoading(); +// hideGoogleLoginLoading(); + Toast.makeText(getActivity(), R.string.error_login, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onNetworkFailure(Exception exception) { // hideGitHubLoginLoading(); // hideGoogleLoginLoading(); Toast.makeText(getActivity(), R.string.error_login, Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/com/espressif/ui/fragments/SchedulesFragment.java b/app/src/main/java/com/espressif/ui/fragments/SchedulesFragment.java index 8fe91ff..de0c7ec 100644 --- a/app/src/main/java/com/espressif/ui/fragments/SchedulesFragment.java +++ b/app/src/main/java/com/espressif/ui/fragments/SchedulesFragment.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.Map; public class SchedulesFragment extends Fragment { @@ -96,6 +97,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa return root; } + @Override + public void onResume() { + super.onResume(); + updateScheduleUi(); + } + @Override public void onDestroy() { ((EspMainActivity) getActivity()).removeUpdateListener(updateListener); @@ -136,8 +143,8 @@ private void init(View view) { swipeRefreshLayout = view.findViewById(R.id.swipe_container); btnAddSchedule = view.findViewById(R.id.btn_add_schedule); - txtAddScheduleBtn = view.findViewById(R.id.text_btn); - arrowImage = view.findViewById(R.id.iv_arrow); + txtAddScheduleBtn = btnAddSchedule.findViewById(R.id.text_btn); + arrowImage = btnAddSchedule.findViewById(R.id.iv_arrow); txtAddScheduleBtn.setText(R.string.btn_add_schedule); btnAddSchedule.setVisibility(View.GONE); arrowImage.setVisibility(View.GONE); @@ -161,21 +168,22 @@ public void onRefresh() { private void updateScheduleUi() { - switch (espApp.getCurrentStatus()) { + switch (espApp.getAppState()) { - case FETCHING_DATA: + case NO_INTERNET: case GET_DATA_SUCCESS: case GET_DATA_FAILED: - updateUiOnSuccess(false); + updateUi(false); break; - case DATA_REFRESHING: - updateUiOnSuccess(true); + case GETTING_DATA: + case REFRESH_DATA: + updateUi(true); break; } } - private void updateUiOnSuccess(boolean isRefreshing) { + private void updateUi(boolean isRefreshing) { schedules.clear(); for (Map.Entry entry : espApp.scheduleMap.entrySet()) { @@ -190,12 +198,22 @@ private void updateUiOnSuccess(boolean isRefreshing) { Log.d(TAG, "Schedules size : " + schedules.size()); - // Sort schedule list to display alphabetically. + // Sort schedule list by time. Collections.sort(schedules, new Comparator() { @Override public int compare(Schedule s1, Schedule s2) { - return s1.getName().compareToIgnoreCase(s2.getName()); + HashMap t1 = s1.getTriggers(); + HashMap t2 = s2.getTriggers(); + Integer m1 = t1.get(AppConstants.KEY_MINUTES); + Integer m2 = t2.get(AppConstants.KEY_MINUTES); + if (m1 == null) { + m1 = 0; + } + if (m2 == null) { + m2 = 0; + } + return m1.compareTo(m2); } }); @@ -243,17 +261,7 @@ public int compare(Schedule s1, Schedule s2) { scheduleAdapter.updateList(schedules); swipeRefreshLayout.setRefreshing(isRefreshing); - } - - private void updateUiOnFailure() { - - swipeRefreshLayout.setRefreshing(false); - tvNoSchedule.setText(R.string.error_schedule_not_received); - rlNoSchedules.setVisibility(View.VISIBLE); - tvNoSchedule.setVisibility(View.VISIBLE); - tvAddSchedule.setVisibility(View.GONE); - ivNoSchedule.setVisibility(View.VISIBLE); - recyclerView.setVisibility(View.GONE); + ((EspMainActivity) getActivity()).updateActionBar(); } private void goToAddScheduleActivity() { diff --git a/app/src/main/java/com/espressif/ui/activities/UserProfileActivity.java b/app/src/main/java/com/espressif/ui/fragments/UserProfileFragment.java similarity index 61% rename from app/src/main/java/com/espressif/ui/activities/UserProfileActivity.java rename to app/src/main/java/com/espressif/ui/fragments/UserProfileFragment.java index 20a896a..fbbd3aa 100644 --- a/app/src/main/java/com/espressif/ui/activities/UserProfileActivity.java +++ b/app/src/main/java/com/espressif/ui/fragments/UserProfileFragment.java @@ -12,59 +12,73 @@ // See the License for the specific language governing permissions and // limitations under the License. -package com.espressif.ui.activities; +package com.espressif.ui.fragments; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.View; +import android.view.ViewGroup; import android.widget.RelativeLayout; import android.widget.TextView; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AlertDialog; +import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser; import com.espressif.AppConstants; -import com.espressif.cloudapi.ApiResponseListener; -import com.espressif.db.EspDatabase; import com.espressif.EspApplication; import com.espressif.cloudapi.ApiManager; +import com.espressif.cloudapi.ApiResponseListener; import com.espressif.rainmaker.BuildConfig; import com.espressif.rainmaker.R; +import com.espressif.ui.activities.MainActivity; import com.espressif.ui.adapters.UserProfileAdapter; import com.espressif.ui.models.SharingRequest; -import com.espressif.ui.user_module.AppHelper; import java.util.ArrayList; -public class UserProfileActivity extends AppCompatActivity { +public class UserProfileFragment extends Fragment { - private TextView tvTitle, tvBack, tvCancel; - - private RecyclerView rvUserInfo; private TextView tvAppVersion; - + private RecyclerView rvUserInfo; private UserProfileAdapter userInfoAdapter; + + private EspApplication espApp; private SharedPreferences sharedPreferences; private ArrayList userInfoList; private ArrayList pendingRequests; + public UserProfileFragment() { + // Required empty public constructor + } + + public static UserProfileFragment newInstance() { + return new UserProfileFragment(); + } + @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_user_profile); - overridePendingTransition(R.anim.anim_left_to_right, R.anim.scale_in); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_user_profile, container, false); + espApp = (EspApplication) getActivity().getApplicationContext(); pendingRequests = new ArrayList<>(); - sharedPreferences = getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE); - initViews(); + sharedPreferences = espApp.getSharedPreferences(AppConstants.ESP_PREFERENCES, Context.MODE_PRIVATE); + initViews(rootView); + return rootView; } @Override @@ -73,36 +87,18 @@ public void onResume() { getSharingRequests(); } - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - finish(); - } - }; - - private void initViews() { + private void initViews(View view) { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_user_profile); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.GONE); - tvBack.setOnClickListener(backButtonClickListener); - - TextView tvEmail = findViewById(R.id.tv_email); + TextView tvEmail = view.findViewById(R.id.tv_email); tvEmail.setText(sharedPreferences.getString(AppConstants.KEY_EMAIL, "")); - rvUserInfo = findViewById(R.id.rv_user_profile); - tvAppVersion = findViewById(R.id.tv_app_version); - RelativeLayout logoutView = findViewById(R.id.layout_logout); + rvUserInfo = view.findViewById(R.id.rv_user_profile); + tvAppVersion = view.findViewById(R.id.tv_app_version); + RelativeLayout logoutView = view.findViewById(R.id.rl_logout); String version = ""; try { - PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + PackageInfo pInfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); version = pInfo.versionName; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); @@ -115,36 +111,14 @@ private void initViews() { @Override public void onClick(View v) { - - if (!ApiManager.isOAuthLogin) { - String username = AppHelper.getCurrUser(); - CognitoUser user = AppHelper.getPool().getUser(username); - user.signOut(); - } - - SharedPreferences.Editor editor = sharedPreferences.edit(); - editor.clear(); - editor.apply(); - EspApplication espApp = (EspApplication) getApplicationContext(); - EspDatabase.getInstance(espApp).getNodeDao().deleteAll(); - EspDatabase.getInstance(espApp).getGroupDao().deleteAll(); - espApp.setCurrentStatus(EspApplication.GetDataStatus.FETCHING_DATA); - espApp.nodeMap.clear(); - espApp.scheduleMap.clear(); - espApp.mDNSDeviceMap.clear(); - espApp.groupMap.clear(); - - Intent loginActivity = new Intent(espApp, MainActivity.class); - loginActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity(loginActivity); - finish(); + confirmLogout(); } }); - LinearLayoutManager llm2 = new LinearLayoutManager(getApplicationContext()); + LinearLayoutManager llm2 = new LinearLayoutManager(getActivity()); llm2.setOrientation(RecyclerView.VERTICAL); rvUserInfo.setLayoutManager(llm2); - DividerItemDecoration itemDecor = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL); + DividerItemDecoration itemDecor = new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL); rvUserInfo.addItemDecoration(itemDecor); userInfoList = new ArrayList<>(); @@ -158,14 +132,15 @@ public void onClick(View v) { userInfoList.add(getString(R.string.documentation)); userInfoList.add(getString(R.string.privacy_policy)); userInfoList.add(getString(R.string.terms_of_use)); - userInfoAdapter = new UserProfileAdapter(this, userInfoList, 0); + userInfoList.add(getString(R.string.voice_services)); + userInfoAdapter = new UserProfileAdapter(getActivity(), userInfoList, 0); rvUserInfo.setAdapter(userInfoAdapter); } private void getSharingRequests() { pendingRequests.clear(); - ApiManager apiManager = ApiManager.getInstance(getApplicationContext()); + ApiManager apiManager = ApiManager.getInstance(espApp); apiManager.getSharingRequests(false, new ApiResponseListener() { @Override @@ -187,8 +162,45 @@ public void onSuccess(Bundle data) { } @Override - public void onFailure(Exception exception) { + public void onResponseFailure(Exception exception) { + } + + @Override + public void onNetworkFailure(Exception exception) { } }); } + + private void confirmLogout() { + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(R.string.dialog_title_logout); + builder.setMessage(R.string.dialog_msg_confirmation); + + builder.setPositiveButton(R.string.btn_yes, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + + dialog.dismiss(); + espApp.logout(); + Intent loginActivity = new Intent(espApp, MainActivity.class); + loginActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + startActivity(loginActivity); + getActivity().finish(); + } + }); + + builder.setNegativeButton(R.string.btn_no, new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + + dialog.dismiss(); + } + }); + + AlertDialog userDialog = builder.create(); + userDialog.show(); + } } diff --git a/app/src/main/java/com/espressif/ui/models/UpdateEvent.java b/app/src/main/java/com/espressif/ui/models/UpdateEvent.java index 3cd9444..edf9a51 100644 --- a/app/src/main/java/com/espressif/ui/models/UpdateEvent.java +++ b/app/src/main/java/com/espressif/ui/models/UpdateEvent.java @@ -14,11 +14,22 @@ package com.espressif.ui.models; +import android.os.Bundle; + import com.espressif.AppConstants; public class UpdateEvent { private AppConstants.UpdateEventType eventType; + private Bundle data; + + public Bundle getData() { + return data; + } + + public void setData(Bundle data) { + this.data = data; + } public UpdateEvent(AppConstants.UpdateEventType type) { eventType = type; diff --git a/app/src/main/java/com/espressif/ui/user_module/ChangePasswordActivity.java b/app/src/main/java/com/espressif/ui/user_module/ChangePasswordActivity.java index d623a5f..bca5fde 100755 --- a/app/src/main/java/com/espressif/ui/user_module/ChangePasswordActivity.java +++ b/app/src/main/java/com/espressif/ui/user_module/ChangePasswordActivity.java @@ -21,7 +21,6 @@ import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; @@ -30,17 +29,16 @@ import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.GenericHandler; import com.espressif.rainmaker.R; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; import com.google.android.material.textfield.TextInputLayout; public class ChangePasswordActivity extends AppCompatActivity { - private TextView tvTitle, tvBack, tvCancel; private EditText etOldPassword, etNewPassword, etConfirmNewPassword; private TextInputLayout layoutOldPassword, layoutNewPassword, layoutConfirmPassword; private MaterialCardView btnSetPassword; private TextView txtSetPasswordBtn; - private ImageView arrowImage; private ContentLoadingProgressBar progressBar; private AlertDialog userDialog; @@ -48,21 +46,23 @@ public class ChangePasswordActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_change_password); - init(); + initViews(); } - private void init() { + private void initViews() { - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); - - tvTitle.setText(R.string.title_activity_change_password); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.VISIBLE); - - tvBack.setOnClickListener(backButtonClickListener); - tvCancel.setOnClickListener(cancelButtonClickListener); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_change_password); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); etOldPassword = findViewById(R.id.et_old_password); etNewPassword = findViewById(R.id.et_new_password); @@ -72,7 +72,7 @@ private void init() { layoutConfirmPassword = findViewById(R.id.layout_confirm_new_password); btnSetPassword = findViewById(R.id.btn_set_password); txtSetPasswordBtn = findViewById(R.id.text_btn); - arrowImage = findViewById(R.id.iv_arrow); + findViewById(R.id.iv_arrow).setVisibility(View.GONE); progressBar = findViewById(R.id.progress_indicator); txtSetPasswordBtn.setText(R.string.btn_set_password); @@ -91,24 +91,6 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { }); } - private View.OnClickListener backButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - finish(); - } - }; - - private View.OnClickListener cancelButtonClickListener = new View.OnClickListener() { - - @Override - public void onClick(View v) { - - finish(); - } - }; - private View.OnClickListener setPasswordBtnClickListener = new View.OnClickListener() { @Override @@ -208,7 +190,6 @@ private void showLoading() { btnSetPassword.setAlpha(0.5f); txtSetPasswordBtn.setText(R.string.btn_setting_password); progressBar.setVisibility(View.VISIBLE); - arrowImage.setVisibility(View.GONE); } public void hideLoading() { @@ -217,6 +198,5 @@ public void hideLoading() { btnSetPassword.setAlpha(1f); txtSetPasswordBtn.setText(R.string.btn_set_password); progressBar.setVisibility(View.GONE); - arrowImage.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/com/espressif/ui/user_module/ForgotPasswordActivity.java b/app/src/main/java/com/espressif/ui/user_module/ForgotPasswordActivity.java index ce5ff94..de4f876 100755 --- a/app/src/main/java/com/espressif/ui/user_module/ForgotPasswordActivity.java +++ b/app/src/main/java/com/espressif/ui/user_module/ForgotPasswordActivity.java @@ -17,7 +17,6 @@ import android.content.DialogInterface; import android.os.Bundle; import android.view.View; -import android.widget.TextView; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; @@ -29,20 +28,20 @@ import com.espressif.rainmaker.R; import com.espressif.ui.fragments.ForgotPasswordFragment; import com.espressif.ui.fragments.ResetPasswordFragment; +import com.google.android.material.appbar.MaterialToolbar; public class ForgotPasswordActivity extends AppCompatActivity { private AlertDialog userDialog; private ForgotPasswordContinuation forgotPasswordContinuation; - private TextView tvTitle, tvBack, tvCancel; - private String email; + private MaterialToolbar toolbar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_forgot_password); - init(); + initViews(); } @Override @@ -63,14 +62,20 @@ public void onBackPressed() { } } - private void init() { - - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); + private void initViews() { - tvBack.setOnClickListener(backButtonClickListener); - tvCancel.setOnClickListener(cancelButtonClickListener); + toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_forgot_password); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); Fragment forgotPasswordFragment = new ForgotPasswordFragment(); loadForgotPasswordFragment(forgotPasswordFragment); @@ -78,9 +83,7 @@ private void init() { private void loadForgotPasswordFragment(Fragment forgotPasswordFragment) { - tvTitle.setText(R.string.title_activity_forgot_password); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); + toolbar.setTitle(R.string.title_activity_forgot_password); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, forgotPasswordFragment); @@ -89,9 +92,7 @@ private void loadForgotPasswordFragment(Fragment forgotPasswordFragment) { private void loadResetPasswordFragment(Fragment resetPasswordFragment) { - tvTitle.setText(R.string.title_activity_reset_password); - tvBack.setVisibility(View.VISIBLE); - tvCancel.setVisibility(View.VISIBLE); + toolbar.setTitle(R.string.title_activity_reset_password); FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.fragment_container, resetPasswordFragment); diff --git a/app/src/main/java/com/espressif/ui/user_module/SignUpConfirmActivity.java b/app/src/main/java/com/espressif/ui/user_module/SignUpConfirmActivity.java index 906fa3f..2c26f51 100644 --- a/app/src/main/java/com/espressif/ui/user_module/SignUpConfirmActivity.java +++ b/app/src/main/java/com/espressif/ui/user_module/SignUpConfirmActivity.java @@ -34,6 +34,7 @@ import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.VerificationHandler; import com.espressif.rainmaker.R; import com.espressif.ui.Utils; +import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.card.MaterialCardView; public class SignUpConfirmActivity extends AppCompatActivity { @@ -47,7 +48,6 @@ public class SignUpConfirmActivity extends AppCompatActivity { private ContentLoadingProgressBar progressBar; private TextView tvResendCode; private AlertDialog userDialog; - private TextView tvTitle, tvBack, tvCancel; private String email, password; @@ -55,27 +55,29 @@ public class SignUpConfirmActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sign_up_confirm); - init(); + initViews(); } @Override public void onBackPressed() { - setResult(RESULT_CANCELED, getIntent()); super.onBackPressed(); } - private void init() { - - tvTitle = findViewById(R.id.main_toolbar_title); - tvBack = findViewById(R.id.btn_back); - tvCancel = findViewById(R.id.btn_cancel); + private void initViews() { - tvTitle.setText(R.string.title_activity_sign_up_confirm); - tvBack.setVisibility(View.GONE); - tvCancel.setVisibility(View.VISIBLE); - - tvCancel.setOnClickListener(cancelButtonClickListener); + MaterialToolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + toolbar.setTitle(R.string.title_activity_sign_up_confirm); + toolbar.setNavigationIcon(R.drawable.ic_arrow_left); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); tvConfMsg = findViewById(R.id.tv_sign_up_confirm_msg_1); etEmail = findViewById(R.id.et_email); diff --git a/app/src/main/res/anim/anim_left_to_right.xml b/app/src/main/res/anim/anim_left_to_right.xml deleted file mode 100644 index 4642514..0000000 --- a/app/src/main/res/anim/anim_left_to_right.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - diff --git a/app/src/main/res/anim/scale_in.xml b/app/src/main/res/anim/scale_in.xml deleted file mode 100644 index b954752..0000000 --- a/app/src/main/res/anim/scale_in.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/ic_connect_device.png b/app/src/main/res/drawable-hdpi/ic_connect_device.png deleted file mode 100755 index d7b0879..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_connect_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device.png b/app/src/main/res/drawable-hdpi/ic_device.png deleted file mode 100755 index 93cb18a..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_bulb.png b/app/src/main/res/drawable-hdpi/ic_device_bulb.png deleted file mode 100755 index 8d01201..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_bulb.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_bulb_cct.png b/app/src/main/res/drawable-hdpi/ic_device_bulb_cct.png deleted file mode 100755 index 007238f..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_bulb_cct.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_bulb_rgb.png b/app/src/main/res/drawable-hdpi/ic_device_bulb_rgb.png deleted file mode 100755 index 63a2bef..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_bulb_rgb.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_fan.png b/app/src/main/res/drawable-hdpi/ic_device_fan.png deleted file mode 100755 index b37ce14..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_fan.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_lock.png b/app/src/main/res/drawable-hdpi/ic_device_lock.png deleted file mode 100755 index 5ec14bc..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_switch.png b/app/src/main/res/drawable-hdpi/ic_device_switch.png deleted file mode 100755 index 7f3250a..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_switch.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_temp_sensor.png b/app/src/main/res/drawable-hdpi/ic_device_temp_sensor.png deleted file mode 100644 index 9711a14..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_temp_sensor.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_device_thermostat.png b/app/src/main/res/drawable-hdpi/ic_device_thermostat.png deleted file mode 100755 index 4834b80..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_device_thermostat.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_no_devices.png b/app/src/main/res/drawable-hdpi/ic_no_devices.png deleted file mode 100755 index 324201a..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_no_devices.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_provisioning.png b/app/src/main/res/drawable-hdpi/ic_provisioning.png deleted file mode 100755 index 9effa33..0000000 Binary files a/app/src/main/res/drawable-hdpi/ic_provisioning.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_connect_device.png b/app/src/main/res/drawable-mdpi/ic_connect_device.png deleted file mode 100755 index b152e08..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_connect_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device.png b/app/src/main/res/drawable-mdpi/ic_device.png deleted file mode 100755 index 629ee8b..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_bulb.png b/app/src/main/res/drawable-mdpi/ic_device_bulb.png deleted file mode 100755 index 143ea66..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_bulb.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_bulb_cct.png b/app/src/main/res/drawable-mdpi/ic_device_bulb_cct.png deleted file mode 100755 index 6bc65ca..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_bulb_cct.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_bulb_rgb.png b/app/src/main/res/drawable-mdpi/ic_device_bulb_rgb.png deleted file mode 100755 index e3cdcbd..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_bulb_rgb.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_fan.png b/app/src/main/res/drawable-mdpi/ic_device_fan.png deleted file mode 100755 index cc1d47d..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_fan.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_lock.png b/app/src/main/res/drawable-mdpi/ic_device_lock.png deleted file mode 100755 index 9ba0401..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_switch.png b/app/src/main/res/drawable-mdpi/ic_device_switch.png deleted file mode 100755 index 3c3582a..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_switch.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_temp_sensor.png b/app/src/main/res/drawable-mdpi/ic_device_temp_sensor.png deleted file mode 100644 index 4294fde..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_temp_sensor.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_device_thermostat.png b/app/src/main/res/drawable-mdpi/ic_device_thermostat.png deleted file mode 100755 index 7d057a6..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_device_thermostat.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_no_devices.png b/app/src/main/res/drawable-mdpi/ic_no_devices.png deleted file mode 100755 index 5631ff9..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_no_devices.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_provisioning.png b/app/src/main/res/drawable-mdpi/ic_provisioning.png deleted file mode 100755 index 29966c3..0000000 Binary files a/app/src/main/res/drawable-mdpi/ic_provisioning.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_connect_device.png b/app/src/main/res/drawable-xhdpi/ic_connect_device.png deleted file mode 100755 index 488952c..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_connect_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device.png b/app/src/main/res/drawable-xhdpi/ic_device.png deleted file mode 100755 index 54f4f32..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_bulb.png b/app/src/main/res/drawable-xhdpi/ic_device_bulb.png deleted file mode 100755 index 61489cd..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_bulb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_bulb_cct.png b/app/src/main/res/drawable-xhdpi/ic_device_bulb_cct.png deleted file mode 100755 index 5efaa69..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_bulb_cct.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_bulb_rgb.png b/app/src/main/res/drawable-xhdpi/ic_device_bulb_rgb.png deleted file mode 100755 index 7952eae..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_bulb_rgb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_fan.png b/app/src/main/res/drawable-xhdpi/ic_device_fan.png deleted file mode 100755 index a303886..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_fan.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_lock.png b/app/src/main/res/drawable-xhdpi/ic_device_lock.png deleted file mode 100755 index 8cfea1b..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_switch.png b/app/src/main/res/drawable-xhdpi/ic_device_switch.png deleted file mode 100755 index cc9254a..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_switch.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_temp_sensor.png b/app/src/main/res/drawable-xhdpi/ic_device_temp_sensor.png deleted file mode 100644 index 1ce72e6..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_temp_sensor.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_device_thermostat.png b/app/src/main/res/drawable-xhdpi/ic_device_thermostat.png deleted file mode 100755 index 9247a79..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_device_thermostat.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_no_devices.png b/app/src/main/res/drawable-xhdpi/ic_no_devices.png deleted file mode 100755 index 06b8ebf..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_no_devices.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_provisioning.png b/app/src/main/res/drawable-xhdpi/ic_provisioning.png deleted file mode 100755 index 3a9fb6f..0000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_provisioning.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_connect_device.png b/app/src/main/res/drawable-xxhdpi/ic_connect_device.png deleted file mode 100755 index 0f090a2..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_connect_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device.png b/app/src/main/res/drawable-xxhdpi/ic_device.png deleted file mode 100755 index 81da502..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_bulb.png b/app/src/main/res/drawable-xxhdpi/ic_device_bulb.png deleted file mode 100755 index ed58aed..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_bulb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_bulb_cct.png b/app/src/main/res/drawable-xxhdpi/ic_device_bulb_cct.png deleted file mode 100755 index 8f268dc..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_bulb_cct.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_bulb_rgb.png b/app/src/main/res/drawable-xxhdpi/ic_device_bulb_rgb.png deleted file mode 100755 index de117f4..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_bulb_rgb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_fan.png b/app/src/main/res/drawable-xxhdpi/ic_device_fan.png deleted file mode 100755 index 8f273a4..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_fan.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_lock.png b/app/src/main/res/drawable-xxhdpi/ic_device_lock.png deleted file mode 100755 index 52f8782..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_switch.png b/app/src/main/res/drawable-xxhdpi/ic_device_switch.png deleted file mode 100755 index 484299f..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_switch.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_temp_sensor.png b/app/src/main/res/drawable-xxhdpi/ic_device_temp_sensor.png deleted file mode 100644 index 3612d6b..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_temp_sensor.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_device_thermostat.png b/app/src/main/res/drawable-xxhdpi/ic_device_thermostat.png deleted file mode 100755 index c6c41be..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_device_thermostat.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_no_devices.png b/app/src/main/res/drawable-xxhdpi/ic_no_devices.png deleted file mode 100755 index a74acba..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_no_devices.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_provisioning.png b/app/src/main/res/drawable-xxhdpi/ic_provisioning.png deleted file mode 100755 index 7262525..0000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_provisioning.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_connect_device.png b/app/src/main/res/drawable-xxxhdpi/ic_connect_device.png deleted file mode 100755 index 44a6811..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_connect_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device.png b/app/src/main/res/drawable-xxxhdpi/ic_device.png deleted file mode 100755 index c58bcdd..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb.png b/app/src/main/res/drawable-xxxhdpi/ic_device_bulb.png deleted file mode 100755 index 5bdc07f..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_cct.png b/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_cct.png deleted file mode 100755 index 3dded2e..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_cct.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_rgb.png b/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_rgb.png deleted file mode 100755 index fbd3ffe..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_bulb_rgb.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_fan.png b/app/src/main/res/drawable-xxxhdpi/ic_device_fan.png deleted file mode 100755 index 229c3df..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_fan.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_lock.png b/app/src/main/res/drawable-xxxhdpi/ic_device_lock.png deleted file mode 100755 index 6c3bbe7..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_lock.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_switch.png b/app/src/main/res/drawable-xxxhdpi/ic_device_switch.png deleted file mode 100755 index af86800..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_switch.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_temp_sensor.png b/app/src/main/res/drawable-xxxhdpi/ic_device_temp_sensor.png deleted file mode 100644 index 2bb8fad..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_temp_sensor.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_device_thermostat.png b/app/src/main/res/drawable-xxxhdpi/ic_device_thermostat.png deleted file mode 100755 index a7c8ae4..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_device_thermostat.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_no_devices.png b/app/src/main/res/drawable-xxxhdpi/ic_no_devices.png deleted file mode 100755 index 71d504a..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_no_devices.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_provisioning.png b/app/src/main/res/drawable-xxxhdpi/ic_provisioning.png deleted file mode 100755 index 387912b..0000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_provisioning.png and /dev/null differ diff --git a/app/src/main/res/drawable/bg_dropdown.xml b/app/src/main/res/drawable/bg_dropdown.xml new file mode 100644 index 0000000..14c294a --- /dev/null +++ b/app/src/main/res/drawable/bg_dropdown.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_group_tab.xml b/app/src/main/res/drawable/bg_group_tab.xml new file mode 100644 index 0000000..a8ca31c --- /dev/null +++ b/app/src/main/res/drawable/bg_group_tab.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_group_tab_selected.xml b/app/src/main/res/drawable/bg_group_tab_selected.xml new file mode 100644 index 0000000..ff88acb --- /dev/null +++ b/app/src/main/res/drawable/bg_group_tab_selected.xml @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_home_screen.jpg b/app/src/main/res/drawable/bg_home_screen.jpg new file mode 100644 index 0000000..00e7cfc Binary files /dev/null and b/app/src/main/res/drawable/bg_home_screen.jpg differ diff --git a/app/src/main/res/drawable/bg_image_view.xml b/app/src/main/res/drawable/bg_image_view.xml deleted file mode 100644 index 911e7d6..0000000 --- a/app/src/main/res/drawable/bg_image_view.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_alexa.png b/app/src/main/res/drawable/ic_alexa.png new file mode 100644 index 0000000..24a7448 Binary files /dev/null and b/app/src/main/res/drawable/ic_alexa.png differ diff --git a/app/src/main/res/drawable/ic_arrow_left.xml b/app/src/main/res/drawable/ic_arrow_left.xml new file mode 100644 index 0000000..8c69def --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_left.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_brightness_high.xml b/app/src/main/res/drawable/ic_brightness_high.xml new file mode 100644 index 0000000..ce89e7c --- /dev/null +++ b/app/src/main/res/drawable/ic_brightness_high.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_brightness_low.xml b/app/src/main/res/drawable/ic_brightness_low.xml new file mode 100644 index 0000000..c48f0ee --- /dev/null +++ b/app/src/main/res/drawable/ic_brightness_low.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_cct_high.xml b/app/src/main/res/drawable/ic_cct_high.xml new file mode 100644 index 0000000..f612ca3 --- /dev/null +++ b/app/src/main/res/drawable/ic_cct_high.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_cct_low.xml b/app/src/main/res/drawable/ic_cct_low.xml new file mode 100644 index 0000000..0859ff5 --- /dev/null +++ b/app/src/main/res/drawable/ic_cct_low.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_change_password.xml b/app/src/main/res/drawable/ic_change_password.xml new file mode 100644 index 0000000..f14de92 --- /dev/null +++ b/app/src/main/res/drawable/ic_change_password.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_checkbox_on.xml b/app/src/main/res/drawable/ic_checkbox_on.xml index 782d5e8..7be9625 100644 --- a/app/src/main/res/drawable/ic_checkbox_on.xml +++ b/app/src/main/res/drawable/ic_checkbox_on.xml @@ -4,7 +4,7 @@ android:viewportWidth="24" android:viewportHeight="24"> diff --git a/app/src/main/res/drawable/ic_connect_device.xml b/app/src/main/res/drawable/ic_connect_device.xml new file mode 100644 index 0000000..7e5b641 --- /dev/null +++ b/app/src/main/res/drawable/ic_connect_device.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device.xml b/app/src/main/res/drawable/ic_device.xml index 87c899e..6885fc2 100644 --- a/app/src/main/res/drawable/ic_device.xml +++ b/app/src/main/res/drawable/ic_device.xml @@ -1,45 +1,21 @@ + android:viewportWidth="100" + android:viewportHeight="100"> + android:fillColor="#D0C7E9" + android:pathData="M8.5,23.8h36.8v43.5h-36.8z" /> + android:fillColor="#D0C7E9" + android:pathData="M54.8,23.8h36.8v43.5h-36.8z" /> + android:fillColor="#333333" + android:pathData="M91.5,87h-83C7.7,87 7,86.3 7,85.5v-71C7,13.7 7.7,13 8.5,13h83c0.8,0 1.5,0.7 1.5,1.5v71C93,86.3 92.3,87 91.5,87zM10,84h80V16H10V84z" /> + android:fillColor="#7D66DC" + android:pathData="M35,77.3H18.8c-0.8,0 -1.5,-0.7 -1.5,-1.5s0.7,-1.5 1.5,-1.5H35c0.8,0 1.5,0.7 1.5,1.5S35.8,77.3 35,77.3z" /> - - - - - - - - + android:fillColor="#7D66DC" + android:pathData="M81.2,77.3H65c-0.8,0 -1.5,-0.7 -1.5,-1.5s0.7,-1.5 1.5,-1.5h16.2c0.8,0 1.5,0.7 1.5,1.5S82.1,77.3 81.2,77.3z" /> diff --git a/app/src/main/res/drawable/ic_device_bulb.xml b/app/src/main/res/drawable/ic_device_bulb.xml new file mode 100644 index 0000000..1a9493f --- /dev/null +++ b/app/src/main/res/drawable/ic_device_bulb.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_bulb_cct.xml b/app/src/main/res/drawable/ic_device_bulb_cct.xml new file mode 100644 index 0000000..2024679 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_bulb_cct.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_bulb_rgb.xml b/app/src/main/res/drawable/ic_device_bulb_rgb.xml new file mode 100644 index 0000000..a19e5c9 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_bulb_rgb.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_fan.xml b/app/src/main/res/drawable/ic_device_fan.xml new file mode 100644 index 0000000..7a17e2d --- /dev/null +++ b/app/src/main/res/drawable/ic_device_fan.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_light_bulb.xml b/app/src/main/res/drawable/ic_device_light_bulb.xml deleted file mode 100644 index f17eb22..0000000 --- a/app/src/main/res/drawable/ic_device_light_bulb.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_device_lock.xml b/app/src/main/res/drawable/ic_device_lock.xml new file mode 100644 index 0000000..c10504d --- /dev/null +++ b/app/src/main/res/drawable/ic_device_lock.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_outlet.xml b/app/src/main/res/drawable/ic_device_outlet.xml new file mode 100644 index 0000000..975d4cc --- /dev/null +++ b/app/src/main/res/drawable/ic_device_outlet.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_switch.xml b/app/src/main/res/drawable/ic_device_switch.xml new file mode 100644 index 0000000..b4af24e --- /dev/null +++ b/app/src/main/res/drawable/ic_device_switch.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_temp_sensor.xml b/app/src/main/res/drawable/ic_device_temp_sensor.xml new file mode 100644 index 0000000..ac067fe --- /dev/null +++ b/app/src/main/res/drawable/ic_device_temp_sensor.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_device_thermostat.xml b/app/src/main/res/drawable/ic_device_thermostat.xml new file mode 100644 index 0000000..b23f243 --- /dev/null +++ b/app/src/main/res/drawable/ic_device_thermostat.xml @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_gva.png b/app/src/main/res/drawable/ic_gva.png new file mode 100644 index 0000000..523026c Binary files /dev/null and b/app/src/main/res/drawable/ic_gva.png differ diff --git a/app/src/main/res/drawable/ic_menu_add.xml b/app/src/main/res/drawable/ic_menu_add.xml new file mode 100644 index 0000000..6e866de --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_add.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_more.xml b/app/src/main/res/drawable/ic_more.xml index f5324f4..53ef5b8 100644 --- a/app/src/main/res/drawable/ic_more.xml +++ b/app/src/main/res/drawable/ic_more.xml @@ -4,12 +4,12 @@ android:viewportWidth="20" android:viewportHeight="20"> diff --git a/app/src/main/res/drawable/ic_no_camera_permission.xml b/app/src/main/res/drawable/ic_no_camera_permission.xml new file mode 100644 index 0000000..5aa8bc2 --- /dev/null +++ b/app/src/main/res/drawable/ic_no_camera_permission.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/ic_no_devices.xml b/app/src/main/res/drawable/ic_no_devices.xml new file mode 100644 index 0000000..8a7474e --- /dev/null +++ b/app/src/main/res/drawable/ic_no_devices.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_no_location_permission.xml b/app/src/main/res/drawable/ic_no_location_permission.xml new file mode 100644 index 0000000..bd98948 --- /dev/null +++ b/app/src/main/res/drawable/ic_no_location_permission.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_node_details.xml b/app/src/main/res/drawable/ic_node_details.xml new file mode 100644 index 0000000..04efb32 --- /dev/null +++ b/app/src/main/res/drawable/ic_node_details.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_node_info.xml b/app/src/main/res/drawable/ic_node_info.xml index c238e79..00e3860 100644 --- a/app/src/main/res/drawable/ic_node_info.xml +++ b/app/src/main/res/drawable/ic_node_info.xml @@ -8,7 +8,7 @@ android:fillType="evenOdd" android:pathData="M18,18m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" android:strokeWidth="2" - android:strokeColor="#5330B9" + android:strokeColor="#8864e4" android:strokeLineCap="round" android:strokeLineJoin="round" /> diff --git a/app/src/main/res/drawable/ic_output_disable.xml b/app/src/main/res/drawable/ic_output_disable.xml index c8f09ed..788573d 100644 --- a/app/src/main/res/drawable/ic_output_disable.xml +++ b/app/src/main/res/drawable/ic_output_disable.xml @@ -5,7 +5,7 @@ android:viewportHeight="40"> @@ -16,7 +16,7 @@ android:pathData="M27.221,12.832a9.474,9.474 0,1 1,-13.4 0M20.526,9v10.526" android:strokeWidth="2" android:strokeAlpha="0.3" - android:strokeColor="#5330B9" + android:strokeColor="#8864e4" android:strokeLineCap="round" android:strokeLineJoin="round" /> diff --git a/app/src/main/res/drawable/ic_output_off.xml b/app/src/main/res/drawable/ic_output_off.xml index 38c5fe3..1701cf3 100644 --- a/app/src/main/res/drawable/ic_output_off.xml +++ b/app/src/main/res/drawable/ic_output_off.xml @@ -5,7 +5,7 @@ android:viewportHeight="40"> @@ -14,7 +14,7 @@ android:fillType="evenOdd" android:pathData="M27.221,12.832a9.474,9.474 0,1 1,-13.4 0M20.526,9v10.526" android:strokeWidth="2" - android:strokeColor="#5330B9" + android:strokeColor="#8864e4" android:strokeLineCap="round" android:strokeLineJoin="round" /> diff --git a/app/src/main/res/drawable/ic_output_on.xml b/app/src/main/res/drawable/ic_output_on.xml index f70dd14..5d7398b 100644 --- a/app/src/main/res/drawable/ic_output_on.xml +++ b/app/src/main/res/drawable/ic_output_on.xml @@ -4,7 +4,7 @@ android:viewportWidth="40" android:viewportHeight="40"> + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_provisioning.xml b/app/src/main/res/drawable/ic_provisioning.xml new file mode 100644 index 0000000..0e6c4b0 --- /dev/null +++ b/app/src/main/res/drawable/ic_provisioning.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_saturation_high.xml b/app/src/main/res/drawable/ic_saturation_high.xml new file mode 100644 index 0000000..bea54d0 --- /dev/null +++ b/app/src/main/res/drawable/ic_saturation_high.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_saturation_low.xml b/app/src/main/res/drawable/ic_saturation_low.xml new file mode 100644 index 0000000..2d4bf99 --- /dev/null +++ b/app/src/main/res/drawable/ic_saturation_low.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_switch_off.xml b/app/src/main/res/drawable/ic_switch_off.xml new file mode 100644 index 0000000..2f801a6 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch_off.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_switch_on.xml b/app/src/main/res/drawable/ic_switch_on.xml new file mode 100644 index 0000000..81a7629 --- /dev/null +++ b/app/src/main/res/drawable/ic_switch_on.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_wifi_select.xml b/app/src/main/res/drawable/ic_wifi_select.xml new file mode 100644 index 0000000..4880445 --- /dev/null +++ b/app/src/main/res/drawable/ic_wifi_select.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/not_checked.png b/app/src/main/res/drawable/not_checked.png deleted file mode 100755 index d4b2ed5..0000000 Binary files a/app/src/main/res/drawable/not_checked.png and /dev/null differ diff --git a/app/src/main/res/drawable/side_nav_bar.xml b/app/src/main/res/drawable/side_nav_bar.xml deleted file mode 100755 index e80396f..0000000 --- a/app/src/main/res/drawable/side_nav_bar.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/sync.png b/app/src/main/res/drawable/sync.png deleted file mode 100755 index 285e2ea..0000000 Binary files a/app/src/main/res/drawable/sync.png and /dev/null differ diff --git a/app/src/main/res/layout/activity_actions.xml b/app/src/main/res/layout/activity_actions.xml index 96fcb82..e9bee11 100644 --- a/app/src/main/res/layout/activity_actions.xml +++ b/app/src/main/res/layout/activity_actions.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/color_background" android:fitsSystemWindows="true"> diff --git a/app/src/main/res/layout/activity_add_device.xml b/app/src/main/res/layout/activity_add_device.xml index e8af8ed..3c40c1a 100644 --- a/app/src/main/res/layout/activity_add_device.xml +++ b/app/src/main/res/layout/activity_add_device.xml @@ -1,93 +1,156 @@ - + android:layout_height="match_parent" + android:background="@color/color_background"> - + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - - - - - - - - - - + + + + + + + + + android:layout_height="match_parent"> + + + + - + android:layout_height="match_parent"> - + - + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_add_schedule.xml b/app/src/main/res/layout/activity_add_schedule.xml index ffdb38f..a154b54 100644 --- a/app/src/main/res/layout/activity_add_schedule.xml +++ b/app/src/main/res/layout/activity_add_schedule.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/color_background" android:fitsSystemWindows="true"> diff --git a/app/src/main/res/layout/activity_bleprovision_landing.xml b/app/src/main/res/layout/activity_bleprovision_landing.xml index 0f9d630..3b61c0f 100644 --- a/app/src/main/res/layout/activity_bleprovision_landing.xml +++ b/app/src/main/res/layout/activity_bleprovision_landing.xml @@ -2,21 +2,10 @@ + android:layout_height="match_parent" + android:background="@color/color_background"> - - - - - + diff --git a/app/src/main/res/layout/activity_change_password.xml b/app/src/main/res/layout/activity_change_password.xml index 74d9777..f615b4f 100755 --- a/app/src/main/res/layout/activity_change_password.xml +++ b/app/src/main/res/layout/activity_change_password.xml @@ -5,134 +5,135 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - + - - + + - - - - - - - - - - - - - - + + - - - - - - + + + + + + - - + + + + + + - - + android:background="@drawable/bg_edit_text" + android:hint="@string/hint_confirm_new_password" + android:imeOptions="actionGo" + android:inputType="textPassword" + android:paddingStart="16dp" + android:paddingTop="18dp" + android:paddingEnd="16dp" + android:paddingBottom="18dp" + android:textSize="16sp" /> + + + + + + - + diff --git a/app/src/main/res/layout/activity_esp_device.xml b/app/src/main/res/layout/activity_esp_device.xml index 96356de..480fab5 100644 --- a/app/src/main/res/layout/activity_esp_device.xml +++ b/app/src/main/res/layout/activity_esp_device.xml @@ -5,8 +5,32 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - + + + + + + + + diff --git a/app/src/main/res/layout/activity_esp_main.xml b/app/src/main/res/layout/activity_esp_main.xml index 3880a91..2e33d44 100644 --- a/app/src/main/res/layout/activity_esp_main.xml +++ b/app/src/main/res/layout/activity_esp_main.xml @@ -4,10 +4,38 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@drawable/bg_home_screen" + android:fitsSystemWindows="true" tools:context="com.espressif.ui.activities.EspMainActivity"> - + - + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_forgot_password.xml b/app/src/main/res/layout/activity_forgot_password.xml index 299954e..712b183 100755 --- a/app/src/main/res/layout/activity_forgot_password.xml +++ b/app/src/main/res/layout/activity_forgot_password.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - + diff --git a/app/src/main/res/layout/activity_groups.xml b/app/src/main/res/layout/activity_groups.xml index 5e85770..acf2362 100644 --- a/app/src/main/res/layout/activity_groups.xml +++ b/app/src/main/res/layout/activity_groups.xml @@ -3,6 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/color_background" android:fitsSystemWindows="true"> diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 693669f..4d45776 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -40,8 +40,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/color_background" - app:tabIndicatorColor="@color/color_purple" - app:tabTextColor="@color/color_purple" /> + app:tabIndicatorColor="@color/colorPrimary" + app:tabTextColor="@color/colorPrimary" /> diff --git a/app/src/main/res/layout/activity_node_details.xml b/app/src/main/res/layout/activity_node_details.xml index afa6561..e18c4fe 100644 --- a/app/src/main/res/layout/activity_node_details.xml +++ b/app/src/main/res/layout/activity_node_details.xml @@ -34,8 +34,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" - android:layout_marginTop="@dimen/margin_24" - android:src="@drawable/ic_provisioning" /> + android:src="@drawable/ic_node_details" /> + + + app:layout_constraintTop_toBottomOf="@id/iv_pop" /> - - + diff --git a/app/src/main/res/layout/activity_provision_landing.xml b/app/src/main/res/layout/activity_provision_landing.xml index b906dcb..9365dd2 100644 --- a/app/src/main/res/layout/activity_provision_landing.xml +++ b/app/src/main/res/layout/activity_provision_landing.xml @@ -3,85 +3,78 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@color/color_background" android:fitsSystemWindows="true"> - - - - + - + - + - + - + - - - + - + diff --git a/app/src/main/res/layout/activity_sharing_requests.xml b/app/src/main/res/layout/activity_sharing_requests.xml index 6ca4aa3..1fc36e6 100644 --- a/app/src/main/res/layout/activity_sharing_requests.xml +++ b/app/src/main/res/layout/activity_sharing_requests.xml @@ -3,7 +3,8 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:background="@color/color_background"> diff --git a/app/src/main/res/layout/activity_sign_up_confirm.xml b/app/src/main/res/layout/activity_sign_up_confirm.xml index 7f6a758..0fc0309 100755 --- a/app/src/main/res/layout/activity_sign_up_confirm.xml +++ b/app/src/main/res/layout/activity_sign_up_confirm.xml @@ -5,7 +5,7 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_wifi_scan_list.xml b/app/src/main/res/layout/activity_wifi_scan_list.xml index a613002..d1a7923 100644 --- a/app/src/main/res/layout/activity_wifi_scan_list.xml +++ b/app/src/main/res/layout/activity_wifi_scan_list.xml @@ -1,25 +1,172 @@ + android:fitsSystemWindows="true"> - + + + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + android:layout_height="match_parent"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + diff --git a/app/src/main/res/layout/app_actionbar.xml b/app/src/main/res/layout/app_actionbar.xml new file mode 100755 index 0000000..3224ea1 --- /dev/null +++ b/app/src/main/res/layout/app_actionbar.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/btn_add_device.xml b/app/src/main/res/layout/btn_add_device.xml index 8275dd1..d872456 100644 --- a/app/src/main/res/layout/btn_add_device.xml +++ b/app/src/main/res/layout/btn_add_device.xml @@ -1,18 +1,20 @@ + app:strokeWidth="1dp" + card_view:cardBackgroundColor="@android:color/transparent"> + android:textSize="18sp" /> - - - - @@ -190,17 +180,12 @@ - - - - - - - @@ -11,7 +12,9 @@ android:id="@+id/prefix_layout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="15dp"> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> @@ -48,6 +52,14 @@ + + - - + app:layout_constraintBottom_toTopOf="@id/devices_layout" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/divider" /> - - + android:layout_height="wrap_content" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/bluetooth_status_message"> - + android:layout_alignParentStart="true" + android:layout_alignParentTop="true" + android:paddingStart="@dimen/margin_18" + android:paddingEnd="@dimen/margin_18" + android:paddingBottom="@dimen/margin_10" + android:text="@string/devices_title" + android:textAlignment="center" + android:textAppearance="@style/TextAppearance.AppCompat.Medium" + android:textColor="@color/colorPrimaryDark" + android:textSize="18sp" /> + + + + + android:layout_margin="@dimen/margin_32" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> - + diff --git a/app/src/main/res/layout/content_esp_device.xml b/app/src/main/res/layout/content_esp_device.xml index 35bd711..9ffd453 100644 --- a/app/src/main/res/layout/content_esp_device.xml +++ b/app/src/main/res/layout/content_esp_device.xml @@ -34,10 +34,10 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/tv_device_offline" - android:layout_marginStart="@dimen/margin_32" - android:layout_marginTop="@dimen/margin_10" - android:layout_marginEnd="@dimen/margin_32" - android:layout_marginBottom="@dimen/margin_32" + android:paddingStart="@dimen/margin_16" + android:paddingTop="@dimen/margin_10" + android:paddingEnd="@dimen/margin_16" + android:paddingBottom="@dimen/margin_16" android:visibility="visible" app:layout_behavior="@string/appbar_scrolling_view_behavior"> diff --git a/app/src/main/res/layout/content_esp_main.xml b/app/src/main/res/layout/content_esp_main.xml deleted file mode 100644 index 252fc77..0000000 --- a/app/src/main/res/layout/content_esp_main.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/content_node_device_list.xml b/app/src/main/res/layout/content_node_device_list.xml index 837d001..f3f8679 100644 --- a/app/src/main/res/layout/content_node_device_list.xml +++ b/app/src/main/res/layout/content_node_device_list.xml @@ -19,6 +19,7 @@ android:id="@+id/rv_device_list" android:layout_width="match_parent" android:layout_height="wrap_content" + android:nestedScrollingEnabled="false" android:scrollbars="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -29,6 +30,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_16" + android:nestedScrollingEnabled="false" android:scrollbars="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" diff --git a/app/src/main/res/layout/content_wifi_scan_list.xml b/app/src/main/res/layout/content_wifi_scan_list.xml deleted file mode 100644 index 751b897..0000000 --- a/app/src/main/res/layout/content_wifi_scan_list.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_devices.xml b/app/src/main/res/layout/fragment_devices.xml index 32e41ac..25a3d9f 100644 --- a/app/src/main/res/layout/fragment_devices.xml +++ b/app/src/main/res/layout/fragment_devices.xml @@ -20,10 +20,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toStartOf="@id/iv_more" + android:background="@android:color/transparent" + app:tabBackground="@drawable/bg_group_tab" app:tabGravity="fill" - app:tabSelectedTextColor="@color/colorPrimary" + app:tabIndicatorHeight="0dp" app:tabMode="scrollable" - app:tabTextAppearance="@android:style/TextAppearance.Material.Widget" /> + app:tabRippleColor="@null" + app:tabTextAppearance="@android:style/TextAppearance.Material.Widget" + app:tabTextColor="@android:color/white" /> diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 16d62de..1f19e00 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -124,7 +124,7 @@ android:layout_marginTop="@dimen/margin_24" android:layout_marginBottom="@dimen/margin_24" android:text="@string/forgot_password" - android:textColor="@color/color_purple" + android:textColor="@color/colorPrimary" android:textSize="14sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" diff --git a/app/src/main/res/layout/fragment_schedules.xml b/app/src/main/res/layout/fragment_schedules.xml index 85aed17..cfb3183 100644 --- a/app/src/main/res/layout/fragment_schedules.xml +++ b/app/src/main/res/layout/fragment_schedules.xml @@ -30,7 +30,7 @@ android:layout_marginTop="@dimen/margin_24" android:gravity="center_horizontal" android:text="@string/no_schedules" - android:textColor="@color/colorPrimaryDark" + android:textColor="@android:color/white" android:textSize="18sp" /> @@ -53,7 +53,7 @@ layout="@layout/button" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_alignParentBottom="true" + android:layout_below="@id/rl_no_schedule" android:layout_margin="@dimen/margin_32" /> - - @@ -32,21 +30,19 @@ android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_margin="@dimen/margin_16" - android:src="@drawable/ic_user_profile" - android:visibility="gone" /> + android:src="@drawable/ic_user_profile" /> + android:orientation="vertical"> - - + app:layout_constraintTop_toBottomOf="@id/layout_user_info" /> - - - - - - - - - + android:layout_centerHorizontal="true" + android:paddingTop="@dimen/margin_8" + android:paddingBottom="@dimen/margin_8" + android:text="@string/btn_logout" + android:textColor="@color/color_orange" + android:textSize="16sp" /> @@ -129,16 +99,15 @@ android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/layout_logout"> + app:layout_constraintTop_toBottomOf="@id/rl_logout"> diff --git a/app/src/main/res/layout/item_action.xml b/app/src/main/res/layout/item_action.xml index 534bf2d..005b68a 100644 --- a/app/src/main/res/layout/item_action.xml +++ b/app/src/main/res/layout/item_action.xml @@ -8,7 +8,7 @@ android:layout_marginTop="@dimen/margin_8" android:layout_marginEnd="@dimen/margin_8" android:layout_marginBottom="@dimen/margin_8" - card_view:cardBackgroundColor="@color/color_background" + card_view:cardBackgroundColor="@android:color/white" card_view:cardCornerRadius="8dp" card_view:cardElevation="1dp" card_view:cardUseCompatPadding="true"> diff --git a/app/src/main/res/layout/item_ble_scan.xml b/app/src/main/res/layout/item_ble_scan.xml index 4087b6c..d103946 100644 --- a/app/src/main/res/layout/item_ble_scan.xml +++ b/app/src/main/res/layout/item_ble_scan.xml @@ -1,22 +1,27 @@ + android:layout_height="wrap_content" + android:background="@android:color/white"> - + android:layout_centerVertical="true" + android:layout_marginStart="10dp" + android:padding="15dp" + android:textColor="@color/colorPrimaryDark" + android:textSize="18sp" /> - - - + diff --git a/app/src/main/res/layout/item_esp_device.xml b/app/src/main/res/layout/item_esp_device.xml index 7925f54..a4a8073 100644 --- a/app/src/main/res/layout/item_esp_device.xml +++ b/app/src/main/res/layout/item_esp_device.xml @@ -60,6 +60,7 @@ android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:gravity="end" + android:maxLines="1" android:text="Test" android:textColor="@color/color_dark_gray" android:textSize="20sp" diff --git a/app/src/main/res/layout/item_group.xml b/app/src/main/res/layout/item_group.xml index 6a8ddba..bacdc16 100644 --- a/app/src/main/res/layout/item_group.xml +++ b/app/src/main/res/layout/item_group.xml @@ -6,7 +6,6 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - card_view:cardBackgroundColor="@color/color_background" card_view:cardCornerRadius="8dp" card_view:cardElevation="2dp" card_view:cardUseCompatPadding="true"> @@ -14,7 +13,7 @@ + android:background="@android:color/white"> + android:padding="@dimen/margin_10"> @@ -29,6 +30,7 @@ android:paddingEnd="@dimen/margin_10" android:paddingBottom="@dimen/margin_10" android:text="My Light Bulb" + android:textColor="@android:color/white" android:textSize="17sp" /> - + android:layout_height="wrap_content"> + + + + + + + + + + diff --git a/app/src/main/res/layout/item_param.xml b/app/src/main/res/layout/item_param.xml index e57f001..945da2a 100644 --- a/app/src/main/res/layout/item_param.xml +++ b/app/src/main/res/layout/item_param.xml @@ -16,7 +16,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="8dp" - android:visibility="gone"> + android:visibility="visible"> - - - - - - - - - - - - - - + + + android:layout_marginBottom="10dp"> + + + + + + + + + + @@ -114,12 +131,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" - android:layout_alignParentTop="true" android:layout_marginStart="8dp" - android:alpha="0.5" android:text="Brightness" android:textColor="@color/colorPrimaryDark" - android:textSize="12sp" /> + android:textSize="18sp" /> + + + + + + + + + diff --git a/app/src/main/res/layout/item_param_switch.xml b/app/src/main/res/layout/item_param_switch.xml new file mode 100644 index 0000000..9051f41 --- /dev/null +++ b/app/src/main/res/layout/item_param_switch.xml @@ -0,0 +1,22 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/item_schedule.xml b/app/src/main/res/layout/item_schedule.xml index b916427..1d57f3d 100644 --- a/app/src/main/res/layout/item_schedule.xml +++ b/app/src/main/res/layout/item_schedule.xml @@ -6,70 +6,118 @@ android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" - card_view:cardBackgroundColor="@color/color_background" card_view:cardCornerRadius="8dp" - card_view:cardElevation="2dp" + card_view:cardElevation="1dp" card_view:cardUseCompatPadding="true"> + android:padding="18dp"> - + android:textSize="18sp" + android:textStyle="bold" /> + + + + + + + android:textSize="18sp" /> + + - + - + android:layout_centerVertical="true"> - + + + + diff --git a/app/src/main/res/layout/item_sharing_request.xml b/app/src/main/res/layout/item_sharing_request.xml index 1e7839b..3dde6a4 100644 --- a/app/src/main/res/layout/item_sharing_request.xml +++ b/app/src/main/res/layout/item_sharing_request.xml @@ -66,15 +66,15 @@ android:orientation="horizontal"> diff --git a/app/src/main/res/layout/layout_group_page.xml b/app/src/main/res/layout/layout_group_page.xml index 65c596e..24fe359 100644 --- a/app/src/main/res/layout/layout_group_page.xml +++ b/app/src/main/res/layout/layout_group_page.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent" - app:layout_behavior="@string/appbar_scrolling_view_behavior"> + android:layout_height="match_parent"> + android:textColor="@android:color/white" + android:textSize="20sp" + android:textStyle="bold" /> - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/tool_bar_device_details.xml b/app/src/main/res/layout/tool_bar_device_details.xml deleted file mode 100644 index 6597d49..0000000 --- a/app/src/main/res/layout/tool_bar_device_details.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/tool_bar_devices.xml b/app/src/main/res/layout/tool_bar_devices.xml deleted file mode 100644 index e3fb1fa..0000000 --- a/app/src/main/res/layout/tool_bar_devices.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/toolbar.xml b/app/src/main/res/layout/toolbar.xml index ec012b5..5215bcc 100644 --- a/app/src/main/res/layout/toolbar.xml +++ b/app/src/main/res/layout/toolbar.xml @@ -1,66 +1,29 @@ + android:fitsSystemWindows="true"> - - + + - - - - - - - - - - + android:layout_gravity="center" + android:visibility="gone" /> diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml deleted file mode 100755 index d4ca9d3..0000000 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/activity_user_drawer.xml b/app/src/main/res/menu/activity_user_drawer.xml deleted file mode 100755 index a43bcb7..0000000 --- a/app/src/main/res/menu/activity_user_drawer.xml +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/menu/menu_bottom_tabs.xml b/app/src/main/res/menu/menu_bottom_tabs.xml index db66d8c..d623706 100644 --- a/app/src/main/res/menu/menu_bottom_tabs.xml +++ b/app/src/main/res/menu/menu_bottom_tabs.xml @@ -13,4 +13,10 @@ android:orderInCategory="100" android:title="@string/tab_schedules" app:showAsAction="never" /> + diff --git a/app/src/main/res/menu/menu_group.xml b/app/src/main/res/menu/menu_group.xml index 783cff4..d6a69d2 100644 --- a/app/src/main/res/menu/menu_group.xml +++ b/app/src/main/res/menu/menu_group.xml @@ -3,14 +3,13 @@ xmlns:tools="http://schemas.android.com/tools" tools:context="com.espressif.espressif.MainActivity"> - diff --git a/app/src/main/res/menu/menu_toolbar.xml b/app/src/main/res/menu/menu_toolbar.xml new file mode 100755 index 0000000..fc0cd0e --- /dev/null +++ b/app/src/main/res/menu/menu_toolbar.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 23b86d1..0acb091 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ - #5330b9 + #8864e4 #1a1a1a #8181a8 #0033CC @@ -17,7 +17,6 @@ - #5330b9 #f2f1fc #1a1a1a #f6f6fb diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bd54f26..7544d14 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -30,6 +30,7 @@ Removing Node... Accepting... Declining... + Scanning for Wi-Fi... Error! @@ -52,6 +53,7 @@ Confirmation code cannot be empty Verification code cannot be empty Network name cannot be empty + No network selected Passwords not matched Please agree to privacy policy and terms of Use. Reset your board to factory defaults and retry @@ -87,6 +89,9 @@ Failed to add a member Failed to delete member Failed to remove sharing request + Failed to update timezone + Camera permission is not given. App will not be able to scan QR code to add device. + Location permission is not given. It will be require to add BLE or SoftAP devices. Settings @@ -167,7 +172,7 @@ I don\'t have a QR code Add Device Add Schedule - Scan Again + Rescan Sign Out Skip Next @@ -179,6 +184,9 @@ Add Accept Decline + Get Permission + Start + Node Info Devices @@ -207,6 +215,7 @@ Create Group Edit Group Sharing Requests + Voice Services Sign-in failed @@ -223,12 +232,12 @@ Are you sure? Choose Provisioning Transport Remove - Are you sure to remove this schedule? - Are you sure to remove this group? + Are you sure? Device disconnected Device connection failed. \nDo you want to connect device manually ? Enter Group Name User Email + Logout Node Id @@ -236,6 +245,7 @@ Type Firmware Version Config Version + Timezone Shared with Shared by Pending for acceptance @@ -261,6 +271,7 @@ Documentation Privacy Policy Terms of Use + Voice Services Looking for QR Code Please position the camera to point at the QR Code. App Version @@ -274,7 +285,6 @@ Device has no parameters This may take time. Not set - Fetching data from cloud No internet connection Actions Schedule added @@ -292,6 +302,12 @@ node Expires in days + Select Timezone + Select Network + Email + Supported Services + Amazon Alexa + Google Assistant Sending Wi-Fi credentials Confirming Wi-Fi connection @@ -306,7 +322,7 @@ On Once - Daily + Every day On Weekends On Weekdays diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index e372fb8..ea0c5df 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -14,6 +14,11 @@ true + +