Copy/paste for Wi-Fi configurations
This commit is contained in:
@@ -3,6 +3,7 @@ package be.mygod.vpnhotspot
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.app.UiModeManager
|
import android.app.UiModeManager
|
||||||
|
import android.content.ClipboardManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.wifi.WifiManager
|
import android.net.wifi.WifiManager
|
||||||
@@ -69,6 +70,7 @@ class App : Application() {
|
|||||||
}
|
}
|
||||||
val pref by lazy { PreferenceManager.getDefaultSharedPreferences(deviceStorage) }
|
val pref by lazy { PreferenceManager.getDefaultSharedPreferences(deviceStorage) }
|
||||||
val connectivity by lazy { getSystemService<ConnectivityManager>()!! }
|
val connectivity by lazy { getSystemService<ConnectivityManager>()!! }
|
||||||
|
val clipboard by lazy { getSystemService<ClipboardManager>()!! }
|
||||||
val uiMode by lazy { getSystemService<UiModeManager>()!! }
|
val uiMode by lazy { getSystemService<UiModeManager>()!! }
|
||||||
val wifi by lazy { getSystemService<WifiManager>()!! }
|
val wifi by lazy { getSystemService<WifiManager>()!! }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package be.mygod.vpnhotspot.net.wifi.configuration
|
package be.mygod.vpnhotspot.net.wifi.configuration
|
||||||
|
|
||||||
import android.annotation.TargetApi
|
import android.annotation.TargetApi
|
||||||
|
import android.content.ClipData
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.net.wifi.WifiConfiguration
|
import android.net.wifi.WifiConfiguration
|
||||||
import android.net.wifi.WifiConfiguration.AuthAlgorithm
|
import android.net.wifi.WifiConfiguration.AuthAlgorithm
|
||||||
@@ -8,14 +9,19 @@ import android.os.Build
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.util.Base64
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import be.mygod.vpnhotspot.AlertDialogFragment
|
import be.mygod.vpnhotspot.AlertDialogFragment
|
||||||
import be.mygod.vpnhotspot.App.Companion.app
|
import be.mygod.vpnhotspot.App.Companion.app
|
||||||
import be.mygod.vpnhotspot.R
|
import be.mygod.vpnhotspot.R
|
||||||
|
import be.mygod.vpnhotspot.util.toByteArray
|
||||||
|
import be.mygod.vpnhotspot.util.toParcelable
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
import kotlinx.android.synthetic.main.dialog_wifi_ap.view.*
|
import kotlinx.android.synthetic.main.dialog_wifi_ap.view.*
|
||||||
import java.lang.IllegalStateException
|
import java.lang.IllegalStateException
|
||||||
@@ -27,7 +33,13 @@ import java.nio.charset.Charset
|
|||||||
* This dialog has been deprecated in API 28, but we are still using it since it works better for our purposes.
|
* This dialog has been deprecated in API 28, but we are still using it since it works better for our purposes.
|
||||||
* Related: https://android.googlesource.com/platform/packages/apps/Settings/+/defb1183ecb00d6231bac7d934d07f58f90261ea
|
* Related: https://android.googlesource.com/platform/packages/apps/Settings/+/defb1183ecb00d6231bac7d934d07f58f90261ea
|
||||||
*/
|
*/
|
||||||
class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiApDialogFragment.Arg>(), TextWatcher {
|
class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiApDialogFragment.Arg>(), TextWatcher,
|
||||||
|
Toolbar.OnMenuItemClickListener {
|
||||||
|
companion object {
|
||||||
|
private const val BASE64_FLAGS = Base64.NO_PADDING or Base64.NO_WRAP
|
||||||
|
private val channels by lazy { (1..165).map { BandOption.Channel(it) } }
|
||||||
|
}
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Arg(val configuration: WifiConfiguration,
|
data class Arg(val configuration: WifiConfiguration,
|
||||||
val readOnly: Boolean = false,
|
val readOnly: Boolean = false,
|
||||||
@@ -59,29 +71,29 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
|||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var dialogView: View
|
private lateinit var dialogView: View
|
||||||
override val ret: Arg? get() {
|
private lateinit var bandOptions: MutableList<BandOption>
|
||||||
return Arg(WifiConfiguration().apply {
|
private var started = false
|
||||||
SSID = dialogView.ssid.text.toString()
|
override val ret get() = Arg(WifiConfiguration().apply {
|
||||||
allowedKeyManagement.set(
|
SSID = dialogView.ssid.text.toString()
|
||||||
if (arg.p2pMode) WifiConfiguration.KeyMgmt.WPA_PSK else dialogView.security.selectedItemPosition)
|
allowedKeyManagement.set(
|
||||||
allowedAuthAlgorithms.set(AuthAlgorithm.OPEN)
|
if (arg.p2pMode) WifiConfiguration.KeyMgmt.WPA_PSK else dialogView.security.selectedItemPosition)
|
||||||
if (dialogView.password.length() != 0) preSharedKey = dialogView.password.text.toString()
|
allowedAuthAlgorithms.set(AuthAlgorithm.OPEN)
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (dialogView.password.length() != 0) preSharedKey = dialogView.password.text.toString()
|
||||||
val bandOption = dialogView.band.selectedItem as BandOption
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
apBand = bandOption.apBand
|
val bandOption = dialogView.band.selectedItem as BandOption
|
||||||
apChannel = bandOption.apChannel
|
apBand = bandOption.apBand
|
||||||
}
|
apChannel = bandOption.apChannel
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
override fun AlertDialog.Builder.prepare(listener: DialogInterface.OnClickListener) {
|
override fun AlertDialog.Builder.prepare(listener: DialogInterface.OnClickListener) {
|
||||||
val activity = requireActivity()
|
val activity = requireActivity()
|
||||||
dialogView = activity.layoutInflater.inflate(R.layout.dialog_wifi_ap, null)
|
dialogView = activity.layoutInflater.inflate(R.layout.dialog_wifi_ap, null)
|
||||||
setView(dialogView)
|
setView(dialogView)
|
||||||
setTitle(R.string.configuration_view)
|
|
||||||
if (!arg.readOnly) setPositiveButton(R.string.wifi_save, listener)
|
if (!arg.readOnly) setPositiveButton(R.string.wifi_save, listener)
|
||||||
setNegativeButton(R.string.donations__button_close, null)
|
setNegativeButton(R.string.donations__button_close, null)
|
||||||
dialogView.ssid.setText(arg.configuration.SSID)
|
dialogView.toolbar.inflateMenu(R.menu.toolbar_configuration)
|
||||||
|
dialogView.toolbar.setOnMenuItemClickListener(this@WifiApDialogFragment)
|
||||||
if (!arg.readOnly) dialogView.ssid.addTextChangedListener(this@WifiApDialogFragment)
|
if (!arg.readOnly) dialogView.ssid.addTextChangedListener(this@WifiApDialogFragment)
|
||||||
if (arg.p2pMode) dialogView.security_wrapper.isGone = true else dialogView.security.apply {
|
if (arg.p2pMode) dialogView.security_wrapper.isGone = true else dialogView.security.apply {
|
||||||
adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0,
|
adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0,
|
||||||
@@ -95,35 +107,46 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
|||||||
dialogView.password_wrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE
|
dialogView.password_wrapper.isGone = position == WifiConfiguration.KeyMgmt.NONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val selected = arg.configuration.allowedKeyManagement.nextSetBit(0)
|
|
||||||
check(selected >= 0) { "No key management selected" }
|
|
||||||
check(arg.configuration.allowedKeyManagement.nextSetBit(selected + 1) < 0) {
|
|
||||||
"More than 1 key managements supplied"
|
|
||||||
}
|
|
||||||
setSelection(selected)
|
|
||||||
}
|
}
|
||||||
dialogView.password.setText(arg.configuration.preSharedKey)
|
|
||||||
if (!arg.readOnly) dialogView.password.addTextChangedListener(this@WifiApDialogFragment)
|
if (!arg.readOnly) dialogView.password.addTextChangedListener(this@WifiApDialogFragment)
|
||||||
if (Build.VERSION.SDK_INT >= 23) dialogView.band.apply {
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
val options = mutableListOf<BandOption>().apply {
|
bandOptions = mutableListOf<BandOption>().apply {
|
||||||
if (arg.p2pMode) add(BandOption.BandAny) else {
|
if (arg.p2pMode) add(BandOption.BandAny) else {
|
||||||
if (Build.VERSION.SDK_INT >= 28) add(BandOption.BandAny)
|
if (Build.VERSION.SDK_INT >= 28) add(BandOption.BandAny)
|
||||||
add(BandOption.Band2GHz)
|
add(BandOption.Band2GHz)
|
||||||
add(BandOption.Band5GHz)
|
add(BandOption.Band5GHz)
|
||||||
}
|
}
|
||||||
addAll((1..165).map { BandOption.Channel(it) })
|
addAll(channels)
|
||||||
}
|
}
|
||||||
adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0, options).apply {
|
dialogView.band.adapter = ArrayAdapter(activity, android.R.layout.simple_spinner_item, 0,
|
||||||
|
bandOptions).apply {
|
||||||
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
}
|
}
|
||||||
setSelection(if (arg.configuration.apChannel in 1..165) {
|
|
||||||
options.indexOfFirst { it.apChannel == arg.configuration.apChannel }
|
|
||||||
} else options.indexOfFirst { it.apBand == arg.configuration.apBand })
|
|
||||||
} else dialogView.band_wrapper.isGone = true
|
} else dialogView.band_wrapper.isGone = true
|
||||||
|
populateFromConfiguration(arg.configuration)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
private fun populateFromConfiguration(configuration: WifiConfiguration) {
|
||||||
super.onResume()
|
dialogView.ssid.setText(configuration.SSID)
|
||||||
|
if (!arg.p2pMode) {
|
||||||
|
val selected = configuration.allowedKeyManagement.nextSetBit(0)
|
||||||
|
check(selected >= 0) { "No key management selected" }
|
||||||
|
check(configuration.allowedKeyManagement.nextSetBit(selected + 1) < 0) {
|
||||||
|
"More than 1 key managements supplied"
|
||||||
|
}
|
||||||
|
dialogView.security.setSelection(selected)
|
||||||
|
}
|
||||||
|
dialogView.password.setText(configuration.preSharedKey)
|
||||||
|
if (Build.VERSION.SDK_INT >= 23) {
|
||||||
|
dialogView.band.setSelection(if (configuration.apChannel in 1..165) {
|
||||||
|
bandOptions.indexOfFirst { it.apChannel == configuration.apChannel }
|
||||||
|
} else bandOptions.indexOfFirst { it.apBand == configuration.apBand })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
started = true
|
||||||
if (!arg.readOnly) validate()
|
if (!arg.readOnly) validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +154,7 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
|||||||
* This function is reached only if not arg.readOnly.
|
* This function is reached only if not arg.readOnly.
|
||||||
*/
|
*/
|
||||||
private fun validate() {
|
private fun validate() {
|
||||||
|
if (!started) return
|
||||||
val ssidValid = dialogView.ssid.length() != 0 &&
|
val ssidValid = dialogView.ssid.length() != 0 &&
|
||||||
Charset.forName("UTF-8").encode(dialogView.ssid.text.toString()).limit() <= 32
|
Charset.forName("UTF-8").encode(dialogView.ssid.text.toString()).limit() <= 32
|
||||||
val passwordValid = when (dialogView.security.selectedItemPosition) {
|
val passwordValid = when (dialogView.security.selectedItemPosition) {
|
||||||
@@ -146,4 +170,19 @@ class WifiApDialogFragment : AlertDialogFragment<WifiApDialogFragment.Arg, WifiA
|
|||||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { }
|
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { }
|
||||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { }
|
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { }
|
||||||
override fun afterTextChanged(editable: Editable) = validate()
|
override fun afterTextChanged(editable: Editable) = validate()
|
||||||
|
|
||||||
|
override fun onMenuItemClick(item: MenuItem?) = when (item?.itemId) {
|
||||||
|
android.R.id.copy -> {
|
||||||
|
app.clipboard.primaryClip =
|
||||||
|
ClipData.newPlainText(null, Base64.encodeToString(ret.configuration.toByteArray(), BASE64_FLAGS))
|
||||||
|
true
|
||||||
|
}
|
||||||
|
android.R.id.paste -> {
|
||||||
|
app.clipboard.primaryClip?.getItemAt(0)?.text?.let {
|
||||||
|
populateFromConfiguration(Base64.decode(it.toString(), BASE64_FLAGS).toParcelable())
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
|
|||||||
import android.content.*
|
import android.content.*
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
|
import android.os.Parcelable
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
@@ -42,6 +43,16 @@ fun <T> useParcel(block: (Parcel) -> T) = Parcel.obtain().run {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Parcelable.toByteArray(parcelableFlags: Int = 0) = useParcel { p ->
|
||||||
|
p.writeParcelable(this, parcelableFlags)
|
||||||
|
p.marshall()
|
||||||
|
}
|
||||||
|
fun <T : Parcelable> ByteArray.toParcelable() = useParcel { p ->
|
||||||
|
p.unmarshall(this, 0, size)
|
||||||
|
p.setDataPosition(0)
|
||||||
|
p.readParcelable<T>(javaClass.classLoader)
|
||||||
|
}
|
||||||
|
|
||||||
fun broadcastReceiver(receiver: (Context, Intent) -> Unit) = object : BroadcastReceiver() {
|
fun broadcastReceiver(receiver: (Context, Intent) -> Unit) = object : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context, intent: Intent) = receiver(context, intent)
|
override fun onReceive(context: Context, intent: Intent) = receiver(context, intent)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Based on: https://android.googlesource.com/platform/packages/apps/Settings/+/6b4a31c/res/layout/wifi_ap_dialog.xml -->
|
<!--
|
||||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
Based on:
|
||||||
|
* https://github.com/material-components/material-components-android/blob/da6096bb8df2ac5b0cabeaa7960501d4083e4ea9/lib/java/com/google/android/material/dialog/res/layout/mtrl_alert_dialog_title.xml
|
||||||
|
* https://android.googlesource.com/platform/packages/apps/Settings/+/6b4a31c/res/layout/wifi_ap_dialog.xml
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2018 The Android Open Source Project
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
@@ -11,85 +16,97 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="300sp"
|
android:layout_width="300sp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fadeScrollbars="false">
|
android:orientation="vertical">
|
||||||
<LinearLayout
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:descendantFocusability="beforeDescendants"
|
android:paddingLeft="20dp"
|
||||||
android:focusableInTouchMode="true"
|
android:paddingRight="20dp"
|
||||||
style="@style/wifi_item">
|
app:title="@string/configuration_view"/>
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<ScrollView
|
||||||
android:id="@+id/ssid_wrapper"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:fadeScrollbars="false">
|
||||||
android:layout_marginTop="8dip">
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/ssid"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/wifi_item_edit_content"
|
|
||||||
android:hint="@string/wifi_ssid"
|
|
||||||
android:inputType="textMultiLine|textNoSuggestions"
|
|
||||||
android:maxLength="32" />
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/security_wrapper"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dip"
|
android:descendantFocusability="beforeDescendants"
|
||||||
android:orientation="vertical">
|
android:focusableInTouchMode="true"
|
||||||
<TextView
|
style="@style/wifi_item">
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/ssid_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/ssid"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_edit_content"
|
||||||
|
android:hint="@string/wifi_ssid"
|
||||||
|
android:inputType="textMultiLine|textNoSuggestions"
|
||||||
|
android:maxLength="32" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/security_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/wifi_item_label"
|
android:layout_marginTop="8dip"
|
||||||
android:text="@string/wifi_security" />
|
android:orientation="vertical">
|
||||||
<Spinner
|
<TextView
|
||||||
android:id="@+id/security"
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_label"
|
||||||
|
android:text="@string/wifi_security" />
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/security"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_content"
|
||||||
|
android:prompt="@string/wifi_security" />
|
||||||
|
</LinearLayout>
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/password_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/wifi_item_content"
|
android:layout_marginTop="8dip"
|
||||||
android:prompt="@string/wifi_security" />
|
app:passwordToggleEnabled="true"
|
||||||
|
app:errorEnabled="true">
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_edit_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:hint="@string/wifi_password"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:typeface="monospace"
|
||||||
|
android:maxLength="63"
|
||||||
|
android:imeOptions="flagForceAscii" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/band_wrapper"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dip"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_label"
|
||||||
|
android:text="@string/wifi_hotspot_ap_band_title" />
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/band"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/wifi_item_content"
|
||||||
|
android:prompt="@string/wifi_hotspot_ap_band_title" />
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
</ScrollView>
|
||||||
android:id="@+id/password_wrapper"
|
</LinearLayout>
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dip"
|
|
||||||
app:passwordToggleEnabled="true"
|
|
||||||
app:errorEnabled="true">
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
|
||||||
android:id="@+id/password"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/wifi_item_edit_content"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:hint="@string/wifi_password"
|
|
||||||
android:inputType="textPassword"
|
|
||||||
android:typeface="monospace"
|
|
||||||
android:maxLength="63"
|
|
||||||
android:imeOptions="flagForceAscii" />
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/band_wrapper"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="8dip"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/wifi_item_label"
|
|
||||||
android:text="@string/wifi_hotspot_ap_band_title" />
|
|
||||||
<Spinner
|
|
||||||
android:id="@+id/band"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
style="@style/wifi_item_content"
|
|
||||||
android:prompt="@string/wifi_hotspot_ap_band_title" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|||||||
14
mobile/src/main/res/menu/toolbar_configuration.xml
Normal file
14
mobile/src/main/res/menu/toolbar_configuration.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item android:id="@android:id/copy"
|
||||||
|
android:alphabeticShortcut="c"
|
||||||
|
android:icon="?attr/actionModeCopyDrawable"
|
||||||
|
android:title="@android:string/copy"
|
||||||
|
app:showAsAction="ifRoom"/>
|
||||||
|
<item android:id="@android:id/paste"
|
||||||
|
android:alphabeticShortcut="v"
|
||||||
|
android:icon="?attr/actionModePasteDrawable"
|
||||||
|
android:title="@android:string/paste"
|
||||||
|
app:showAsAction="ifRoom"/>
|
||||||
|
</menu>
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
<!-- https://android.googlesource.com/platform/packages/apps/Settings/+/7efcc35/res/values/styles.xml -->
|
<!-- https://android.googlesource.com/platform/packages/apps/Settings/+/7efcc35/res/values/styles.xml -->
|
||||||
<style name="wifi_item">
|
<style name="wifi_item">
|
||||||
<item name="android:layout_marginTop">8dip</item>
|
|
||||||
<item name="android:layout_marginStart">8dip</item>
|
<item name="android:layout_marginStart">8dip</item>
|
||||||
<item name="android:layout_marginEnd">8dip</item>
|
<item name="android:layout_marginEnd">8dip</item>
|
||||||
<item name="android:paddingStart">8dip</item>
|
<item name="android:paddingStart">8dip</item>
|
||||||
|
|||||||
Reference in New Issue
Block a user