Bläddra i källkod

Add speedInterval settings & Update README

世界 4 år sedan
förälder
incheckning
735d45a4fd

+ 1 - 0
.idea/dictionaries/sekai.xml

@@ -5,6 +5,7 @@
       <w>downlink</w>
       <w>grpc</w>
       <w>gson</w>
+      <w>libev</w>
       <w>nekohasekai</w>
       <w>obfs</w>
       <w>quic</w>

+ 37 - 1
README.md

@@ -1,17 +1,53 @@
 # SagerNet for Android
 
-[![API](https://img.shields.io/badge/API-23%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=23)
+[![API](https://img.shields.io/badge/API-21%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=21)
 [![Releases](https://img.shields.io/github/downloads/nekohasekai/SagerNet/total.svg)](https://github.com/nekohasekai/SagerNet/releases)
 [![Language: Kotlin](https://img.shields.io/github/languages/top/nekohasekai/SagerNet.svg)](https://github.com/nekohasekai/SagerNet/search?l=kotlin)
 [![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0-orange.svg)](https://www.gnu.org/licenses/gpl-3.0)
 
 The universal proxy toolchain for Android, written in Kotlin.
 
+## PROTOCOLS
+
+The application is designed to be used whenever possible.
+ 
+### Protocols
+
+* SOCKS
+* Shadowsocks
+* ShadowsocksR
+* VMess
+* VLESS
+* Trojan
+* SSH (not yet)
+* OpenVPN (not yet)
+* Chain (not yet)
+
+### Subscription protocols
+
+* Universal base64 format
+* SIP008
+* Clash
+
+## FEATURES
+
+* Full basic features  
+* Option to change the notification update interval  
+* A china apps scanner (based on dex classpath scanning, so it's may slower)
+
+## TIPS
+
+* Click on the title to scroll to the first proxy or the selected proxy  
+* Proxy list can be dragged by holding the progress bar  
+* The china apps scanner will only scan system apps if "Show system apps" is checked  
+* V2Ray browser forwarding is not yet available, only for developers to debug
+
 ## OPEN SOURCE LICENSES
 
 <ul>
     <li><a href="https://github.com/shadowsocks/shadowsocks-android">shadowsocks-android</a>: GPL 3.0</li>
     <li><a href="https://github.com/nekohasekai/AndroidLibV2rayLite">AndroidLibV2rayLite</a>: LGPL 3.0</li>
+    <li><a href="https://github.com/shadowsocksRb/shadowsocksr-libev/blob/master/LICENSE">shadowsocksr-libev</a>: GPL 3.0</li>
 </ul>
 
 ### LICENSE

+ 2 - 2
app/build.gradle

@@ -137,7 +137,7 @@ dependencies {
     implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3"
     implementation 'androidx.core:core-ktx:1.6.0-alpha02'
     implementation 'androidx.activity:activity-ktx:1.2.2'
-    implementation "androidx.fragment:fragment-ktx:1.3.2"
+    implementation "androidx.fragment:fragment-ktx:1.3.3"
 
     implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
     implementation "androidx.navigation:navigation-fragment-ktx:2.3.5"
@@ -159,7 +159,7 @@ dependencies {
         exclude group: "androidx.recyclerview"
         exclude group: "androidx.appcompat"
     }
-    implementation ("org.smali:dexlib2:2.5.2") {
+    implementation("org.smali:dexlib2:2.5.2") {
         exclude group: 'com.google.guava', module: 'guava'
     }
     implementation "com.google.guava:guava:30.1.1-android"

+ 1 - 0
app/src/main/java/io/nekohasekai/sagernet/Constants.kt

@@ -53,6 +53,7 @@ object Key {
     const val REQUIRE_HTTP = "requireHttp"
     const val HTTP_PORT = "httpPort"
     const val ALLOW_ACCESS = "allowAccess"
+    const val SPEED_INTERVAL = "speedInterval"
     const val WS_MAX_EARLY_DATA = "wsMaxEarlyData"
     const val WS_BROWSER_FORWARDING = "wsBrowserForwarding"
 

+ 22 - 18
app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt

@@ -122,29 +122,33 @@ class SagerNet : Application() {
         super.attachBaseContext(base)
         application = this
 
-        initAcra {
-            alsoReportToAndroidFramework = true
-
-            applicationLogFileDir = Directory.EXTERNAL_FILES
-            applicationLogFile = "application_log.txt"
-            buildConfigClass = BuildConfig::class.java
-            reportFormat = StringFormat.JSON
-            sendReportsInDevMode = false
-            stopServicesOnCrash = true
-
-            mailSender {
-                mailTo = "[email protected]"
-                reportAsFile = true
-                reportFileName = "crash_report.json"
-            }
+        if (!BuildConfig.DEBUG) {
+
+            initAcra {
+                alsoReportToAndroidFramework = true
+
+                applicationLogFileDir = Directory.EXTERNAL_FILES
+                applicationLogFile = "application_log.txt"
+                buildConfigClass = BuildConfig::class.java
+                reportFormat = StringFormat.JSON
+                stopServicesOnCrash = true
 
+                mailSender {
+                    mailTo = "[email protected]"
+                    reportAsFile = true
+                    reportFileName = "crash_report.json"
+                }
+
+
+                notification {
+                    channelName = "Crash report"
+                    channelDescription = ":("
+                }
 
-            notification {
-                channelName = "Crash report"
-                channelDescription = ":("
             }
 
         }
+
     }
 
     override fun onCreate() {

+ 4 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/BaseService.kt

@@ -126,16 +126,17 @@ class BaseService {
             while (true) {
                 val delayMs = bandwidthListeners.values.minOrNull()
                 delay(delayMs ?: return)
+                if (delayMs == 0L) return
                 val queryTime = System.currentTimeMillis()
-                val sinceLastQueryInSeconds = (queryTime - lastQueryTime) / 1000L
+                val sinceLastQueryInSeconds = (queryTime - lastQueryTime).toDouble() / 1000L
                 val proxy = data?.proxy ?: continue
                 lastQueryTime = queryTime
                 val up = proxy.uplink
                 val down = proxy.downlink
                 if (up + down == 0L) continue
                 val stats = TrafficStats(
-                    up / sinceLastQueryInSeconds,
-                    down / sinceLastQueryInSeconds,
+                    (up / sinceLastQueryInSeconds).toLong(),
+                    (down / sinceLastQueryInSeconds).toLong(),
                     proxy.uplinkTotal,
                     proxy.downlinkTotal
                 )

+ 5 - 3
app/src/main/java/io/nekohasekai/sagernet/bg/ServiceNotification.kt

@@ -33,11 +33,12 @@ import android.text.format.Formatter
 import androidx.core.app.NotificationCompat
 import androidx.core.content.ContextCompat
 import androidx.core.content.getSystemService
-import io.nekohasekai.sagernet.aidl.IShadowsocksServiceCallback
-import io.nekohasekai.sagernet.aidl.TrafficStats
 import io.nekohasekai.sagernet.Action
 import io.nekohasekai.sagernet.R
 import io.nekohasekai.sagernet.SagerNet
+import io.nekohasekai.sagernet.aidl.IShadowsocksServiceCallback
+import io.nekohasekai.sagernet.aidl.TrafficStats
+import io.nekohasekai.sagernet.database.DataStore
 
 /**
  * User can customize visibility of notification since Android 8.
@@ -114,7 +115,8 @@ class ServiceNotification(
     private fun updateCallback(screenOn: Boolean) {
         if (screenOn) {
             service.data.binder.registerCallback(callback)
-            service.data.binder.startListeningForBandwidth(callback, 3000)
+            service.data.binder.startListeningForBandwidth(callback,
+                DataStore.speedInterval.toLong())
             callbackRegistered = true
         } else if (callbackRegistered) {    // unregister callback to save battery
             service.data.binder.unregisterCallback(callback)

+ 1 - 0
app/src/main/java/io/nekohasekai/sagernet/database/DataStore.kt

@@ -69,6 +69,7 @@ object DataStore : OnPreferenceDataStoreChangeListener {
     var serviceMode by configurationStore.string(Key.SERVICE_MODE) { Key.MODE_VPN }
     var routeMode by configurationStore.string(Key.ROUTE_MODE) { RouteMode.ALL }
     var allowAccess by configurationStore.boolean(Key.ALLOW_ACCESS)
+    var speedInterval by configurationStore.stringToInt(Key.SPEED_INTERVAL)
 
     var enableLocalDNS by configurationStore.boolean(Key.ENABLE_LOCAL_DNS) { true }
     var remoteDNS by configurationStore.string(Key.REMOTE_DNS) { "1.1.1.1" }

+ 0 - 1
app/src/main/java/io/nekohasekai/sagernet/ui/ConfigurationFragment.kt

@@ -182,7 +182,6 @@ class ConfigurationFragment : ToolbarFragment(R.layout.layout_group_list),
             }
             R.id.action_new_socks -> {
                 startActivity(Intent(requireActivity(), SocksSettingsActivity::class.java))
-
             }
             R.id.action_new_ss -> {
                 startActivity(Intent(requireActivity(), ShadowsocksSettingsActivity::class.java))

+ 2 - 2
app/src/main/java/io/nekohasekai/sagernet/ui/MainActivity.kt

@@ -128,7 +128,7 @@ class MainActivity : AppCompatActivity(), SagerConnection.Callback,
         changeState(state, msg, true)
     }
 
-    private val connection = SagerConnection(true)
+    val connection = SagerConnection(true)
     override fun onServiceConnected(service: IShadowsocksService) = changeState(try {
         BaseService.State.values()[service.state]
     } catch (_: RemoteException) {
@@ -171,7 +171,7 @@ class MainActivity : AppCompatActivity(), SagerConnection.Callback,
 
     override fun onStart() {
         super.onStart()
-        connection.bandwidthTimeout = 1000
+        connection.bandwidthTimeout = DataStore.speedInterval.toLong()
     }
 
     override fun onStop() {

+ 8 - 0
app/src/main/java/io/nekohasekai/sagernet/ui/SettingsPreferenceFragment.kt

@@ -52,6 +52,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
             val persistAcrossReboot = findPreference<SwitchPreference>(Key.PERSIST_ACROSS_REBOOT)!!
             val directBootAware = findPreference<SwitchPreference>(Key.DIRECT_BOOT_AWARE)!!
             val portSocks5 = findPreference<EditTextPreference>(Key.SOCKS_PORT)!!
+            val speedInterval = findPreference<Preference>(Key.SPEED_INTERVAL)!!
 
             val serviceMode = findPreference<Preference>(Key.SERVICE_MODE)!!
             val routeMode = findPreference<Preference>(Key.ROUTE_MODE)!!
@@ -100,6 +101,7 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
                     persistAcrossReboot.isEnabled = stopped
                     directBootAware.isEnabled = stopped
                     serviceMode.isEnabled = stopped
+                    speedInterval.isEnabled = stopped
                     portSocks5.isEnabled = stopped
                     requireHttp.isEnabled = stopped
                     portHttp.isEnabled = stopped
@@ -130,6 +132,12 @@ class SettingsPreferenceFragment : PreferenceFragmentCompat() {
                     }
                     true
                 }
+            speedInterval.onPreferenceChangeListener =
+                Preference.OnPreferenceChangeListener { _, newValue ->
+                    (requireActivity() as MainActivity).connection.bandwidthTimeout =
+                        (newValue as String).toLong()
+                    true
+                }
         }
 
     }

+ 31 - 0
app/src/main/res/drawable/ic_baseline_shutter_speed_24.xml

@@ -0,0 +1,31 @@
+<!--
+  ~
+  ~ Copyright (C) 2021 by nekohasekai <[email protected]>
+  ~ Copyright (C) 2021 by Max Lv <[email protected]>
+  ~ Copyright (C) 2021 by Mygod Studio <[email protected]>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify
+  ~ it under the terms of the GNU General Public License as published by
+  ~ the Free Software Foundation, either version 3 of the License, or
+  ~  (at your option) any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License
+  ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
+  ~
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="?attr/colorControlNormal">
+  <path
+      android:fillColor="@android:color/white"
+      android:pathData="M15,1L9,1v2h6L15,1zM19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9 9,-4.03 9,-9c0,-2.12 -0.74,-4.07 -1.97,-5.61zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7zM11.68,15L6.35,15c0.57,1.62 1.82,2.92 3.41,3.56l-0.11,-0.06 2.03,-3.5zM17.65,11c-0.57,-1.6 -1.78,-2.89 -3.34,-3.54L12.26,11h5.39zM10.61,18.83c0.45,0.11 0.91,0.17 1.39,0.17 1.34,0 2.57,-0.45 3.57,-1.19l-2.11,-3.9 -2.85,4.92zM7.55,8.99C6.59,10.05 6,11.46 6,13c0,0.34 0.04,0.67 0.09,1h4.72L7.55,8.99zM16.34,17.13C17.37,16.06 18,14.6 18,13c0,-0.34 -0.04,-0.67 -0.09,-1h-4.34l2.77,5.13zM13.33,7.15C12.9,7.06 12.46,7 12,7c-1.4,0 -2.69,0.49 -3.71,1.29l2.32,3.56 2.72,-4.7z"/>
+</vector>

+ 15 - 0
app/src/main/res/values/arrays.xml

@@ -364,5 +364,20 @@
         <item>zero</item>
     </string-array>
 
+    <string-array name="notifications_entry">
+        <item>Disable</item>
+        <item>500ms</item>
+        <item>1s</item>
+        <item>3s</item>
+        <item>10s</item>
+    </string-array>
+
+    <string-array name="notifications_value">
+        <item>0</item>
+        <item>500</item>
+        <item>1000</item>
+        <item>3000</item>
+        <item>10000</item>
+    </string-array>
 
 </resources>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -61,6 +61,7 @@
     <string name="ws_max_early_data">Max early data</string>
     <string name="ws_browser_forwarding">Browser Forwarding</string>
     <string name="ws_browser_forwarding_sum">WIf browser forwarding is enabled, the corresponding WebSockets connection will be forwarded through the browser forwarding module before being sent to the Internet.</string>
+    <string name="speed_interval">Speed notification update interval</string>
 
     <string name="traffic">%1$s↑\t%2$s↓</string>
     <string name="stat_summary">Sent: \t\t\t\t\t%3$s\t↑\t%1$s\nReceived: \t%4$s\t↓\t%2$s</string>

+ 9 - 4
app/src/main/res/xml/global_preferences.xml

@@ -1,9 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <PreferenceCategory
-        app:initialExpandedChildrenCount="1"
-        app:title="@string/general_settings">
+    <PreferenceCategory app:title="@string/general_settings">
         <SwitchPreference
             app:icon="@drawable/ic_communication_phonelink_ring"
             app:key="isAutoConnect"
@@ -14,13 +12,20 @@
             app:key="directBootAware"
             app:summary="@string/direct_boot_aware_summary"
             app:title="@string/direct_boot_aware" />
-
         <SwitchPreference
             app:icon="@drawable/ic_device_data_usage"
             app:key="meteredNetwork"
             app:summary="@string/metered_summary"
             app:title="@string/metered" />
 
+        <com.takisoft.preferencex.SimpleMenuPreference
+            app:defaultValue="1000"
+            app:entries="@array/notifications_entry"
+            app:entryValues="@array/notifications_value"
+            app:icon="@drawable/ic_baseline_shutter_speed_24"
+            app:key="speedInterval"
+            app:title="@string/speed_interval"
+            app:useSimpleSummaryProvider="true" />
     </PreferenceCategory>
 
     <PreferenceCategory

+ 33 - 0
metadata/description.txt

@@ -0,0 +1,33 @@
+The application is designed to be used whenever possible.
+
+Supports the following protocols:
+
+■ SOCKS
+■ Shadowsocks
+■ ShadowsocksR
+■ VMess
+■ VLESS
+□ SSH
+□ OpenVPN
+□ Chain
+
+Supports the following subscription protocols:
+
+■ Universal base64 format
+■ SIP008
+■ Clash
+
+
+FEATURES
+
+■ Full basic features
+■ Option to change the notification update interval
+■ A china apps scanner (based on dex classpath scanning, so it's may slower)
+
+
+TIPS
+
+■ Click on the title to scroll to the first proxy or the selected proxy
+■ Proxy list can be dragged by holding the progress bar
+■ The china apps scanner will only scan system apps if "Show system apps" is checked.
+■ V2Ray browser forwarding is not yet available, only for developers to debug.

+ 1 - 0
metadata/name.txt

@@ -0,0 +1 @@
+SagerNet

+ 1 - 0
metadata/summary.txt

@@ -0,0 +1 @@
+The universal proxy toolchain for Android