Extract string resources
This commit is contained in:
@@ -5,6 +5,7 @@ import android.app.Application
|
|||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
|
|
||||||
@@ -16,10 +17,19 @@ class App : Application() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
app = this
|
app = this
|
||||||
|
updateNotificationChannels()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onConfigurationChanged(newConfig: Configuration?) {
|
||||||
|
super.onConfigurationChanged(newConfig)
|
||||||
|
updateNotificationChannels()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateNotificationChannels() {
|
||||||
if (Build.VERSION.SDK_INT >= 26) @TargetApi(26) {
|
if (Build.VERSION.SDK_INT >= 26) @TargetApi(26) {
|
||||||
val nm = getSystemService(NotificationManager::class.java)
|
val nm = getSystemService(NotificationManager::class.java)
|
||||||
nm.createNotificationChannel(NotificationChannel(RepeaterService.CHANNEL,
|
nm.createNotificationChannel(NotificationChannel(RepeaterService.CHANNEL,
|
||||||
"Repeater Service", NotificationManager.IMPORTANCE_LOW))
|
getText(R.string.notification_channel_repeater), NotificationManager.IMPORTANCE_LOW))
|
||||||
nm.deleteNotificationChannel("hotspot") // remove old service channel
|
nm.deleteNotificationChannel("hotspot") // remove old service channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ssid @Bindable get() = binder?.service?.ssid ?: "Service inactive"
|
val ssid @Bindable get() = binder?.service?.ssid ?: getText(R.string.repeater_inactive)
|
||||||
val password @Bindable get() = binder?.service?.password ?: ""
|
val password @Bindable get() = binder?.service?.password ?: ""
|
||||||
|
|
||||||
fun onStatusChanged() {
|
fun onStatusChanged() {
|
||||||
@@ -151,12 +151,12 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
|||||||
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
|
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
|
||||||
R.id.wps -> if (binder?.active == true) {
|
R.id.wps -> if (binder?.active == true) {
|
||||||
val dialog = AlertDialog.Builder(context!!)
|
val dialog = AlertDialog.Builder(context!!)
|
||||||
.setTitle("Enter PIN")
|
.setTitle(R.string.repeater_wps_dialog_title)
|
||||||
.setView(R.layout.dialog_wps)
|
.setView(R.layout.dialog_wps)
|
||||||
.setPositiveButton(android.R.string.ok, { dialog, _ -> binder?.startWps((dialog as AppCompatDialog)
|
.setPositiveButton(android.R.string.ok, { dialog, _ -> binder?.startWps((dialog as AppCompatDialog)
|
||||||
.findViewById<EditText>(android.R.id.edit)!!.text.toString()) })
|
.findViewById<EditText>(android.R.id.edit)!!.text.toString()) })
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.setNeutralButton("Push Button", { _, _ -> binder?.startWps(null) })
|
.setNeutralButton(R.string.repeater_wps_dialog_pbc, { _, _ -> binder?.startWps(null) })
|
||||||
.create()
|
.create()
|
||||||
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
|
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
|
||||||
dialog.show()
|
dialog.show()
|
||||||
@@ -164,9 +164,10 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
|||||||
} else false
|
} else false
|
||||||
R.id.resetGroup -> {
|
R.id.resetGroup -> {
|
||||||
AlertDialog.Builder(context!!)
|
AlertDialog.Builder(context!!)
|
||||||
.setTitle("Reset credentials")
|
.setTitle(R.string.repeater_reset_credentials)
|
||||||
.setMessage("Android system will generate new network name and password next time repeater is activated. This is irreversible.")
|
.setMessage(getString(R.string.repeater_reset_credentials_dialog_message))
|
||||||
.setPositiveButton("Reset", { _, _ -> binder?.resetCredentials() })
|
.setPositiveButton(R.string.repeater_reset_credentials_dialog_reset,
|
||||||
|
{ _, _ -> binder?.resetCredentials() })
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import android.net.wifi.p2p.WifiP2pManager
|
|||||||
import android.os.Binder
|
import android.os.Binder
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
|
import android.support.annotation.StringRes
|
||||||
import android.support.v4.app.NotificationCompat
|
import android.support.v4.app.NotificationCompat
|
||||||
import android.support.v4.content.ContextCompat
|
import android.support.v4.content.ContextCompat
|
||||||
import android.support.v4.content.LocalBroadcastManager
|
import android.support.v4.content.LocalBroadcastManager
|
||||||
@@ -92,10 +93,10 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
}
|
}
|
||||||
p2pManager.startWps(channel, wps, object : WifiP2pManager.ActionListener {
|
p2pManager.startWps(channel, wps, object : WifiP2pManager.ActionListener {
|
||||||
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
||||||
if (pin == null) "Please use WPS push button within the next 2 minutes to connect your device."
|
if (pin == null) R.string.repeater_wps_success_pbc else R.string.repeater_wps_success_keypad,
|
||||||
else "PIN registered.", Toast.LENGTH_SHORT).show()
|
Toast.LENGTH_SHORT).show()
|
||||||
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
||||||
"Failed to start WPS (reason: ${formatReason(reason)})", Toast.LENGTH_SHORT).show()
|
formatReason(R.string.repeater_wps_failure, reason), Toast.LENGTH_SHORT).show()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,9 +109,9 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
if (netId == TEMPORARY_NET_ID) return
|
if (netId == TEMPORARY_NET_ID) return
|
||||||
p2pManager.deletePersistentGroup(channel, netId, object : WifiP2pManager.ActionListener {
|
p2pManager.deletePersistentGroup(channel, netId, object : WifiP2pManager.ActionListener {
|
||||||
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
||||||
"Credentials reset.", Toast.LENGTH_SHORT).show()
|
R.string.repeater_reset_credentials_success, Toast.LENGTH_SHORT).show()
|
||||||
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
override fun onFailure(reason: Int) = Toast.makeText(this@RepeaterService,
|
||||||
"Failed to reset credentials (reason: ${formatReason(reason)})", Toast.LENGTH_SHORT).show()
|
formatReason(R.string.repeater_reset_credentials_failure, reason), Toast.LENGTH_SHORT).show()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,7 +142,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private val onVpnUnavailable = Runnable { startFailure("VPN unavailable") }
|
private val onVpnUnavailable = Runnable { startFailure(getString(R.string.repeater_vpn_unavailable)) }
|
||||||
|
|
||||||
val ssid get() = if (status == Status.ACTIVE) group?.networkName else null
|
val ssid get() = if (status == Status.ACTIVE) group?.networkName else null
|
||||||
val password get() = if (status == Status.ACTIVE) group?.passphrase else null
|
val password get() = if (status == Status.ACTIVE) group?.passphrase else null
|
||||||
@@ -157,13 +158,13 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
LocalBroadcastManager.getInstance(this).sendBroadcast(Intent(ACTION_STATUS_CHANGED))
|
LocalBroadcastManager.getInstance(this).sendBroadcast(Intent(ACTION_STATUS_CHANGED))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun formatReason(reason: Int) = when (reason) {
|
private fun formatReason(@StringRes resId: Int, reason: Int) = getString(resId, when (reason) {
|
||||||
WifiP2pManager.ERROR -> "ERROR"
|
WifiP2pManager.ERROR -> getString(R.string.repeater_failure_reason_error)
|
||||||
WifiP2pManager.P2P_UNSUPPORTED -> "P2P_UNSUPPORTED"
|
WifiP2pManager.P2P_UNSUPPORTED -> getString(R.string.repeater_failure_reason_p2p_unsupported)
|
||||||
WifiP2pManager.BUSY -> "BUSY"
|
WifiP2pManager.BUSY -> getString(R.string.repeater_failure_reason_busy)
|
||||||
WifiP2pManager.NO_SERVICE_REQUESTS -> "NO_SERVICE_REQUESTS"
|
WifiP2pManager.NO_SERVICE_REQUESTS -> getString(R.string.repeater_failure_reason_no_service_requests)
|
||||||
else -> "unknown reason: $reason"
|
else -> getString(R.string.repeater_failure_reason_unknown, reason)
|
||||||
}
|
})
|
||||||
|
|
||||||
override fun onBind(intent: Intent) = binder
|
override fun onBind(intent: Intent) = binder
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
Status.STARTING -> {
|
Status.STARTING -> {
|
||||||
val matcher = patternNetworkInfo.matcher(loggerSu("dumpsys ${Context.WIFI_P2P_SERVICE}") ?: "")
|
val matcher = patternNetworkInfo.matcher(loggerSu("dumpsys ${Context.WIFI_P2P_SERVICE}") ?: "")
|
||||||
when {
|
when {
|
||||||
!matcher.find() -> startFailure("Root unavailable")
|
!matcher.find() -> startFailure(getString(R.string.repeater_root_unavailable))
|
||||||
matcher.group(2) == "true" -> {
|
matcher.group(2) == "true" -> {
|
||||||
unregisterReceiver()
|
unregisterReceiver()
|
||||||
registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
|
registerReceiver(receiver, intentFilter(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION,
|
||||||
@@ -213,7 +214,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
override fun onSuccess() = doStart()
|
override fun onSuccess() = doStart()
|
||||||
override fun onFailure(reason: Int) {
|
override fun onFailure(reason: Int) {
|
||||||
Toast.makeText(this@RepeaterService,
|
Toast.makeText(this@RepeaterService,
|
||||||
"Failed to remove old P2P group (${formatReason(reason)})",
|
formatReason(R.string.repeater_remove_old_group_failure, reason),
|
||||||
Toast.LENGTH_SHORT).show()
|
Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -221,7 +222,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else -> startFailure("Wi-Fi direct unavailable")
|
else -> startFailure(getString(R.string.repeater_p2p_unavailable))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ACTIVE -> {
|
Status.ACTIVE -> {
|
||||||
@@ -240,7 +241,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doStart() = p2pManager.createGroup(channel, object : WifiP2pManager.ActionListener {
|
private fun doStart() = p2pManager.createGroup(channel, object : WifiP2pManager.ActionListener {
|
||||||
override fun onFailure(reason: Int) = startFailure("Failed to create P2P group (${formatReason(reason)})")
|
override fun onFailure(reason: Int) = startFailure(formatReason(R.string.repeater_create_group_failure, reason))
|
||||||
override fun onSuccess() { } // wait for WIFI_P2P_CONNECTION_CHANGED_ACTION to fire
|
override fun onSuccess() { } // wait for WIFI_P2P_CONNECTION_CHANGED_ACTION to fire
|
||||||
})
|
})
|
||||||
private fun doStart(group: WifiP2pGroup) {
|
private fun doStart(group: WifiP2pGroup) {
|
||||||
@@ -260,7 +261,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
this.group = group
|
this.group = group
|
||||||
binder.data?.onGroupChanged()
|
binder.data?.onGroupChanged()
|
||||||
showNotification(group)
|
showNotification(group)
|
||||||
Log.d(TAG, "P2P connection changed: $info\n$net\n$group")
|
debugLog(TAG, "P2P connection changed: $info\n$net\n$group")
|
||||||
}
|
}
|
||||||
private fun onGroupCreated(info: WifiP2pInfo, group: WifiP2pGroup) {
|
private fun onGroupCreated(info: WifiP2pInfo, group: WifiP2pGroup) {
|
||||||
val owner = info.groupOwnerAddress
|
val owner = info.groupOwnerAddress
|
||||||
@@ -293,7 +294,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
val builder = NotificationCompat.Builder(this, CHANNEL)
|
val builder = NotificationCompat.Builder(this, CHANNEL)
|
||||||
.setWhen(0)
|
.setWhen(0)
|
||||||
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
|
.setColor(ContextCompat.getColor(this, R.color.colorPrimary))
|
||||||
.setContentTitle(group?.networkName ?: ssid ?: "Connecting...")
|
.setContentTitle(group?.networkName ?: ssid ?: getString(R.string.repeater_connecting))
|
||||||
.setSmallIcon(R.drawable.ic_device_wifi_tethering)
|
.setSmallIcon(R.drawable.ic_device_wifi_tethering)
|
||||||
.setContentIntent(PendingIntent.getActivity(this, 0,
|
.setContentIntent(PendingIntent.getActivity(this, 0,
|
||||||
Intent(this, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
Intent(this, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
@@ -307,8 +308,8 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
|||||||
override fun onSuccess() = clean()
|
override fun onSuccess() = clean()
|
||||||
override fun onFailure(reason: Int) {
|
override fun onFailure(reason: Int) {
|
||||||
if (reason == WifiP2pManager.BUSY) clean() else { // assuming it's already gone
|
if (reason == WifiP2pManager.BUSY) clean() else { // assuming it's already gone
|
||||||
Toast.makeText(this@RepeaterService, "Failed to remove P2P group (${formatReason(reason)})",
|
Toast.makeText(this@RepeaterService,
|
||||||
Toast.LENGTH_SHORT).show()
|
formatReason(R.string.repeater_remove_group_failure, reason), Toast.LENGTH_SHORT).show()
|
||||||
status = Status.ACTIVE
|
status = Status.ACTIVE
|
||||||
LocalBroadcastManager.getInstance(this@RepeaterService).sendBroadcast(Intent(ACTION_STATUS_CHANGED))
|
LocalBroadcastManager.getInstance(this@RepeaterService).sendBroadcast(Intent(ACTION_STATUS_CHANGED))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Network name"
|
android:text="@string/repeater_ssid"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_column="0"
|
android:layout_column="0"
|
||||||
android:layout_row="1"
|
android:layout_row="1"
|
||||||
android:text="Password"
|
android:text="@string/repeater_password"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingStart="16dp"
|
android:paddingStart="16dp"
|
||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:text="Connected devices"
|
android:text="@string/repeater_connected_devices"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
|
android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_repeater"
|
android:id="@+id/navigation_repeater"
|
||||||
android:icon="@drawable/ic_device_network_wifi"
|
android:icon="@drawable/ic_device_network_wifi"
|
||||||
android:title="Repeater"/>
|
android:title="@string/title_repeater"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_tethering"
|
android:id="@+id/navigation_tethering"
|
||||||
android:icon="@drawable/ic_device_wifi_tethering"
|
android:icon="@drawable/ic_device_wifi_tethering"
|
||||||
android:title="Tethering"/>
|
android:title="@string/title_tethering"/>
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/navigation_settings"
|
android:id="@+id/navigation_settings"
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/wps"
|
android:id="@+id/wps"
|
||||||
android:title="WPS"/>
|
android:title="@string/repeater_wps"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/resetGroup"
|
android:id="@+id/resetGroup"
|
||||||
android:title="Reset credentials"/>
|
android:title="@string/repeater_reset_credentials"/>
|
||||||
</menu>
|
</menu>
|
||||||
@@ -1,12 +1,62 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">VPN Hotspot</string>
|
<string name="app_name">VPN Hotspot</string>
|
||||||
|
<string name="title_repeater">Repeater</string>
|
||||||
|
<string name="title_tethering">Tethering</string>
|
||||||
<string name="title_settings">Settings</string>
|
<string name="title_settings">Settings</string>
|
||||||
|
|
||||||
|
<string name="repeater_ssid">Network name</string>
|
||||||
|
<string name="repeater_password">Password</string>
|
||||||
|
<string name="repeater_connected_devices">Connected devices</string>
|
||||||
|
<string name="repeater_wps">WPS</string>
|
||||||
|
<string name="repeater_wps_dialog_title">Enter PIN</string>
|
||||||
|
<string name="repeater_wps_dialog_pbc">Push Button</string>
|
||||||
|
<string name="repeater_wps_success_pbc">Please use WPS push button within the next 2 minutes to connect your
|
||||||
|
device.</string>
|
||||||
|
<string name="repeater_wps_success_keypad">PIN registered.</string>
|
||||||
|
<string name="repeater_wps_failure">Failed to start WPS (reason: %s)</string>
|
||||||
|
<string name="repeater_reset_credentials">Reset credentials</string>
|
||||||
|
<string name="repeater_reset_credentials_dialog_message">Android system will generate new network name and password
|
||||||
|
next time repeater is activated. This is irreversible.</string>
|
||||||
|
<string name="repeater_reset_credentials_dialog_reset">Reset</string>
|
||||||
|
<string name="repeater_reset_credentials_success">Credentials reset.</string>
|
||||||
|
<string name="repeater_reset_credentials_failure">Failed to reset credentials (reason: %s)</string>
|
||||||
|
|
||||||
|
<string name="repeater_inactive">Service inactive</string>
|
||||||
|
<string name="repeater_connecting">Connecting…</string>
|
||||||
|
<string name="repeater_vpn_unavailable">VPN unavailable, please enable any VPN</string>
|
||||||
|
<string name="repeater_root_unavailable">Root unavailable</string>
|
||||||
|
<string name="repeater_p2p_unavailable">Wi-Fi direct unavailable</string>
|
||||||
|
<string name="repeater_create_group_failure">Failed to create P2P group (reason: %s)</string>
|
||||||
|
<string name="repeater_remove_group_failure">Failed to remove P2P group (reason: %s)</string>
|
||||||
|
<string name="repeater_remove_old_group_failure">Failed to remove old P2P group (reason: %s)</string>
|
||||||
|
|
||||||
|
<string name="repeater_failure_reason_error">internal error</string>
|
||||||
|
<string name="repeater_failure_reason_p2p_unsupported">Wi-Fi direct unsupported</string>
|
||||||
|
<string name="repeater_failure_reason_busy">framework is busy</string>
|
||||||
|
<string name="repeater_failure_reason_no_service_requests">no service requests added</string>
|
||||||
|
<string name="repeater_failure_reason_unknown">unknown reason #%d</string>
|
||||||
|
|
||||||
|
<string name="tethering_no_interfaces"><![CDATA[To use this feature, turn on any <a href="#">system
|
||||||
|
tethering</a> first.]]></string>
|
||||||
|
|
||||||
|
<string name="settings_service">Service</string>
|
||||||
|
<string name="settings_service_dns">Downstream DNS server:port</string>
|
||||||
|
<string name="settings_service_clean">Clean routing rules</string>
|
||||||
|
<string name="settings_service_clean_summary">Only use after having shut down everything</string>
|
||||||
|
<string name="settings_misc">Misc</string>
|
||||||
|
<string name="settings_misc_logcat">Export logcat</string>
|
||||||
|
<string name="settings_misc_logcat_summary">Such useful very wow</string>
|
||||||
|
<string name="settings_misc_source">View on GitHub</string>
|
||||||
|
<string name="settings_misc_source_summary">Star, submit issues and contribute</string>
|
||||||
|
<string name="settings_misc_donate">Donate</string>
|
||||||
|
<string name="settings_misc_donate_summary">I love money</string>
|
||||||
|
|
||||||
|
<string name="notification_channel_repeater">Repeater Service</string>
|
||||||
<plurals name="notification_connected_devices">
|
<plurals name="notification_connected_devices">
|
||||||
<item quantity="one">1 connected device</item>
|
<item quantity="one">1 connected device</item>
|
||||||
<item quantity="other">%d connected devices</item>
|
<item quantity="other">%d connected devices</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
|
||||||
<string name="exception_interface_not_found">Fatal: Downstream interface not found</string>
|
<string name="exception_interface_not_found">Fatal: Downstream interface not found</string>
|
||||||
<string name="tethering_no_interfaces"><![CDATA[To use this feature, turn on any <a href="#">system
|
|
||||||
tethering</a> first.]]></string>
|
|
||||||
<string name="noisy_su_failure">Something went wrong, please check logcat.</string>
|
<string name="noisy_su_failure">Something went wrong, please check logcat.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="Service">
|
android:title="@string/settings_service">
|
||||||
<AutoSummaryEditTextPreference
|
<AutoSummaryEditTextPreference
|
||||||
android:key="service.dns"
|
android:key="service.dns"
|
||||||
android:title="Downstream DNS server:port"
|
android:title="@string/settings_service_dns"
|
||||||
android:summary="%s"
|
android:summary="%s"
|
||||||
android:defaultValue="8.8.8.8:53"/>
|
android:defaultValue="8.8.8.8:53"/>
|
||||||
<Preference
|
<Preference
|
||||||
android:key="service.clean"
|
android:key="service.clean"
|
||||||
android:title="Clean routing rules"
|
android:title="@string/settings_service_clean"
|
||||||
android:summary="Only use after having shut down everything"/>
|
android:summary="@string/settings_service_clean_summary"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:title="Misc">
|
android:title="@string/settings_misc">
|
||||||
<Preference
|
<Preference
|
||||||
android:key="misc.logcat"
|
android:key="misc.logcat"
|
||||||
android:title="Export logcat"
|
android:title="@string/settings_misc_logcat"
|
||||||
android:summary="Such useful very wow"/>
|
android:summary="@string/settings_misc_logcat_summary"/>
|
||||||
<Preference
|
<Preference
|
||||||
android:key="misc.source"
|
android:key="misc.source"
|
||||||
android:title="View on GitHub"
|
android:title="@string/settings_misc_source"
|
||||||
android:summary="Star, submit issues and contribute"/>
|
android:summary="@string/settings_misc_source_summary"/>
|
||||||
<Preference
|
<Preference
|
||||||
android:key="misc.donate"
|
android:key="misc.donate"
|
||||||
android:title="Donate"
|
android:title="@string/settings_misc_donate"
|
||||||
android:summary="I love money"/>
|
android:summary="@string/settings_misc_donate_summary"/>
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|||||||
Reference in New Issue
Block a user