diff --git a/app/src/main/java/io/legado/app/service/WebService.kt b/app/src/main/java/io/legado/app/service/WebService.kt index a87fb520d..d05b2042e 100644 --- a/app/src/main/java/io/legado/app/service/WebService.kt +++ b/app/src/main/java/io/legado/app/service/WebService.kt @@ -3,12 +3,20 @@ package io.legado.app.service import android.content.Context import android.content.Intent import androidx.core.app.NotificationCompat +import io.legado.app.App import io.legado.app.R import io.legado.app.base.BaseService import io.legado.app.constant.Action import io.legado.app.constant.AppConst import io.legado.app.help.IntentHelp +import io.legado.app.utils.NetworkUtils +import io.legado.app.utils.getPrefInt +import io.legado.app.web.HttpServer +import io.legado.app.web.WebSocketServer +import kotlinx.coroutines.launch import org.jetbrains.anko.startService +import org.jetbrains.anko.toast +import java.io.IOException class WebService : BaseService() { @@ -29,6 +37,9 @@ class WebService : BaseService() { } + private var httpServer: HttpServer? = null + private var webSocketServer: WebSocketServer? = null + override fun onCreate() { super.onCreate() isRun = true @@ -43,10 +54,47 @@ class WebService : BaseService() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { when (intent?.action) { Action.stop -> stopSelf() + else -> upWebServer() } return super.onStartCommand(intent, flags, startId) } + private fun upWebServer() { + if (httpServer?.isAlive == true) { + httpServer?.stop() + } + if (webSocketServer?.isAlive == true) { + webSocketServer?.stop() + } + val port = getPort() + httpServer = HttpServer(port) + webSocketServer = WebSocketServer(port + 1) + val address = NetworkUtils.getLocalIPAddress() + if (address != null) { + try { + httpServer?.start() + webSocketServer?.start(1000 * 30) // 通信超时设置 + isRun = true + updateNotification(getString(R.string.http_ip, address.hostAddress, port)) + } catch (e: IOException) { + launch { + toast(e.localizedMessage) + stopSelf() + } + } + } else { + stopSelf() + } + } + + private fun getPort(): Int { + var port = App.INSTANCE.getPrefInt("webPort", 1122) + if (port > 65530 || port < 1024) { + port = 1122 + } + return port + } + /** * 更新通知 */ diff --git a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt index 3f42784f9..616aa0006 100644 --- a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt +++ b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt @@ -1,8 +1,12 @@ package io.legado.app.utils import retrofit2.Response +import java.net.InetAddress +import java.net.NetworkInterface +import java.net.SocketException import java.net.URL import java.util.* +import java.util.regex.Pattern object NetworkUtils { fun getUrl(response: Response<*>): String { @@ -93,4 +97,50 @@ object NetworkUtils { } else url.substring(0, index) } + /** + * Get local Ip address. + */ + fun getLocalIPAddress(): InetAddress? { + var enumeration: Enumeration? = null + try { + enumeration = NetworkInterface.getNetworkInterfaces() + } catch (e: SocketException) { + e.printStackTrace() + } + + if (enumeration != null) { + while (enumeration.hasMoreElements()) { + val nif = enumeration.nextElement() + val addresses = nif.inetAddresses + if (addresses != null) { + while (addresses.hasMoreElements()) { + val address = addresses.nextElement() + if (!address.isLoopbackAddress && isIPv4Address(address.hostAddress)) { + return address + } + } + } + } + } + return null + } + + /** + * Check if valid IPV4 address. + * + * @param input the address string to check for validity. + * @return True if the input parameter is a valid IPv4 address. + */ + fun isIPv4Address(input: String): Boolean { + return IPV4_PATTERN.matcher(input).matches() + } + + /** + * Ipv4 address check. + */ + private val IPV4_PATTERN = Pattern.compile( + "^(" + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}" + + "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" + ) + } \ No newline at end of file