Skip to content

Commit aca8550

Browse files
authored
更新 ConnectionsFragment.kt
1 parent 16888f6 commit aca8550

1 file changed

Lines changed: 43 additions & 28 deletions

File tree

app/src/main/java/com/netmonitor/app/ui/connections/ConnectionsFragment.kt

Lines changed: 43 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ class ConnectionsFragment : Fragment() {
5151
onItemClick = { conn -> showConnectionDetail(conn) },
5252
onIpLookup = { ip -> lookupIp(ip) }
5353
)
54-
5554
binding.rvConnections.layoutManager = LinearLayoutManager(requireContext())
5655
binding.rvConnections.adapter = adapter
5756

@@ -62,6 +61,8 @@ class ConnectionsFragment : Fragment() {
6261
binding.chipListen.setOnClickListener { setFilter("listen") }
6362
binding.chipCloseWait.setOnClickListener { setFilter("close_wait") }
6463
binding.chipTimeWait.setOnClickListener { setFilter("time_wait") }
64+
binding.chipIpExposed.setOnClickListener { setFilter("ip_exposed") }
65+
binding.chipExposedListener.setOnClickListener { setFilter("exposed_listener") }
6566

6667
binding.etSearch.addTextChangedListener(object : TextWatcher {
6768
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
@@ -93,38 +94,57 @@ class ConnectionsFragment : Fragment() {
9394
"listen" -> filtered.filter { it.displayState == "LISTEN" }
9495
"close_wait" -> filtered.filter { it.displayState == "CLOSE_WAIT" }
9596
"time_wait" -> filtered.filter { it.displayState == "TIME_WAIT" }
97+
"ip_exposed" -> filtered.filter { it.isRealIpExposed }
98+
"exposed_listener" -> filtered.filter { it.isExposedListener }
9699
else -> filtered
97100
}
98101

99102
if (searchText.isNotBlank()) {
100103
val query = searchText.lowercase()
101104
filtered = filtered.filter { conn ->
102105
conn.localIp.lowercase().contains(query) ||
103-
conn.remoteIp.lowercase().contains(query) ||
104-
conn.localPort.toString().contains(query) ||
105-
conn.remotePort.toString().contains(query) ||
106-
conn.appName.lowercase().contains(query) ||
107-
conn.protocol.lowercase().contains(query)
106+
conn.remoteIp.lowercase().contains(query) ||
107+
conn.localPort.toString().contains(query) ||
108+
conn.remotePort.toString().contains(query) ||
109+
conn.appName.lowercase().contains(query) ||
110+
conn.protocol.lowercase().contains(query)
108111
}
109112
}
110113

111114
adapter.submitList(filtered)
112-
binding.tvConnectionCount.text = "" + filtered.size + " 个连接"
115+
binding.tvConnectionCount.text = when (currentFilter) {
116+
"ip_exposed" -> "\u26a0 \u771f\u5b9eIP\u66b4\u9732: ${filtered.size} \u4e2a\u8fde\u63a5"
117+
"exposed_listener" -> "\u26a0 \u7aef\u53e3\u66b4\u9732: ${filtered.size} \u4e2a\u76d1\u542c"
118+
else -> "\u5171 ${filtered.size} \u4e2a\u8fde\u63a5"
119+
}
113120
}
114121

115122
private fun showConnectionDetail(conn: ConnectionInfo) {
116123
val ctx = context ?: return
117124

118125
val sb = StringBuilder()
119-
sb.appendLine("协议: " + conn.protocol)
120-
sb.appendLine("状态: " + conn.displayState)
126+
sb.appendLine("\u534f\u8bae: " + conn.protocol)
127+
sb.appendLine("\u72b6\u6001: " + conn.displayState)
121128
sb.appendLine("")
122-
sb.appendLine("本地地址: " + conn.localIp + ":" + conn.localPort)
123-
sb.appendLine("远程地址: " + conn.remoteIp + ":" + conn.remotePort)
129+
sb.appendLine("\u672c\u5730\u5730\u5740: " + conn.localIp + ":" + conn.localPort)
130+
sb.appendLine("\u8fdc\u7a0b\u5730\u5740: " + conn.remoteIp + ":" + conn.remotePort)
124131
sb.appendLine("")
125-
sb.appendLine("应用: " + conn.appName)
132+
sb.appendLine("\u5e94\u7528: " + conn.appName)
126133
sb.appendLine("UID: " + conn.uid)
127134

135+
if (conn.isRealIpExposed) {
136+
sb.appendLine("")
137+
sb.appendLine("\u26a0 \u8b66\u544a: \u8be5\u8fde\u63a5\u66b4\u9732\u4e86\u60a8\u7684\u771f\u5b9eIP\u5730\u5740\uff01")
138+
sb.appendLine(" \u672c\u5730\u5730\u5740 ${conn.localIp} \u662f\u516c\u7f51IP\uff0c")
139+
sb.appendLine(" \u8bf4\u660e\u6b64\u8fde\u63a5\u672a\u901a\u8fc7VPN/\u4ee3\u7406\uff0c\u76f4\u63a5\u66b4\u9732\u771f\u5b9e\u8eab\u4efd\u3002")
140+
}
141+
if (conn.isExposedListener) {
142+
sb.appendLine("")
143+
sb.appendLine("\u26a0 \u8b66\u544a: \u8be5\u7aef\u53e3\u76d1\u542c\u5728\u6240\u6709\u7f51\u5361\uff01")
144+
sb.appendLine(" \u540c\u4e00\u5c40\u57df\u7f51\u5185\u5176\u4ed6\u8bbe\u5907\u53ef\u4ee5\u8fde\u63a5\u6b64\u7aef\u53e3\u3002")
145+
sb.appendLine(" \u5728\u516c\u5171WiFi\u4e0b\u5b58\u5728\u5b89\u5168\u98ce\u9669\u3002")
146+
}
147+
128148
val scrollView = ScrollView(ctx)
129149
val textView = TextView(ctx).apply {
130150
text = sb.toString()
@@ -135,38 +155,34 @@ class ConnectionsFragment : Fragment() {
135155
scrollView.addView(textView)
136156

137157
AlertDialog.Builder(ctx)
138-
.setTitle("连接详情")
158+
.setTitle("\u8fde\u63a5\u8be6\u60c5")
139159
.setView(scrollView)
140-
.setPositiveButton("确定", null)
141-
.setNeutralButton("查询远程IP") { _, _ ->
160+
.setPositiveButton("\u786e\u5b9a", null)
161+
.setNeutralButton("\u67e5\u8be2\u8fdc\u7a0bIP") { _, _ ->
142162
lookupIp(conn.remoteIp)
143163
}
144-
.setNegativeButton("复制") { _, _ ->
164+
.setNegativeButton("\u590d\u5236") { _, _ ->
145165
val clipboard = ctx.getSystemService(
146166
android.content.Context.CLIPBOARD_SERVICE
147167
) as android.content.ClipboardManager
148168
val clip = android.content.ClipData.newPlainText("connection", sb.toString())
149169
clipboard.setPrimaryClip(clip)
150-
Toast.makeText(ctx, "已复制", Toast.LENGTH_SHORT).show()
170+
Toast.makeText(ctx, "\u5df2\u590d\u5236", Toast.LENGTH_SHORT).show()
151171
}
152172
.show()
153173
}
154174

155175
private fun lookupIp(ip: String) {
156176
val ctx = context ?: return
157-
158177
if (IpLocator.isLocalIp(ip)) {
159-
Toast.makeText(ctx, "这是本机/局域网地址,无需查询", Toast.LENGTH_SHORT).show()
178+
Toast.makeText(ctx, "\u8fd9\u662f\u672c\u673a/\u5c40\u57df\u7f51\u5730\u5740\uff0c\u65e0\u9700\u67e5\u8be2", Toast.LENGTH_SHORT).show()
160179
return
161180
}
162-
163-
Toast.makeText(ctx, "正在查询 " + ip + " ...", Toast.LENGTH_SHORT).show()
164-
181+
Toast.makeText(ctx, "\u6b63\u5728\u67e5\u8be2 $ip ...", Toast.LENGTH_SHORT).show()
165182
viewLifecycleOwner.lifecycleScope.launch {
166183
val info = withContext(Dispatchers.IO) {
167184
IpLocator.lookup(ip)
168185
}
169-
170186
if (_binding != null) {
171187
val scrollView = ScrollView(ctx)
172188
val textView = TextView(ctx).apply {
@@ -176,18 +192,17 @@ class ConnectionsFragment : Fragment() {
176192
setTextIsSelectable(true)
177193
}
178194
scrollView.addView(textView)
179-
180195
AlertDialog.Builder(ctx)
181-
.setTitle("IP 归属地查询")
196+
.setTitle("IP \u5f52\u5c5e\u5730\u67e5\u8be2")
182197
.setView(scrollView)
183-
.setPositiveButton("确定", null)
184-
.setNeutralButton("复制") { _, _ ->
198+
.setPositiveButton("\u786e\u5b9a", null)
199+
.setNeutralButton("\u590d\u5236") { _, _ ->
185200
val clipboard = ctx.getSystemService(
186201
android.content.Context.CLIPBOARD_SERVICE
187202
) as android.content.ClipboardManager
188203
val clip = android.content.ClipData.newPlainText("ip_info", info.format())
189204
clipboard.setPrimaryClip(clip)
190-
Toast.makeText(ctx, "已复制", Toast.LENGTH_SHORT).show()
205+
Toast.makeText(ctx, "\u5df2\u590d\u5236", Toast.LENGTH_SHORT).show()
191206
}
192207
.show()
193208
}

0 commit comments

Comments
 (0)