From ed64bfd9bfd8a170323564c669d45772d868518c Mon Sep 17 00:00:00 2001 From: XuXiangJun Date: Fri, 10 Apr 2020 14:13:51 +0800 Subject: [PATCH] update --- README.md | 3 + app/build.gradle | 13 +- app/src/main/AndroidManifest.xml | 5 +- .../esptouch/android/EspTouchActivityAbs.java | 176 ++++++++ .../esptouch/android/v1/EspTouchActivity.java | 281 +++++++++++++ .../android/v1/EspTouchViewModel.java | 31 ++ .../demo_activity/EsptouchDemoActivity.java | 395 ------------------ .../iot_esptouch_demo/EspTouchApp.java | 89 ++++ .../espressif/iot_esptouch_demo/NetUtils.java | 147 +++++++ .../drawable-hdpi/baseline_info_black_24.png | Bin 0 -> 307 bytes .../drawable-mdpi/baseline_info_black_24.png | Bin 0 -> 215 bytes .../drawable-xhdpi/baseline_info_black_24.png | Bin 0 -> 366 bytes .../baseline_info_black_24.png | Bin 0 -> 541 bytes ...emo_activity.xml => activity_esptouch.xml} | 79 ++-- .../main/res/layout/activity_esptouch2.xml | 159 +++++++ app/src/main/res/layout/activity_main.xml | 17 + .../main/res/layout/activity_main_item.xml | 15 + .../main/res/layout/activity_provision.xml | 42 ++ app/src/main/res/values-zh-rCN/strings.xml | 63 ++- app/src/main/res/values/strings.xml | 59 ++- app/src/main/res/values/styles.xml | 1 - build.gradle | 2 +- esptouch/README.md | 42 ++ esptouch/build.gradle | 4 + .../espressif/iot/esptouch/IEsptouchTask.java | 2 +- .../iot/esptouch/util/TouchNetUtil.java | 15 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 27 files changed, 1157 insertions(+), 487 deletions(-) create mode 100644 app/src/main/java/com/espressif/esptouch/android/EspTouchActivityAbs.java create mode 100644 app/src/main/java/com/espressif/esptouch/android/v1/EspTouchActivity.java create mode 100644 app/src/main/java/com/espressif/esptouch/android/v1/EspTouchViewModel.java delete mode 100644 app/src/main/java/com/espressif/iot/esptouch/demo_activity/EsptouchDemoActivity.java create mode 100644 app/src/main/java/com/espressif/iot_esptouch_demo/EspTouchApp.java create mode 100644 app/src/main/java/com/espressif/iot_esptouch_demo/NetUtils.java create mode 100755 app/src/main/res/drawable-hdpi/baseline_info_black_24.png create mode 100755 app/src/main/res/drawable-mdpi/baseline_info_black_24.png create mode 100755 app/src/main/res/drawable-xhdpi/baseline_info_black_24.png create mode 100755 app/src/main/res/drawable-xxhdpi/baseline_info_black_24.png rename app/src/main/res/layout/{esptouch_demo_activity.xml => activity_esptouch.xml} (59%) create mode 100644 app/src/main/res/layout/activity_esptouch2.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/layout/activity_main_item.xml create mode 100644 app/src/main/res/layout/activity_provision.xml create mode 100644 esptouch/README.md diff --git a/README.md b/README.md index 543d0da..88915cd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ This APP is used to configure ESP devices to connect target AP, the devices need ## Version Log - See [Log](log/log-en.md) +## Modules +- EspTouch: [esptouch](esptouch) + ## Releases - See [releases](https://github.com/EspressifApp/EsptouchForAndroid/releases/latest), contain APK and aar - For programmer, if you don't want use [esptouch](esptouch) module, download the aar into your own project. diff --git a/app/build.gradle b/app/build.gradle index 2575525..3ceb492 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,10 +5,10 @@ android { defaultConfig { applicationId "com.espressif.iot_esptouch_demo" - minSdkVersion 14 + minSdkVersion 21 targetSdkVersion 29 - versionCode 22 - versionName "v1.1.0" + versionCode 23 + versionName "v1.1.1" } signingConfigs { @@ -28,17 +28,16 @@ android { signingConfig signingConfigs.debug } } - compileOptions { - sourceCompatibility 1.8 - targetCompatibility 1.8 + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs') implementation 'androidx.appcompat:appcompat:1.1.0' - implementation 'com.google.android.material:material:1.0.0' + implementation 'com.google.android.material:material:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation project(':esptouch') } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a4d615a..af3dbc3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ + package="com.espressif.iot_esptouch_demo"> @@ -11,13 +11,14 @@ diff --git a/app/src/main/java/com/espressif/esptouch/android/EspTouchActivityAbs.java b/app/src/main/java/com/espressif/esptouch/android/EspTouchActivityAbs.java new file mode 100644 index 0000000..8355bda --- /dev/null +++ b/app/src/main/java/com/espressif/esptouch/android/EspTouchActivityAbs.java @@ -0,0 +1,176 @@ +package com.espressif.esptouch.android; + +import android.Manifest; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.location.LocationManager; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Build; +import android.os.Bundle; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.style.ForegroundColorSpan; +import android.view.Menu; +import android.view.MenuItem; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.location.LocationManagerCompat; + +import com.espressif.iot_esptouch_demo.R; +import com.espressif.iot_esptouch_demo.NetUtils; + +import java.net.InetAddress; + +public abstract class EspTouchActivityAbs extends AppCompatActivity { + private static final int MENU_ITEM_ABOUT = 0; + + private WifiManager mWifiManager; + + protected abstract String getEspTouchVersion(); + + protected static class StateResult { + public CharSequence message = null; + + public boolean permissionGranted = false; + + public boolean locationRequirement = false; + + public boolean wifiConnected = false; + public boolean is5G = false; + public InetAddress address = null; + public String ssid = null; + public byte[] ssidBytes = null; + public String bssid = null; + } + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mWifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE); + } + + private void showAboutDialog() { + String esptouchVerText = getEspTouchVersion(); + String appVer = ""; + PackageManager packageManager = getPackageManager(); + try { + PackageInfo info = packageManager.getPackageInfo(getPackageName(), 0); + appVer = info.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + + CharSequence[] items = new CharSequence[]{ + getString(R.string.about_app_version, appVer), + esptouchVerText + }; + new AlertDialog.Builder(this) + .setTitle(R.string.menu_item_about) + .setIcon(R.drawable.baseline_info_black_24) + .setItems(items, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(Menu.NONE, MENU_ITEM_ABOUT, 0, R.string.menu_item_about) + .setIcon(R.drawable.ic_info_outline_white_24dp) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + case MENU_ITEM_ABOUT: + showAboutDialog(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + protected StateResult checkPermission() { + StateResult result = new StateResult(); + result.permissionGranted = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + boolean locationGranted = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED; + if (!locationGranted) { + String[] splits = getString(R.string.esptouch_message_permission).split("\n"); + if (splits.length != 2) { + throw new IllegalArgumentException("Invalid String @RES esptouch_message_permission"); + } + SpannableStringBuilder ssb = new SpannableStringBuilder(splits[0]); + ssb.append('\n'); + SpannableString clickMsg = new SpannableString(splits[1]); + ForegroundColorSpan clickSpan = new ForegroundColorSpan(0xFF0022FF); + clickMsg.setSpan(clickSpan, 0, clickMsg.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE); + ssb.append(clickMsg); + result.message = ssb; + return result; + } + } + + result.permissionGranted = true; + return result; + } + + protected StateResult checkLocation() { + StateResult result = new StateResult(); + result.locationRequirement = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + LocationManager manager = getSystemService(LocationManager.class); + boolean enable = manager != null && LocationManagerCompat.isLocationEnabled(manager); + if (!enable) { + result.message = getString(R.string.esptouch_message_location); + return result; + } + } + + result.locationRequirement = false; + return result; + } + + protected StateResult checkWifi() { + StateResult result = new StateResult(); + result.wifiConnected = false; + WifiInfo wifiInfo = mWifiManager.getConnectionInfo(); + boolean connected = NetUtils.isWifiConnected(mWifiManager); + if (!connected) { + result.message = getString(R.string.esptouch_message_wifi_connection); + return result; + } + + String ssid = NetUtils.getSsidString(wifiInfo); + int ipValue = wifiInfo.getIpAddress(); + if (ipValue != 0) { + result.address = NetUtils.getAddress(wifiInfo.getIpAddress()); + } else { + result.address = NetUtils.getIPv4Address(); + if (result.address == null) { + result.address = NetUtils.getIPv6Address(); + } + } + + result.wifiConnected = true; + result.message = ""; + result.is5G = NetUtils.is5G(wifiInfo.getFrequency()); + if (result.is5G) { + result.message = getString(R.string.esptouch_message_wifi_frequency); + } + result.ssid = ssid; + result.ssidBytes = NetUtils.getRawSsidBytesOrElse(wifiInfo, ssid.getBytes()); + result.bssid = wifiInfo.getBSSID(); + + return result; + } +} diff --git a/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchActivity.java b/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchActivity.java new file mode 100644 index 0000000..2b568e5 --- /dev/null +++ b/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchActivity.java @@ -0,0 +1,281 @@ +package com.espressif.esptouch.android.v1; + +import android.Manifest; +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageManager; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Bundle; +import android.util.Log; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AlertDialog; + +import com.espressif.esptouch.android.EspTouchActivityAbs; +import com.espressif.iot.esptouch.EsptouchTask; +import com.espressif.iot.esptouch.IEsptouchResult; +import com.espressif.iot.esptouch.IEsptouchTask; +import com.espressif.iot.esptouch.util.ByteUtil; +import com.espressif.iot.esptouch.util.TouchNetUtil; +import com.espressif.iot_esptouch_demo.EspTouchApp; +import com.espressif.iot_esptouch_demo.R; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; + +public class EspTouchActivity extends EspTouchActivityAbs { + private static final String TAG = EspTouchActivity.class.getSimpleName(); + + private static final int REQUEST_PERMISSION = 0x01; + + private EspTouchViewModel mViewModel; + + private EsptouchAsyncTask4 mTask; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_esptouch); + mViewModel = new EspTouchViewModel(); + mViewModel.apSsidTV = findViewById(R.id.apSsidText); + mViewModel.apBssidTV = findViewById(R.id.apBssidText); + mViewModel.apPasswordEdit = findViewById(R.id.apPasswordEdit); + mViewModel.deviceCountEdit = findViewById(R.id.deviceCountEdit); + mViewModel.packageModeGroup = findViewById(R.id.packageModeGroup); + mViewModel.messageView = findViewById(R.id.messageView); + mViewModel.confirmBtn = findViewById(R.id.confirmBtn); + mViewModel.confirmBtn.setOnClickListener(v -> executeEsptouch()); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION}; + requestPermissions(permissions, REQUEST_PERMISSION); + } + + EspTouchApp.getInstance().observeBroadcast(this, broadcast -> { + Log.d(TAG, "onCreate: Broadcast=" + broadcast); + onWifiChanged(); + }); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayHomeAsUpEnabled(true); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == REQUEST_PERMISSION) { + if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { + onWifiChanged(); + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.esptouch1_location_permission_title) + .setMessage(R.string.esptouch1_location_permission_message) + .setCancelable(false) + .setPositiveButton(android.R.string.ok, (dialog, which) -> finish()) + .show(); + } + + return; + } + + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } + + @Override + protected String getEspTouchVersion() { + return getString(R.string.esptouch1_about_version, IEsptouchTask.ESPTOUCH_VERSION); + } + + private StateResult check() { + StateResult result = checkPermission(); + if (!result.permissionGranted) { + return result; + } + result = checkLocation(); + result.permissionGranted = true; + if (result.locationRequirement) { + return result; + } + result = checkWifi(); + result.permissionGranted = true; + result.locationRequirement = false; + return result; + } + + private void onWifiChanged() { + StateResult stateResult = check(); + mViewModel.message = stateResult.message; + mViewModel.ssid = stateResult.ssid; + mViewModel.ssidBytes = stateResult.ssidBytes; + mViewModel.bssid = stateResult.bssid; + mViewModel.confirmEnable = false; + if (stateResult.wifiConnected) { + mViewModel.confirmEnable = true; + if (stateResult.is5G) { + mViewModel.message = getString(R.string.esptouch1_wifi_5g_message); + } + } else { + if (mTask != null) { + mTask.cancelEsptouch(); + mTask = null; + new AlertDialog.Builder(EspTouchActivity.this) + .setMessage(R.string.esptouch1_configure_wifi_change_message) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + } + mViewModel.invalidateAll(); + } + + private void executeEsptouch() { + EspTouchViewModel viewModel = mViewModel; + byte[] ssid = viewModel.ssidBytes == null ? ByteUtil.getBytesByString(viewModel.ssid) + : viewModel.ssidBytes; + CharSequence pwdStr = mViewModel.apPasswordEdit.getText(); + byte[] password = pwdStr == null ? null : ByteUtil.getBytesByString(pwdStr.toString()); + byte[] bssid = TouchNetUtil.parseBssid2bytes(viewModel.bssid); + CharSequence devCountStr = mViewModel.deviceCountEdit.getText(); + byte[] deviceCount = devCountStr == null ? new byte[0] : devCountStr.toString().getBytes(); + byte[] broadcast = {(byte) (mViewModel.packageModeGroup.getCheckedRadioButtonId() == R.id.packageBroadcast + ? 1 : 0)}; + + if (mTask != null) { + mTask.cancelEsptouch(); + } + mTask = new EsptouchAsyncTask4(this); + mTask.execute(ssid, bssid, password, deviceCount, broadcast); + } + + private static class EsptouchAsyncTask4 extends AsyncTask> { + private WeakReference mActivity; + + private final Object mLock = new Object(); + private ProgressDialog mProgressDialog; + private AlertDialog mResultDialog; + private IEsptouchTask mEsptouchTask; + + EsptouchAsyncTask4(EspTouchActivity activity) { + mActivity = new WeakReference<>(activity); + } + + void cancelEsptouch() { + cancel(true); + if (mProgressDialog != null) { + mProgressDialog.dismiss(); + } + if (mResultDialog != null) { + mResultDialog.dismiss(); + } + if (mEsptouchTask != null) { + mEsptouchTask.interrupt(); + } + } + + @Override + protected void onPreExecute() { + Activity activity = mActivity.get(); + mProgressDialog = new ProgressDialog(activity); + mProgressDialog.setMessage(activity.getString(R.string.esptouch1_configuring_message)); + mProgressDialog.setCanceledOnTouchOutside(false); + mProgressDialog.setOnCancelListener(dialog -> { + synchronized (mLock) { + if (mEsptouchTask != null) { + mEsptouchTask.interrupt(); + } + } + }); + mProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, activity.getText(android.R.string.cancel), + (dialog, which) -> { + synchronized (mLock) { + if (mEsptouchTask != null) { + mEsptouchTask.interrupt(); + } + } + }); + mProgressDialog.show(); + } + + @Override + protected void onProgressUpdate(IEsptouchResult... values) { + Context context = mActivity.get(); + if (context != null) { + IEsptouchResult result = values[0]; + Log.i(TAG, "EspTouchResult: " + result); + String text = result.getBssid() + " is connected to the wifi"; + Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); + } + } + + @Override + protected List doInBackground(byte[]... params) { + EspTouchActivity activity = mActivity.get(); + int taskResultCount; + synchronized (mLock) { + byte[] apSsid = params[0]; + byte[] apBssid = params[1]; + byte[] apPassword = params[2]; + byte[] deviceCountData = params[3]; + byte[] broadcastData = params[4]; + taskResultCount = deviceCountData.length == 0 ? -1 : Integer.parseInt(new String(deviceCountData)); + Context context = activity.getApplicationContext(); + mEsptouchTask = new EsptouchTask(apSsid, apBssid, apPassword, context); + mEsptouchTask.setPackageBroadcast(broadcastData[0] == 1); + mEsptouchTask.setEsptouchListener(this::publishProgress); + } + return mEsptouchTask.executeForResults(taskResultCount); + } + + @Override + protected void onPostExecute(List result) { + EspTouchActivity activity = mActivity.get(); + activity.mTask = null; + mProgressDialog.dismiss(); + if (result == null) { + mResultDialog = new AlertDialog.Builder(activity) + .setMessage(R.string.esptouch1_configure_result_failed_port) + .setPositiveButton(android.R.string.ok, null) + .show(); + mResultDialog.setCanceledOnTouchOutside(false); + return; + } + + // check whether the task is cancelled and no results received + IEsptouchResult firstResult = result.get(0); + if (firstResult.isCancelled()) { + return; + } + // the task received some results including cancelled while + // executing before receiving enough results + + if (!firstResult.isSuc()) { + mResultDialog = new AlertDialog.Builder(activity) + .setMessage(R.string.esptouch1_configure_result_failed) + .setPositiveButton(android.R.string.ok, null) + .show(); + mResultDialog.setCanceledOnTouchOutside(false); + return; + } + + ArrayList resultMsgList = new ArrayList<>(result.size()); + for (IEsptouchResult touchResult : result) { + String message = activity.getString(R.string.esptouch1_configure_result_success_item, + touchResult.getBssid(), touchResult.getInetAddress().getHostAddress()); + resultMsgList.add(message); + } + CharSequence[] items = new CharSequence[resultMsgList.size()]; + mResultDialog = new AlertDialog.Builder(activity) + .setTitle(R.string.esptouch1_configure_result_success) + .setItems(resultMsgList.toArray(items), null) + .setPositiveButton(android.R.string.ok, null) + .show(); + mResultDialog.setCanceledOnTouchOutside(false); + } + } +} diff --git a/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchViewModel.java b/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchViewModel.java new file mode 100644 index 0000000..5b648b5 --- /dev/null +++ b/app/src/main/java/com/espressif/esptouch/android/v1/EspTouchViewModel.java @@ -0,0 +1,31 @@ +package com.espressif.esptouch.android.v1; + +import android.widget.Button; +import android.widget.EditText; +import android.widget.RadioGroup; +import android.widget.TextView; + +class EspTouchViewModel { + TextView apSsidTV; + TextView apBssidTV; + EditText apPasswordEdit; + EditText deviceCountEdit; + RadioGroup packageModeGroup; + TextView messageView; + Button confirmBtn; + + String ssid; + byte[] ssidBytes; + String bssid; + + CharSequence message; + + boolean confirmEnable; + + void invalidateAll() { + apSsidTV.setText(ssid); + apBssidTV.setText(bssid); + messageView.setText(message); + confirmBtn.setEnabled(confirmEnable); + } +} diff --git a/app/src/main/java/com/espressif/iot/esptouch/demo_activity/EsptouchDemoActivity.java b/app/src/main/java/com/espressif/iot/esptouch/demo_activity/EsptouchDemoActivity.java deleted file mode 100644 index faa8dee..0000000 --- a/app/src/main/java/com/espressif/iot/esptouch/demo_activity/EsptouchDemoActivity.java +++ /dev/null @@ -1,395 +0,0 @@ -package com.espressif.iot.esptouch.demo_activity; - -import android.Manifest; -import android.app.Activity; -import android.app.ProgressDialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.location.LocationManager; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.widget.Button; -import android.widget.EditText; -import android.widget.RadioGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.location.LocationManagerCompat; - -import com.espressif.iot.esptouch.EsptouchTask; -import com.espressif.iot.esptouch.IEsptouchResult; -import com.espressif.iot.esptouch.IEsptouchTask; -import com.espressif.iot.esptouch.util.ByteUtil; -import com.espressif.iot.esptouch.util.TouchNetUtil; -import com.espressif.iot_esptouch_demo.R; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -public class EsptouchDemoActivity extends AppCompatActivity implements OnClickListener { - private static final String TAG = EsptouchDemoActivity.class.getSimpleName(); - - private static final int REQUEST_PERMISSION = 0x01; - - private static final int MENU_ITEM_ABOUT = 0; - - private TextView mApSsidTV; - private TextView mApBssidTV; - private EditText mApPasswordET; - private EditText mDeviceCountET; - private RadioGroup mPackageModeGroup; - private TextView mMessageTV; - private Button mConfirmBtn; - - private EsptouchAsyncTask4 mTask; - - private boolean mReceiverRegistered = false; - private BroadcastReceiver mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action == null) { - return; - } - - WifiManager wifiManager = (WifiManager) context.getApplicationContext() - .getSystemService(WIFI_SERVICE); - assert wifiManager != null; - - switch (action) { - case WifiManager.NETWORK_STATE_CHANGED_ACTION: - case LocationManager.PROVIDERS_CHANGED_ACTION: - onWifiChanged(wifiManager.getConnectionInfo()); - break; - } - } - }; - - private boolean mDestroyed = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.esptouch_demo_activity); - - mApSsidTV = findViewById(R.id.ap_ssid_text); - mApBssidTV = findViewById(R.id.ap_bssid_text); - mApPasswordET = findViewById(R.id.ap_password_edit); - mDeviceCountET = findViewById(R.id.device_count_edit); - mDeviceCountET.setText("1"); - mPackageModeGroup = findViewById(R.id.package_mode_group); - mMessageTV = findViewById(R.id.message); - mConfirmBtn = findViewById(R.id.confirm_btn); - mConfirmBtn.setEnabled(false); - mConfirmBtn.setOnClickListener(this); - - if (isSDKAtLeastP()) { - if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) - != PackageManager.PERMISSION_GRANTED) { - String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION}; - requestPermissions(permissions, REQUEST_PERMISSION); - } else { - registerBroadcastReceiver(); - } - - } else { - registerBroadcastReceiver(); - } - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == REQUEST_PERMISSION) { - if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - if (!mDestroyed) { - registerBroadcastReceiver(); - } - } - return; - } - - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - - mDestroyed = true; - if (mReceiverRegistered) { - unregisterReceiver(mReceiver); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(Menu.NONE, MENU_ITEM_ABOUT, 0, R.string.menu_item_about) - .setIcon(R.drawable.ic_info_outline_white_24dp) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == MENU_ITEM_ABOUT) { - showAboutDialog(); - return true; - } - - return super.onOptionsItemSelected(item); - } - - private void showAboutDialog() { - String esptouchVer = IEsptouchTask.ESPTOUCH_VERSION; - String appVer = ""; - PackageManager packageManager = getPackageManager(); - try { - PackageInfo info = packageManager.getPackageInfo(getPackageName(), 0); - appVer = info.versionName; - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - } - - CharSequence[] items = new CharSequence[]{ - getString(R.string.about_app_version, appVer), - getString(R.string.about_esptouch_version, esptouchVer), - }; - new AlertDialog.Builder(this) - .setTitle(R.string.menu_item_about) - .setIcon(R.drawable.ic_info_outline_black_24dp) - .setItems(items, null) - .show(); - } - - private boolean isSDKAtLeastP() { - return Build.VERSION.SDK_INT >= 28; - } - - private void registerBroadcastReceiver() { - IntentFilter filter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION); - if (isSDKAtLeastP()) { - filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION); - } - registerReceiver(mReceiver, filter); - mReceiverRegistered = true; - } - - private void onWifiChanged(WifiInfo info) { - boolean disconnected = info == null - || info.getNetworkId() == -1 - || "".equals(info.getSSID()); - if (disconnected) { - mApSsidTV.setText(""); - mApSsidTV.setTag(null); - mApBssidTV.setText(""); - mMessageTV.setText(R.string.no_wifi_connection); - mConfirmBtn.setEnabled(false); - - if (isSDKAtLeastP()) { - checkLocation(); - } - - if (mTask != null) { - mTask.cancelEsptouch(); - mTask = null; - new AlertDialog.Builder(EsptouchDemoActivity.this) - .setMessage(R.string.configure_wifi_change_message) - .setNegativeButton(android.R.string.cancel, null) - .show(); - } - } else { - String ssid = info.getSSID(); - if (ssid.startsWith("\"") && ssid.endsWith("\"")) { - ssid = ssid.substring(1, ssid.length() - 1); - } - mApSsidTV.setText(ssid); - mApSsidTV.setTag(ByteUtil.getBytesByString(ssid)); - byte[] ssidOriginalData = TouchNetUtil.getOriginalSsidBytes(info); - mApSsidTV.setTag(ssidOriginalData); - - String bssid = info.getBSSID(); - mApBssidTV.setText(bssid); - - mConfirmBtn.setEnabled(true); - mMessageTV.setText(""); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - int frequency = info.getFrequency(); - if (frequency > 4900 && frequency < 5900) { - // Connected 5G wifi. Device does not support 5G - mMessageTV.setText(R.string.wifi_5g_message); - } - } - } - } - - private void checkLocation() { - boolean enable; - LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - enable = locationManager != null && LocationManagerCompat.isLocationEnabled(locationManager); - if (!enable) { - mMessageTV.setText(R.string.location_disable_message); - } - } - - @Override - public void onClick(View v) { - if (v == mConfirmBtn) { - byte[] ssid = mApSsidTV.getTag() == null ? ByteUtil.getBytesByString(mApSsidTV.getText().toString()) - : (byte[]) mApSsidTV.getTag(); - byte[] password = ByteUtil.getBytesByString(mApPasswordET.getText().toString()); - byte[] bssid = TouchNetUtil.parseBssid2bytes(mApBssidTV.getText().toString()); - byte[] deviceCount = mDeviceCountET.getText().toString().getBytes(); - byte[] broadcast = {(byte) (mPackageModeGroup.getCheckedRadioButtonId() == R.id.package_broadcast - ? 1 : 0)}; - - if (mTask != null) { - mTask.cancelEsptouch(); - } - mTask = new EsptouchAsyncTask4(this); - mTask.execute(ssid, bssid, password, deviceCount, broadcast); - } - } - - private static class EsptouchAsyncTask4 extends AsyncTask> { - private WeakReference mActivity; - - private final Object mLock = new Object(); - private ProgressDialog mProgressDialog; - private AlertDialog mResultDialog; - private IEsptouchTask mEsptouchTask; - - EsptouchAsyncTask4(EsptouchDemoActivity activity) { - mActivity = new WeakReference<>(activity); - } - - void cancelEsptouch() { - cancel(true); - if (mProgressDialog != null) { - mProgressDialog.dismiss(); - } - if (mResultDialog != null) { - mResultDialog.dismiss(); - } - if (mEsptouchTask != null) { - mEsptouchTask.interrupt(); - } - } - - @Override - protected void onPreExecute() { - Activity activity = mActivity.get(); - mProgressDialog = new ProgressDialog(activity); - mProgressDialog.setMessage(activity.getString(R.string.configuring_message)); - mProgressDialog.setCanceledOnTouchOutside(false); - mProgressDialog.setOnCancelListener(dialog -> { - synchronized (mLock) { - if (mEsptouchTask != null) { - mEsptouchTask.interrupt(); - } - } - }); - mProgressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, activity.getText(android.R.string.cancel), - (dialog, which) -> { - synchronized (mLock) { - if (mEsptouchTask != null) { - mEsptouchTask.interrupt(); - } - } - }); - mProgressDialog.show(); - } - - @Override - protected void onProgressUpdate(IEsptouchResult... values) { - Context context = mActivity.get(); - if (context != null) { - IEsptouchResult result = values[0]; - Log.i(TAG, "EspTouchResult: " + result); - String text = result.getBssid() + " is connected to the wifi"; - Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); - } - } - - @Override - protected List doInBackground(byte[]... params) { - EsptouchDemoActivity activity = mActivity.get(); - int taskResultCount; - synchronized (mLock) { - byte[] apSsid = params[0]; - byte[] apBssid = params[1]; - byte[] apPassword = params[2]; - byte[] deviceCountData = params[3]; - byte[] broadcastData = params[4]; - taskResultCount = deviceCountData.length == 0 ? -1 : Integer.parseInt(new String(deviceCountData)); - Context context = activity.getApplicationContext(); - mEsptouchTask = new EsptouchTask(apSsid, apBssid, apPassword, context); - mEsptouchTask.setPackageBroadcast(broadcastData[0] == 1); - mEsptouchTask.setEsptouchListener(this::publishProgress); - } - return mEsptouchTask.executeForResults(taskResultCount); - } - - @Override - protected void onPostExecute(List result) { - EsptouchDemoActivity activity = mActivity.get(); - activity.mTask = null; - mProgressDialog.dismiss(); - if (result == null) { - mResultDialog = new AlertDialog.Builder(activity) - .setMessage(R.string.configure_result_failed_port) - .setPositiveButton(android.R.string.ok, null) - .show(); - mResultDialog.setCanceledOnTouchOutside(false); - return; - } - - // check whether the task is cancelled and no results received - IEsptouchResult firstResult = result.get(0); - if (firstResult.isCancelled()) { - return; - } - // the task received some results including cancelled while - // executing before receiving enough results - - if (!firstResult.isSuc()) { - mResultDialog = new AlertDialog.Builder(activity) - .setMessage(R.string.configure_result_failed) - .setPositiveButton(android.R.string.ok, null) - .show(); - mResultDialog.setCanceledOnTouchOutside(false); - return; - } - - ArrayList resultMsgList = new ArrayList<>(result.size()); - for (IEsptouchResult touchResult : result) { - String message = activity.getString(R.string.configure_result_success_item, - touchResult.getBssid(), touchResult.getInetAddress().getHostAddress()); - resultMsgList.add(message); - } - CharSequence[] items = new CharSequence[resultMsgList.size()]; - mResultDialog = new AlertDialog.Builder(activity) - .setTitle(R.string.configure_result_success) - .setItems(resultMsgList.toArray(items), null) - .setPositiveButton(android.R.string.ok, null) - .show(); - mResultDialog.setCanceledOnTouchOutside(false); - } - } -} diff --git a/app/src/main/java/com/espressif/iot_esptouch_demo/EspTouchApp.java b/app/src/main/java/com/espressif/iot_esptouch_demo/EspTouchApp.java new file mode 100644 index 0000000..de0c2df --- /dev/null +++ b/app/src/main/java/com/espressif/iot_esptouch_demo/EspTouchApp.java @@ -0,0 +1,89 @@ +package com.espressif.iot_esptouch_demo; + +import android.app.Application; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.location.LocationManager; +import android.net.wifi.WifiManager; +import android.os.Build; + +import androidx.lifecycle.LifecycleOwner; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Observer; + +import java.util.HashMap; +import java.util.Map; + +public class EspTouchApp extends Application { + private static EspTouchApp app; + + private MutableLiveData mBroadcastData; + + private Map mCacheMap; + + private BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action == null) { + return; + } + + switch (action) { + case WifiManager.NETWORK_STATE_CHANGED_ACTION: + case LocationManager.PROVIDERS_CHANGED_ACTION: + mBroadcastData.setValue(action); + break; + } + } + }; + + @Override + public void onCreate() { + super.onCreate(); + + app = this; + + mCacheMap = new HashMap<>(); + + mBroadcastData = new MutableLiveData<>(); + IntentFilter filter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION); + } + registerReceiver(mReceiver, filter); + } + + @Override + public void onTerminate() { + super.onTerminate(); + + unregisterReceiver(mReceiver); + } + + public static EspTouchApp getInstance() { + return app; + } + + public void observeBroadcast(LifecycleOwner owner, Observer observer) { + mBroadcastData.observe(owner, observer); + } + + public void observeBroadcastForever(Observer observer) { + mBroadcastData.observeForever(observer); + } + + public void removeBroadcastObserver(Observer observer) { + mBroadcastData.removeObserver(observer); + } + + public void putCache(String key, Object value) { + mCacheMap.put(key, value); + } + + public Object takeCache(String key) { + return mCacheMap.remove(key); + } +} diff --git a/app/src/main/java/com/espressif/iot_esptouch_demo/NetUtils.java b/app/src/main/java/com/espressif/iot_esptouch_demo/NetUtils.java new file mode 100644 index 0000000..8a5bb89 --- /dev/null +++ b/app/src/main/java/com/espressif/iot_esptouch_demo/NetUtils.java @@ -0,0 +1,147 @@ +package com.espressif.iot_esptouch_demo; + +import android.net.DhcpInfo; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Enumeration; + +public class NetUtils { + public static boolean isWifiConnected(WifiManager wifiManager) { + WifiInfo wifiInfo = wifiManager.getConnectionInfo(); + return wifiInfo != null + && wifiInfo.getNetworkId() != -1 + && !"".equals(wifiInfo.getSSID()); + } + + public static byte[] getRawSsidBytes(WifiInfo info) { + try { + Method method = info.getClass().getMethod("getWifiSsid"); + method.setAccessible(true); + Object wifiSsid = method.invoke(info); + if (wifiSsid == null) { + return null; + } + method = wifiSsid.getClass().getMethod("getOctets"); + method.setAccessible(true); + return (byte[]) method.invoke(wifiSsid); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | NullPointerException e) { + e.printStackTrace(); + } + return null; + } + + public static byte[] getRawSsidBytesOrElse(WifiInfo info, byte[] orElse) { + byte[] raw = getRawSsidBytes(info); + return raw != null ? raw : orElse; + } + + public static String getSsidString(WifiInfo info) { + String ssid = info.getSSID(); + if (ssid.startsWith("\"") && ssid.endsWith("\"")) { + ssid = ssid.substring(1, ssid.length() - 1); + } + return ssid; + } + + public static InetAddress getBroadcastAddress(WifiManager wifi) { + DhcpInfo dhcp = wifi.getDhcpInfo(); + if (dhcp != null) { + int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; + byte[] quads = new byte[4]; + for (int k = 0; k < 4; k++) { + quads[k] = (byte) ((broadcast >> k * 8) & 0xFF); + } + try { + return InetAddress.getByAddress(quads); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + } + + try { + return InetAddress.getByName("255.255.255.255"); + } catch (UnknownHostException e) { + e.printStackTrace(); + } + // Impossible arrive here + return null; + } + + public static boolean is5G(int frequency) { + return frequency > 4900 && frequency < 5900; + } + + public static InetAddress getAddress(int ipAddress) { + byte[] ip = new byte[]{ + (byte) (ipAddress & 0xff), + (byte) ((ipAddress >> 8) & 0xff), + (byte) ((ipAddress >> 16) & 0xff), + (byte) ((ipAddress >> 24) & 0xff) + }; + + try { + return InetAddress.getByAddress(ip); + } catch (UnknownHostException e) { + e.printStackTrace(); + // Impossible arrive here + return null; + } + } + + private static InetAddress getAddress(boolean isIPv4) { + try { + Enumeration enums = NetworkInterface.getNetworkInterfaces(); + while (enums.hasMoreElements()) { + NetworkInterface ni = enums.nextElement(); + Enumeration addrs = ni.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress address = addrs.nextElement(); + if (!address.isLoopbackAddress()) { + if (isIPv4 && address instanceof Inet4Address) { + return address; + } + if (!isIPv4 && address instanceof Inet6Address) { + return address; + } + } + } + } + } catch (SocketException e) { + e.printStackTrace(); + } + return null; + } + + public static InetAddress getIPv4Address() { + return getAddress(true); + } + + public static InetAddress getIPv6Address() { + return getAddress(false); + } + + /** + * @param bssid the bssid like aa:bb:cc:dd:ee:ff + * @return byte array converted from bssid + */ + public static byte[] convertBssid2Bytes(String bssid) { + String[] bssidSplits = bssid.split(":"); + if (bssidSplits.length != 6) { + throw new IllegalArgumentException("Invalid bssid format"); + } + byte[] result = new byte[bssidSplits.length]; + for (int i = 0; i < bssidSplits.length; i++) { + result[i] = (byte) Integer.parseInt(bssidSplits[i], 16); + } + return result; + } +} diff --git a/app/src/main/res/drawable-hdpi/baseline_info_black_24.png b/app/src/main/res/drawable-hdpi/baseline_info_black_24.png new file mode 100755 index 0000000000000000000000000000000000000000..35eb346c237b0c5ae389fcbf11e087a7de5e1702 GIT binary patch literal 307 zcmV-30nGl1P)K8YU7Pe?vh5^O``|cR7$pA*V~xh6BtmeRMbutyJsW9Bf~KBz{=mh|6ry_ zhR>8SWx<9!S2is8BO_A6H*3VPH3bQQat?@R2XX@ZAOS1!V}=B7hQ|bn*aSEFNaXrB zB%Bb(YD!9K#IYk?T1MV$EfMENwCqfw9U46Z2|Su!52Zqkt5D|V&>W>PA8m5vMhZ>aH9I8=%&7lezoInW$D`#Xy!55Lz*CXQgd_<&tq6gsGm}C7>f&l;k002ovPDHLk FV1mx-fOP-> literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/baseline_info_black_24.png b/app/src/main/res/drawable-mdpi/baseline_info_black_24.png new file mode 100755 index 0000000000000000000000000000000000000000..4edd578634d8c5b83f6a43505f178fd69a810fde GIT binary patch literal 215 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_+id7dtgAr*{!FEg^WI7l4*Xm4N@ z@siC^edX42&P#<+2N-VZ3FI=IWs|$qLQ2NDAa@Riqf_W;%xjC%W!g z`C#I`kQY1a*YvG__~_2w<%+(WE)+Zz{rh`%$D^VKuG1ZQ?ryy=7XK?MQLC9#7gGpy ODTAl0pUXO@geCyLxmDEw literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/baseline_info_black_24.png b/app/src/main/res/drawable-xhdpi/baseline_info_black_24.png new file mode 100755 index 0000000000000000000000000000000000000000..eec71311281206c4d2050ae67fba425a1d683fbb GIT binary patch literal 366 zcmV-!0g?WRP)YR^}+M~W#mP7my}q`66Xf-*bQ-V2_eQ7;&WTXg1+`XB;fk|zmEdukr11w z5FfIcMnZ0i96a?Q5!Q=`1|;GdagonepCzTa&;oB_x$VOaejz zv~*6)0>`AI)F6hdMrkz-w4h9w2F6jAO#@3PCy3dXES#V`nFbzF?o0!BC}*aDGn7Ts zz#__oXa89S|CKp=i|!yann6(xe*;2QP#JmnJ~c*aEz(P4~!R^!n|hPjV2y2l7>acmMjTtWr9NG}s{q?gC2M33pk zy19&_3XL-ti?;9_RqQ!iY^|F%vQ)eJdRoMFWU*^3qJkAXK$g4DN=ll=b>yIH%%X&e z97B#e%0vnqLJk|Epnb@32Pj}MZ;|8Pu$bIB$U_}++Jp-AI~A&nT+VqL=nOe*L*51w z+sJg(>p;iIu#z8M2l~NkQVk%l1Bn4rokpHJjTzJViahs~=@{)q0osXCf&!Fa)ItGj zVRQxs=nO`Wk@v%1JjUo%kbz!d^drbX-!b|UWS}n?y$LeV8;qU@8R$7ir-BT05~F62 zftna4K?X`N+8$(}?Y3_}erNgi1I~CK=yYtiunDPFd%wwFNrq!y2Rcrs?Xf*5!kM@p zrJ*afmkrQH9%{$+!s;E1DPVV~r!li(&2Qf(jOK z&Hu+2f1js1%*Bc=yg(Iu!IsEBaaPyMGgP8y^y0`Q`nZe=bcsGD;n)U7xS!+j9${_# fzgpC4wcvgN^F?t@4}YHe00000NkvXXu0mjfG*9|g literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/esptouch_demo_activity.xml b/app/src/main/res/layout/activity_esptouch.xml similarity index 59% rename from app/src/main/res/layout/esptouch_demo_activity.xml rename to app/src/main/res/layout/activity_esptouch.xml index 4e4bcba..9ee7bdd 100644 --- a/app/src/main/res/layout/esptouch_demo_activity.xml +++ b/app/src/main/res/layout/activity_esptouch.xml @@ -1,64 +1,69 @@ + + app:layout_constraintTop_toBottomOf="@id/apSsidLabel" /> + app:layout_constraintBaseline_toBaselineOf="@id/apBssidLabel" + app:layout_constraintStart_toEndOf="@id/apBssidLabel" + app:layout_constraintTop_toTopOf="@id/apBssidLabel" /> + android:hint="@string/esptouch1_device_count_title" + app:layout_constraintTop_toBottomOf="@id/apPasswordLayout"> + android:inputType="number" + android:text="1" /> + app:layout_constraintTop_toBottomOf="@id/deviceCountLayout"> + android:text="@string/esptouch1_package_broadcast" /> + android:text="@string/esptouch1_package_multicast" /> - \ No newline at end of file + + + + diff --git a/app/src/main/res/layout/activity_esptouch2.xml b/app/src/main/res/layout/activity_esptouch2.xml new file mode 100644 index 0000000..a9a78a2 --- /dev/null +++ b/app/src/main/res/layout/activity_esptouch2.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..b939681 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main_item.xml b/app/src/main/res/layout/activity_main_item.xml new file mode 100644 index 0000000..d3f3b0c --- /dev/null +++ b/app/src/main/res/layout/activity_main_item.xml @@ -0,0 +1,15 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_provision.xml b/app/src/main/res/layout/activity_provision.xml new file mode 100644 index 0000000..fe24e75 --- /dev/null +++ b/app/src/main/res/layout/activity_provision.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a33c85e..bff6aec 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1,23 +1,48 @@ EspTouch - 关于App - App版本: %s - EspTouch版本: %s - SSID: - BSSID: - 密码: - 设备数量: - 广播 - 组播 - 确认 - 设备不支持 5G Wifi, 请确认当前连接的 Wifi 为 2.4G - 位置信息(GPS)不可用 - 没有 Wifi 连接 - Wifi 已断开或发生了变化 - Esptouch 正在执行配网, 请稍等片刻… - EspTouch 配网失败 - 建立 Esptouch 任务失败, 端口可能被其他程序占用 - EspTouch 完成 - BSSID = %1$s, 地址 = %2$s + 关于 App + App 版本: %s + + 主页 + + 需要位置权限来获取 Wi-Fi 信息。 \n点击申请权限 + 请打开 GPS 以获取 Wi-Fi 信息。 + 请先连上 Wi-Fi + 当前连接的是 5G Wi-Fi, 设备仅支持 2.4G Wi-Fi + + EspTouch + EspTouch 版本: %s + SSID: + BSSID: + 密码: + 设备数量: + 广播 + 组播 + 确认 + 设备不支持 5G Wi-Fi, 请确认当前连接的 Wi-Fi 为 2.4G, 或者您可以尝试选择组播 + ⚠️警告️ + 在 Android M 及以上版本,如果您禁止授权位置权限,APP将无法获取 Wi-Fi 信息。 + Wi-Fi 已断开或发生了变化 + Esptouch 正在执行配网, 请稍等片刻… + EspTouch 配网失败 + 建立 EspTouch 任务失败, 端口可能被其他程序占用 + EspTouch 完成 + BSSID: %1$s, 地址: %2$s + + EspTouch V2 + EspTouch V2 版本: %s + SSID: + BSSID: + IP: + 密码 + AES Key + AES Key 必须为空或者16字节数据 + 自定义数据 + 自定义数据不能超过127字节 + + 配网 + 停止 + 捕获到错误:%s + 没有找到设备 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index bf38eaf..710678c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,21 +3,46 @@ EspTouch About App App Version: %s - EspTouch Version: %s - SSID: - BSSID: - Password: - Device count: - Broadcast - Multicast - Confirm - Device don\'t support 5G Wifi, please make sure the currently connected Wifi is 2.4G - Location(GPS) is disable - No Wifi connection - Esptouch is configuring, please wait for a moment… - Wifi disconnected or changed - EspTouch failed - Create Esptouch task failed, the EspTouch port could be used by other thread - EspTouch 完成 - BSSID = %1$s, InetAddress = %2$s + + Home + + APP require Location permission to get Wi-Fi information. \nClick to request permission + Please turn on GPS to get Wi-Fi information. + Please connect Wi-Fi first. + Current Wi-Fi connection is 5G, but the device just support 2.4G. + + EspTouch + EspTouch Version: %s + SSID: + BSSID: + Password: + Device count: + Broadcast + Multicast + Confirm + Device don\'t support 5G Wi-Fi, please make sure the currently connected Wi-Fi is 2.4G, or you can try multicast + ⚠️Warning + On Android M or higher version, App can\'t get Wi-Fi connection information if you forbid Location permission. + Esptouch is configuring, please wait for a moment… + Wi-Fi disconnected or changed + EspTouch failed + Create EspTouch task failed, the EspTouch port could be used by other thread + EspTouch 完成 + BSSID = %1$s, InetAddress = %2$s + + EspTouch V2 + EspTouch V2 Version: %s + SSID: + BSSID: + IP: + Password + AES Key + AES Key must be null or 16 bytes data + Custom Data + Custom data can\'t be more than 127 bytes + + Provision + Stop + Catch exception: %s + Not found any devices diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index fef37f9..0b6e4f1 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -16,5 +16,4 @@