// Copyright 2020 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.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.text.TextUtils; 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.TextView; import android.widget.Toast; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import com.espressif.AppConstants; import com.espressif.wifi_provisioning.R; import com.espressif.provisioning.ESPConstants; import com.espressif.provisioning.ESPProvisionManager; import com.espressif.provisioning.WiFiAccessPoint; import com.espressif.provisioning.listeners.WiFiScanListener; import com.espressif.ui.adapters.WiFiListAdapter; import com.google.android.material.textfield.TextInputLayout; import java.util.ArrayList; public class WiFiScanActivity extends AppCompatActivity { private static final String TAG = WiFiScanActivity.class.getSimpleName(); private Handler handler; private ImageView ivRefresh; private ListView wifiListView; private ProgressBar progressBar; private WiFiListAdapter adapter; private ArrayList<WiFiAccessPoint> wifiAPList; private ESPProvisionManager provisionManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_wifi_scan_list); Toolbar 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()); 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) { goForProvisioning(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) { } }); startWifiScan(); } @Override public void onBackPressed() { provisionManager.getEspDevice().disconnectDevice(); super.onBackPressed(); } private void startWifiScan() { Log.d(TAG, "Start Wi-Fi Scan"); wifiAPList.clear(); runOnUiThread(new Runnable() { @Override public void run() { updateProgressAndScanBtn(true); } }); handler.postDelayed(stopScanningTask, 15000); provisionManager.getEspDevice().scanNetworks(new WiFiScanListener() { @Override public void onWifiListReceived(final ArrayList<WiFiAccessPoint> wifiList) { runOnUiThread(new Runnable() { @Override public void run() { wifiAPList.addAll(wifiList); completeWifiList(); } }); } @Override public void onWiFiScanFailed(Exception e) { // TODO Log.e(TAG, "onWiFiScanFailed"); e.printStackTrace(); runOnUiThread(new Runnable() { @Override public void run() { updateProgressAndScanBtn(false); Toast.makeText(WiFiScanActivity.this, "Failed to get Wi-Fi scan list", Toast.LENGTH_LONG).show(); } }); } }); } private void completeWifiList() { // Add "Join network" Option as a list item WiFiAccessPoint wifiAp = new WiFiAccessPoint(); wifiAp.setWifiName(getString(R.string.join_other_network)); wifiAPList.add(wifiAp); updateProgressAndScanBtn(false); handler.removeCallbacks(stopScanningTask); } private void askForNetwork(final String ssid, final int authMode) { final AlertDialog.Builder builder = new AlertDialog.Builder(this, R.style.AlertDialogTheme); LayoutInflater inflater = this.getLayoutInflater(); final View dialogView = inflater.inflate(R.layout.dialog_wifi_network, null); builder.setView(dialogView); 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.setPositiveButton(R.string.btn_provision, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String password = etPassword.getText().toString(); if (ssid.equals(getString(R.string.join_other_network))) { String networkName = etSsid.getText().toString(); if (TextUtils.isEmpty(networkName)) { etSsid.setError(getString(R.string.error_ssid_empty)); } else { dialog.dismiss(); goForProvisioning(networkName, password); } } 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(); goForProvisioning(ssid, password); } } else { if (authMode == ESPConstants.WIFI_OPEN) { password = ""; } dialog.dismiss(); goForProvisioning(ssid, password); } } } }); builder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); } private void goForProvisioning(String ssid, String password) { finish(); Intent provisionIntent = new Intent(getApplicationContext(), ProvisionActivity.class); provisionIntent.putExtras(getIntent()); provisionIntent.putExtra(AppConstants.KEY_WIFI_SSID, ssid); provisionIntent.putExtra(AppConstants.KEY_WIFI_PASSWORD, password); startActivity(provisionIntent); } private View.OnClickListener refreshClickListener = new View.OnClickListener() { @Override public void onClick(View v) { startWifiScan(); } }; private Runnable stopScanningTask = new Runnable() { @Override public void run() { updateProgressAndScanBtn(false); } }; /** * This method will update UI (Scan button enable / disable and progressbar visibility) */ private void updateProgressAndScanBtn(boolean isScanning) { if (isScanning) { progressBar.setVisibility(View.VISIBLE); wifiListView.setVisibility(View.GONE); ivRefresh.setVisibility(View.GONE); } else { progressBar.setVisibility(View.GONE); wifiListView.setVisibility(View.VISIBLE); ivRefresh.setVisibility(View.VISIBLE); adapter.notifyDataSetChanged(); } } }