Extract string resources
This commit is contained in:
@@ -5,6 +5,7 @@ import android.app.Application
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.content.SharedPreferences
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.preference.PreferenceManager
|
||||
|
||||
@@ -16,10 +17,19 @@ class App : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
app = this
|
||||
updateNotificationChannels()
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration?) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
updateNotificationChannels()
|
||||
}
|
||||
|
||||
private fun updateNotificationChannels() {
|
||||
if (Build.VERSION.SDK_INT >= 26) @TargetApi(26) {
|
||||
val nm = getSystemService(NotificationManager::class.java)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 ?: ""
|
||||
|
||||
fun onStatusChanged() {
|
||||
@@ -151,12 +151,12 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
||||
override fun onMenuItemClick(item: MenuItem) = when (item.itemId) {
|
||||
R.id.wps -> if (binder?.active == true) {
|
||||
val dialog = AlertDialog.Builder(context!!)
|
||||
.setTitle("Enter PIN")
|
||||
.setTitle(R.string.repeater_wps_dialog_title)
|
||||
.setView(R.layout.dialog_wps)
|
||||
.setPositiveButton(android.R.string.ok, { dialog, _ -> binder?.startWps((dialog as AppCompatDialog)
|
||||
.findViewById<EditText>(android.R.id.edit)!!.text.toString()) })
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setNeutralButton("Push Button", { _, _ -> binder?.startWps(null) })
|
||||
.setNeutralButton(R.string.repeater_wps_dialog_pbc, { _, _ -> binder?.startWps(null) })
|
||||
.create()
|
||||
dialog.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
|
||||
dialog.show()
|
||||
@@ -164,9 +164,10 @@ class RepeaterFragment : Fragment(), ServiceConnection, Toolbar.OnMenuItemClickL
|
||||
} else false
|
||||
R.id.resetGroup -> {
|
||||
AlertDialog.Builder(context!!)
|
||||
.setTitle("Reset credentials")
|
||||
.setMessage("Android system will generate new network name and password next time repeater is activated. This is irreversible.")
|
||||
.setPositiveButton("Reset", { _, _ -> binder?.resetCredentials() })
|
||||
.setTitle(R.string.repeater_reset_credentials)
|
||||
.setMessage(getString(R.string.repeater_reset_credentials_dialog_message))
|
||||
.setPositiveButton(R.string.repeater_reset_credentials_dialog_reset,
|
||||
{ _, _ -> binder?.resetCredentials() })
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
true
|
||||
|
||||
@@ -12,6 +12,7 @@ import android.net.wifi.p2p.WifiP2pManager
|
||||
import android.os.Binder
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.support.annotation.StringRes
|
||||
import android.support.v4.app.NotificationCompat
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.content.LocalBroadcastManager
|
||||
@@ -92,10 +93,10 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
||||
}
|
||||
p2pManager.startWps(channel, wps, object : WifiP2pManager.ActionListener {
|
||||
override fun onSuccess() = Toast.makeText(this@RepeaterService,
|
||||
if (pin == null) "Please use WPS push button within the next 2 minutes to connect your device."
|
||||
else "PIN registered.", Toast.LENGTH_SHORT).show()
|
||||
if (pin == null) R.string.repeater_wps_success_pbc else R.string.repeater_wps_success_keypad,
|
||||
Toast.LENGTH_SHORT).show()
|
||||
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
|
||||
p2pManager.deletePersistentGroup(channel, netId, object : WifiP2pManager.ActionListener {
|
||||
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,
|
||||
"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 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))
|
||||
}
|
||||
|
||||
private fun formatReason(reason: Int) = when (reason) {
|
||||
WifiP2pManager.ERROR -> "ERROR"
|
||||
WifiP2pManager.P2P_UNSUPPORTED -> "P2P_UNSUPPORTED"
|
||||
WifiP2pManager.BUSY -> "BUSY"
|
||||
WifiP2pManager.NO_SERVICE_REQUESTS -> "NO_SERVICE_REQUESTS"
|
||||
else -> "unknown reason: $reason"
|
||||
}
|
||||
private fun formatReason(@StringRes resId: Int, reason: Int) = getString(resId, when (reason) {
|
||||
WifiP2pManager.ERROR -> getString(R.string.repeater_failure_reason_error)
|
||||
WifiP2pManager.P2P_UNSUPPORTED -> getString(R.string.repeater_failure_reason_p2p_unsupported)
|
||||
WifiP2pManager.BUSY -> getString(R.string.repeater_failure_reason_busy)
|
||||
WifiP2pManager.NO_SERVICE_REQUESTS -> getString(R.string.repeater_failure_reason_no_service_requests)
|
||||
else -> getString(R.string.repeater_failure_reason_unknown, reason)
|
||||
})
|
||||
|
||||
override fun onBind(intent: Intent) = binder
|
||||
|
||||
@@ -196,7 +197,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
||||
Status.STARTING -> {
|
||||
val matcher = patternNetworkInfo.matcher(loggerSu("dumpsys ${Context.WIFI_P2P_SERVICE}") ?: "")
|
||||
when {
|
||||
!matcher.find() -> startFailure("Root unavailable")
|
||||
!matcher.find() -> startFailure(getString(R.string.repeater_root_unavailable))
|
||||
matcher.group(2) == "true" -> {
|
||||
unregisterReceiver()
|
||||
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 onFailure(reason: Int) {
|
||||
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()
|
||||
}
|
||||
})
|
||||
@@ -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 -> {
|
||||
@@ -240,7 +241,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
||||
}
|
||||
|
||||
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
|
||||
})
|
||||
private fun doStart(group: WifiP2pGroup) {
|
||||
@@ -260,7 +261,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
||||
this.group = group
|
||||
binder.data?.onGroupChanged()
|
||||
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) {
|
||||
val owner = info.groupOwnerAddress
|
||||
@@ -293,7 +294,7 @@ class RepeaterService : Service(), WifiP2pManager.ChannelListener, VpnListener.C
|
||||
val builder = NotificationCompat.Builder(this, CHANNEL)
|
||||
.setWhen(0)
|
||||
.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)
|
||||
.setContentIntent(PendingIntent.getActivity(this, 0,
|
||||
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 onFailure(reason: Int) {
|
||||
if (reason == WifiP2pManager.BUSY) clean() else { // assuming it's already gone
|
||||
Toast.makeText(this@RepeaterService, "Failed to remove P2P group (${formatReason(reason)})",
|
||||
Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this@RepeaterService,
|
||||
formatReason(R.string.repeater_remove_group_failure, reason), Toast.LENGTH_SHORT).show()
|
||||
status = Status.ACTIVE
|
||||
LocalBroadcastManager.getInstance(this@RepeaterService).sendBroadcast(Intent(ACTION_STATUS_CHANGED))
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Network name"
|
||||
android:text="@string/repeater_ssid"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||
|
||||
<Space
|
||||
@@ -65,7 +65,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_column="0"
|
||||
android:layout_row="1"
|
||||
android:text="Password"
|
||||
android:text="@string/repeater_password"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||
|
||||
<TextView
|
||||
@@ -83,7 +83,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:text="Connected devices"
|
||||
android:text="@string/repeater_connected_devices"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"/>
|
||||
|
||||
<View
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
<item
|
||||
android:id="@+id/navigation_repeater"
|
||||
android:icon="@drawable/ic_device_network_wifi"
|
||||
android:title="Repeater"/>
|
||||
android:title="@string/title_repeater"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_tethering"
|
||||
android:icon="@drawable/ic_device_wifi_tethering"
|
||||
android:title="Tethering"/>
|
||||
android:title="@string/title_tethering"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/navigation_settings"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<item
|
||||
android:id="@+id/wps"
|
||||
android:title="WPS"/>
|
||||
android:title="@string/repeater_wps"/>
|
||||
<item
|
||||
android:id="@+id/resetGroup"
|
||||
android:title="Reset credentials"/>
|
||||
android:title="@string/repeater_reset_credentials"/>
|
||||
</menu>
|
||||
@@ -1,12 +1,62 @@
|
||||
<resources>
|
||||
<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="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">
|
||||
<item quantity="one">1 connected device</item>
|
||||
<item quantity="other">%d connected devices</item>
|
||||
</plurals>
|
||||
|
||||
<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>
|
||||
</resources>
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory
|
||||
android:title="Service">
|
||||
android:title="@string/settings_service">
|
||||
<AutoSummaryEditTextPreference
|
||||
android:key="service.dns"
|
||||
android:title="Downstream DNS server:port"
|
||||
android:title="@string/settings_service_dns"
|
||||
android:summary="%s"
|
||||
android:defaultValue="8.8.8.8:53"/>
|
||||
<Preference
|
||||
android:key="service.clean"
|
||||
android:title="Clean routing rules"
|
||||
android:summary="Only use after having shut down everything"/>
|
||||
android:title="@string/settings_service_clean"
|
||||
android:summary="@string/settings_service_clean_summary"/>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:title="Misc">
|
||||
android:title="@string/settings_misc">
|
||||
<Preference
|
||||
android:key="misc.logcat"
|
||||
android:title="Export logcat"
|
||||
android:summary="Such useful very wow"/>
|
||||
android:title="@string/settings_misc_logcat"
|
||||
android:summary="@string/settings_misc_logcat_summary"/>
|
||||
<Preference
|
||||
android:key="misc.source"
|
||||
android:title="View on GitHub"
|
||||
android:summary="Star, submit issues and contribute"/>
|
||||
android:title="@string/settings_misc_source"
|
||||
android:summary="@string/settings_misc_source_summary"/>
|
||||
<Preference
|
||||
android:key="misc.donate"
|
||||
android:title="Donate"
|
||||
android:summary="I love money"/>
|
||||
android:title="@string/settings_misc_donate"
|
||||
android:summary="@string/settings_misc_donate_summary"/>
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
||||
Reference in New Issue
Block a user