diff --git a/src/main/res/values-zh/strings.xml b/src/main/res/values-zh/strings.xml
index 08aba74f..e405acba 100755
--- a/src/main/res/values-zh/strings.xml
+++ b/src/main/res/values-zh/strings.xml
@@ -11,9 +11,9 @@
服务器
远程服务器的地址
远程端口
- 远程服务器的端口号
+ %d(远程服务器的端口号)
本地端口
- 本地客户端的端口号
+ %d(本地客户端的端口号)
密码
远程服务器的密码
加密方法
@@ -43,8 +43,6 @@
正在关闭……
后台服务启动失败:%s
关闭
- 本地端口号应大于 1024
- 端口号不能为空
代理服务器地址不能为空
连接
正在初始化……
diff --git a/src/main/res/values/attrs.xml b/src/main/res/values/attrs.xml
index ca0adbc5..85c250f1 100644
--- a/src/main/res/values/attrs.xml
+++ b/src/main/res/values/attrs.xml
@@ -7,4 +7,8 @@
-
\ No newline at end of file
+
+
+
+
+
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index c5d37579..e4c16cdc 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -19,9 +19,9 @@
Server
Hostname or IP of the remote server
Remote Port
- Port number of the remote server
+ %d (port number of the remote server)
Local Port
- Port number of the local server
+ %d (port number of the local server)
Password
Password of the remote server
Encrypt Method
@@ -64,8 +64,6 @@
Close
- The local port number should be greater than 1024
- Port should not be empty
Proxy should not be empty
Connect
Initializing…
diff --git a/src/main/res/xml/pref_all.xml b/src/main/res/xml/pref_all.xml
index c08688de..f2a6af85 100644
--- a/src/main/res/xml/pref_all.xml
+++ b/src/main/res/xml/pref_all.xml
@@ -26,17 +26,19 @@
android:key="proxy"
android:summary="@string/proxy_summary"
android:title="@string/proxy"/>
-
-
- Snackbar.make(getWindow.getDecorView.findViewById(android.R.id.content), R.string.port_alert,
- Snackbar.LENGTH_LONG).show
- return false
- }
- true
- }
-
/** Called when connect button is clicked. */
def serviceStart() {
bgService.start(ConfigUtils.load(ShadowsocksApplication.settings))
diff --git a/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala b/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
index 08ea17d3..c9e9d099 100644
--- a/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
+++ b/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala
@@ -128,8 +128,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
edit.putString(Key.proxy, profile.host)
edit.putString(Key.sitekey, profile.password)
edit.putString(Key.encMethod, profile.method)
- edit.putString(Key.remotePort, profile.remotePort.toString)
- edit.putString(Key.localPort, profile.localPort.toString)
+ edit.putInt(Key.remotePort, profile.remotePort)
+ edit.putInt(Key.localPort, profile.localPort)
edit.putString(Key.proxied, profile.individual)
edit.putInt(Key.profileId, profile.id)
edit.putString(Key.route, profile.route)
@@ -155,18 +155,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
profile.password = settings.getString(Key.sitekey, "default")
profile.method = settings.getString(Key.encMethod, "table")
profile.route = settings.getString(Key.route, "all")
- profile.remotePort = try {
- Integer.valueOf(settings.getString(Key.remotePort, "1984"))
- } catch {
- case ex: NumberFormatException =>
- 1984
- }
- profile.localPort = try {
- Integer.valueOf(settings.getString(Key.localPort, "1984"))
- } catch {
- case ex: NumberFormatException =>
- 1984
- }
+ profile.remotePort = settings.getInt(Key.remotePort, 1984)
+ profile.localPort = settings.getInt(Key.localPort, 1984)
profile.individual = settings.getString(Key.proxied, "")
profile
diff --git a/src/main/scala/com/github/shadowsocks/preferences/DropDownPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/DropDownPreference.scala
index 142e384a..c42891f3 100644
--- a/src/main/scala/com/github/shadowsocks/preferences/DropDownPreference.scala
+++ b/src/main/scala/com/github/shadowsocks/preferences/DropDownPreference.scala
@@ -14,7 +14,6 @@ import android.widget.{AdapterView, ArrayAdapter}
import com.github.shadowsocks.R
/**
- * Based on: https://github.com/Mygod/mygod-lib-android/blob/683c41cb86d10e99ab0f457d41a218c6915fccc8/lib/src/main/scala/tk/mygod/preference/DropDownPreference.scala
* @author Mygod
*/
final class DropDownPreference(private val mContext: Context, attrs: AttributeSet = null)
diff --git a/src/main/scala/com/github/shadowsocks/preferences/NumberPickerPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/NumberPickerPreference.scala
new file mode 100644
index 00000000..9fa2d7aa
--- /dev/null
+++ b/src/main/scala/com/github/shadowsocks/preferences/NumberPickerPreference.scala
@@ -0,0 +1,56 @@
+package com.github.shadowsocks.preferences
+
+import android.content.Context
+import android.content.res.TypedArray
+import android.preference.DialogPreference
+import android.util.AttributeSet
+import android.view.ViewGroup
+import android.widget.NumberPicker
+import com.github.shadowsocks.R
+
+/**
+ * @author Mygod
+ */
+final class NumberPickerPreference(context: Context, attrs: AttributeSet = null)
+ extends DialogPreference(context, attrs) with SummaryPreference {
+ private val picker = new NumberPicker(context)
+ private var value: Int = _
+
+ {
+ val a: TypedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberPickerPreference)
+ setMin(a.getInt(R.styleable.NumberPickerPreference_min, 0))
+ setMax(a.getInt(R.styleable.NumberPickerPreference_max, Int.MaxValue - 1))
+ a.recycle
+ }
+ initSummary(context, attrs)
+
+ def getValue = value
+ def getMin = if (picker == null) 0 else picker.getMinValue
+ def getMax = picker.getMaxValue
+ def setValue(i: Int) {
+ if (i == getValue || !callChangeListener(i)) return
+ picker.setValue(i)
+ value = picker.getValue
+ persistInt(value)
+ notifyChanged
+ }
+ def setMin(value: Int) = picker.setMinValue(value)
+ def setMax(value: Int) = picker.setMaxValue(value)
+
+ override protected def onCreateDialogView = {
+ val parent = picker.getParent.asInstanceOf[ViewGroup]
+ if (parent != null) parent.removeView(picker)
+ picker
+ }
+ override protected def onDialogClosed(positiveResult: Boolean) {
+ picker.clearFocus // commit changes
+ super.onDialogClosed(positiveResult) // forward compatibility
+ if (positiveResult) setValue(picker.getValue) else picker.setValue(value)
+ }
+ override protected def onGetDefaultValue(a: TypedArray, index: Int) = a.getInt(index, getMin).asInstanceOf[AnyRef]
+ override protected def onSetInitialValue(restorePersistedValue: Boolean, defaultValue: Any) {
+ val default = defaultValue.asInstanceOf[Int]
+ setValue(if (restorePersistedValue) getPersistedInt(default) else default)
+ }
+ protected def getSummaryValue: AnyRef = getValue.asInstanceOf[AnyRef]
+}
diff --git a/src/main/scala/com/github/shadowsocks/preferences/SummaryPreference.scala b/src/main/scala/com/github/shadowsocks/preferences/SummaryPreference.scala
index 56523494..15e59970 100644
--- a/src/main/scala/com/github/shadowsocks/preferences/SummaryPreference.scala
+++ b/src/main/scala/com/github/shadowsocks/preferences/SummaryPreference.scala
@@ -7,7 +7,6 @@ import com.github.shadowsocks.R
/**
* Make your preference support %s in summary. Override getSummaryValue to customize what to put in.
- * Based on: https://github.com/Mygod/mygod-lib-android/blob/eb20c57a0da70bb5dbc27104002f20fb1eb31d76/lib/src/main/scala/tk/mygod/preference/SummaryPreference.scala
* @author Mygod
*/
trait SummaryPreference extends Preference {
diff --git a/src/main/scala/com/github/shadowsocks/utils/ConfigUtils.scala b/src/main/scala/com/github/shadowsocks/utils/ConfigUtils.scala
index 774c355b..cf2bcf65 100644
--- a/src/main/scala/com/github/shadowsocks/utils/ConfigUtils.scala
+++ b/src/main/scala/com/github/shadowsocks/utils/ConfigUtils.scala
@@ -261,18 +261,8 @@ object ConfigUtils {
val encMethod = settings.getString(Key.encMethod, "table")
val route = settings.getString(Key.route, "all")
- val remotePort: Int = try {
- settings.getString(Key.remotePort, "1984").toInt
- } catch {
- case ex: NumberFormatException =>
- 1984
- }
- val localPort: Int = try {
- settings.getString(Key.localPort, "1984").toInt
- } catch {
- case ex: NumberFormatException =>
- 1984
- }
+ val remotePort = settings.getInt(Key.remotePort, 1984)
+ val localPort = settings.getInt(Key.localPort, 1984)
val proxiedAppString = settings.getString(Key.proxied, "")
new Config(isGlobalProxy, isGFWList, isBypassApps, isTrafficStat, isUdpDns, isAuth, isIpv6, profileName, proxy,