mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2024-04-21 14:11:34 +00:00
support android
This commit is contained in:
@@ -1,17 +1,22 @@
|
||||
package cn.openp2p
|
||||
|
||||
import android.app.Service
|
||||
import android.app.*
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.VpnService
|
||||
import android.graphics.Color
|
||||
import android.os.Binder
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import openp2p.Openp2p
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import cn.openp2p.ui.login.LoginActivity
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import openp2p.Openp2p
|
||||
|
||||
class OpenP2PService : VpnService() {
|
||||
|
||||
class OpenP2PService : Service() {
|
||||
companion object {
|
||||
private val LOG_TAG = OpenP2PService::class.simpleName
|
||||
}
|
||||
@@ -21,39 +26,90 @@ class OpenP2PService : VpnService() {
|
||||
}
|
||||
|
||||
private val binder = LocalBinder()
|
||||
private lateinit var network: openp2p.P2PNetwork
|
||||
private lateinit var network: openp2p.P2PNetwork
|
||||
private lateinit var mToken: String
|
||||
private var running:Boolean =true
|
||||
override fun onCreate() {
|
||||
Log.i("xiao","onCreate - Thread ID = " + Thread.currentThread().id)
|
||||
Log.i(LOG_TAG, "onCreate - Thread ID = " + Thread.currentThread().id)
|
||||
var channelId: String? = null
|
||||
channelId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel("kim.hsl", "ForegroundService")
|
||||
} else {
|
||||
""
|
||||
}
|
||||
val notificationIntent = Intent(this, LoginActivity::class.java)
|
||||
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this, 0,
|
||||
notificationIntent, 0
|
||||
)
|
||||
|
||||
val notification = channelId?.let {
|
||||
NotificationCompat.Builder(this, it)
|
||||
// .setSmallIcon(R.mipmap.app_icon)
|
||||
.setContentTitle("My Awesome App")
|
||||
.setContentText("Doing some work...")
|
||||
.setContentIntent(pendingIntent).build()
|
||||
}
|
||||
|
||||
startForeground(1337, notification)
|
||||
super.onCreate()
|
||||
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Log.i("xiao", "onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().id)
|
||||
Log.i(
|
||||
LOG_TAG,
|
||||
"onStartCommand - startId = " + startId + ", Thread ID = " + Thread.currentThread().id
|
||||
)
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun onBind(p0: Intent?): IBinder? {
|
||||
|
||||
val token = p0?.getStringExtra("token")
|
||||
Log.i(LOG_TAG, "onBind - Thread ID = " + Thread.currentThread().id + token)
|
||||
GlobalScope.launch {
|
||||
network = Openp2p.runAsModule(getExternalFilesDir(null).toString(), token, 0, 1)
|
||||
val isConnect = network.connect(30000) // ms
|
||||
Log.i(OpenP2PService.LOG_TAG, "login result: " + isConnect.toString());
|
||||
do {
|
||||
Thread.sleep(1000)
|
||||
}while(network.connect(30000)&&running)
|
||||
stopSelf()
|
||||
}
|
||||
return binder
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.i("xiao", "onDestroy - Thread ID = " + Thread.currentThread().id)
|
||||
Log.i(LOG_TAG, "onDestroy - Thread ID = " + Thread.currentThread().id)
|
||||
super.onDestroy()
|
||||
}
|
||||
fun onStart(token:String){
|
||||
GlobalScope.launch {
|
||||
do {
|
||||
network =Openp2p.runAsModule(getExternalFilesDir(null).toString(), token, 0)
|
||||
val isConnect = network.connect(30000) // ms
|
||||
Log.i(OpenP2PService.LOG_TAG, "login result: " + isConnect.toString());
|
||||
} while(!network?.connect(10000))
|
||||
|
||||
}
|
||||
override fun onUnbind(intent: Intent?): Boolean {
|
||||
Log.i(LOG_TAG, "onUnbind - Thread ID = " + Thread.currentThread().id)
|
||||
stopSelf()
|
||||
return super.onUnbind(intent)
|
||||
}
|
||||
fun isConnected(): Boolean{
|
||||
fun isConnected(): Boolean {
|
||||
if (!::network.isInitialized) return false
|
||||
return network?.connect(1000)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
running=false
|
||||
stopSelf()
|
||||
}
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun createNotificationChannel(channelId: String, channelName: String): String? {
|
||||
val chan = NotificationChannel(
|
||||
channelId,
|
||||
channelName, NotificationManager.IMPORTANCE_NONE
|
||||
)
|
||||
chan.lightColor = Color.BLUE
|
||||
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
||||
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
service.createNotificationChannel(chan)
|
||||
return channelId
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,26 @@
|
||||
package cn.openp2p.ui.login
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.ActivityManager
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.ServiceConnection
|
||||
import android.net.Uri
|
||||
import android.net.VpnService
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.EditText
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.Observer
|
||||
@@ -23,17 +30,18 @@ import cn.openp2p.R
|
||||
import cn.openp2p.databinding.ActivityLoginBinding
|
||||
import openp2p.Openp2p
|
||||
import kotlin.concurrent.thread
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
companion object {
|
||||
private val LOG_TAG = LoginActivity::class.simpleName
|
||||
}
|
||||
|
||||
private val connection = object : ServiceConnection {
|
||||
override fun onServiceConnected(className: ComponentName, service: IBinder) {
|
||||
val binder = service as OpenP2PService.LocalBinder
|
||||
mService = binder.getService()
|
||||
mService.onStart(mToken)
|
||||
}
|
||||
|
||||
override fun onServiceDisconnected(className: ComponentName) {
|
||||
@@ -43,7 +51,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
private lateinit var loginViewModel: LoginViewModel
|
||||
private lateinit var binding: ActivityLoginBinding
|
||||
private lateinit var mService: OpenP2PService
|
||||
private var mToken: String=""
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -52,7 +60,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
|
||||
val token = binding.token
|
||||
val login = binding.login
|
||||
val onlineState=binding.onlineState
|
||||
val onlineState = binding.onlineState
|
||||
val openp2pLog = binding.openp2pLog
|
||||
val profile = binding.profile
|
||||
val loading = binding.loading
|
||||
@@ -70,7 +78,6 @@ class LoginActivity : AppCompatActivity() {
|
||||
token.error = getString(loginState.passwordError)
|
||||
}
|
||||
})
|
||||
mToken=token.text.toString()
|
||||
val intent1 = VpnService.prepare(this) ?: return
|
||||
loginViewModel.loginResult.observe(this@LoginActivity, Observer {
|
||||
val loginResult = it ?: return@Observer
|
||||
@@ -102,59 +109,57 @@ class LoginActivity : AppCompatActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
// setOnEditorActionListener { _, actionId, _ ->
|
||||
// when (actionId) {
|
||||
// EditorInfo.IME_ACTION_DONE ->
|
||||
// loginViewModel.login(
|
||||
// "username.text.toString()",
|
||||
// token.text.toString()
|
||||
// )
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
|
||||
// openp2pLog.setText(getExternalFilesDir(null).toString())
|
||||
openp2pLog.setText(R.string.phone_setting)
|
||||
token.setText(Openp2p.getToken(getExternalFilesDir(null).toString()))
|
||||
login.setOnClickListener {
|
||||
// loading.visibility = View.VISIBLE
|
||||
// loginViewModel.login(username.text.toString(), password.text.toString())
|
||||
|
||||
// startService(Intent(this, OpenP2PService::class.java))
|
||||
val intent = Intent(this@LoginActivity,OpenP2PService::class.java)
|
||||
if (login.text.toString()=="退出"){
|
||||
// val intent = Intent(this@LoginActivity, OpenP2PService::class.java)
|
||||
// stopService(intent)
|
||||
Log.i(LOG_TAG, "quit")
|
||||
mService.stop()
|
||||
unbindService(connection)
|
||||
val intent = Intent(this@LoginActivity, OpenP2PService::class.java)
|
||||
stopService(intent)
|
||||
exitAPP()
|
||||
|
||||
}
|
||||
login.setText("退出")
|
||||
Log.i(LOG_TAG, "start")
|
||||
val intent = Intent(this@LoginActivity, OpenP2PService::class.java)
|
||||
intent.putExtra("token", token.text.toString())
|
||||
bindService(intent, connection, Context.BIND_AUTO_CREATE)
|
||||
startService(intent)
|
||||
thread {
|
||||
do {
|
||||
Thread.sleep(3000)
|
||||
Thread.sleep(1000)
|
||||
if (!::mService.isInitialized) continue
|
||||
val isConnect = mService.isConnected()
|
||||
// Log.i(LOG_TAG, "mService.isConnected() = " + isConnect.toString())
|
||||
runOnUiThread {
|
||||
if (isConnect) {
|
||||
onlineState.setText("在线")
|
||||
} else {
|
||||
onlineState.setText("离线")
|
||||
if (isConnect) {
|
||||
onlineState.setText("在线")
|
||||
} else {
|
||||
onlineState.setText("离线")
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(true)
|
||||
} while (true)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// fun listenProgress() {
|
||||
// Thread {
|
||||
// while (progress < MsgService.MAX_PROGRESS) {
|
||||
// progress = msgService.getProgress()
|
||||
// mProgressBar.setProgress(progress)
|
||||
// try {
|
||||
// Thread.sleep(1000)
|
||||
// } catch (e: InterruptedException) {
|
||||
// e.printStackTrace()
|
||||
// }
|
||||
// }
|
||||
// }.start()
|
||||
// }
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@SuppressLint("ServiceCast")
|
||||
fun exitAPP() {
|
||||
val activityManager =
|
||||
applicationContext?.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
val appTaskList = activityManager.appTasks
|
||||
|
||||
for (i in appTaskList.indices) {
|
||||
appTaskList[i].finishAndRemoveTask()
|
||||
}
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
private fun updateUiWithUser(model: LoggedInUserView) {
|
||||
val welcome = getString(R.string.welcome)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</selector>
|
||||
+1
-1
@@ -17,7 +17,7 @@ import (
|
||||
// ./openp2p install -node hhd1207-222 -token YOUR-TOKEN -sharebandwidth 0 -peernode hhdhome-n1 -dstip 127.0.0.1 -dstport 50022 -protocol tcp -srcport 22
|
||||
func install() {
|
||||
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
|
||||
gLog.Println(LvINFO, "Contact: QQ: 477503927, Email: openp2p.cn@gmail.com")
|
||||
gLog.Println(LvINFO, "Contact: QQ: 16947733, Email: openp2p.cn@gmail.com")
|
||||
gLog.Println(LvINFO, "install start")
|
||||
defer gLog.Println(LvINFO, "install end")
|
||||
// auto uninstall
|
||||
|
||||
@@ -51,6 +51,8 @@ func natTCP(serverHost string, serverPort int, localPort int) (publicIP string,
|
||||
|
||||
}
|
||||
func natTest(serverHost string, serverPort int, localPort int) (publicIP string, publicPort int, err error) {
|
||||
gLog.Println(LvDEBUG, "natTest start")
|
||||
defer gLog.Println(LvDEBUG, "natTest end")
|
||||
conn, err := net.ListenPacket("udp", fmt.Sprintf(":%d", localPort))
|
||||
if err != nil {
|
||||
gLog.Println(LvERROR, "natTest listen udp error:", err)
|
||||
@@ -113,6 +115,7 @@ func publicIPTest(publicIP string, echoPort int) (hasPublicIP int, hasUPNPorNATP
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
gLog.Println(LvDEBUG, "echo server start")
|
||||
var err error
|
||||
echoConn, err = net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: echoPort})
|
||||
if err != nil {
|
||||
@@ -129,6 +132,7 @@ func publicIPTest(publicIP string, echoPort int) (hasPublicIP int, hasUPNPorNATP
|
||||
return
|
||||
}
|
||||
echoConn.WriteToUDP(buf[0:n], addr)
|
||||
gLog.Println(LvDEBUG, "echo server end")
|
||||
}()
|
||||
wg.Wait() // wait echo udp
|
||||
defer echoConn.Close()
|
||||
@@ -136,6 +140,7 @@ func publicIPTest(publicIP string, echoPort int) (hasPublicIP int, hasUPNPorNATP
|
||||
for i := 0; i < 2; i++ {
|
||||
if i == 1 {
|
||||
// test upnp or nat-pmp
|
||||
gLog.Println(LvDEBUG, "upnp test start")
|
||||
nat, err := Discover()
|
||||
if err != nil || nat == nil {
|
||||
gLog.Println(LvDEBUG, "could not perform UPNP discover:", err)
|
||||
|
||||
+10
-7
@@ -43,7 +43,7 @@ func Run() {
|
||||
}
|
||||
parseParams("")
|
||||
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
|
||||
gLog.Println(LvINFO, "Contact: QQ: 477503927, Email: openp2p.cn@gmail.com")
|
||||
gLog.Println(LvINFO, "Contact: QQ group 16947733, Email openp2p.cn@gmail.com")
|
||||
|
||||
if gConf.daemonMode {
|
||||
d := daemon{}
|
||||
@@ -67,18 +67,21 @@ var network *P2PNetwork
|
||||
|
||||
// for Android app
|
||||
// gomobile not support uint64 exported to java
|
||||
func RunAsModule(baseDir string, token string, bw int) *P2PNetwork {
|
||||
func RunAsModule(baseDir string, token string, bw int, logLevel int) *P2PNetwork {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
os.Chdir(baseDir) // for system service
|
||||
gLog = NewLogger(baseDir, ProducnName, LvDEBUG, 1024*1024, LogFileAndConsole)
|
||||
// TODO: install sub command, deamon process
|
||||
|
||||
parseParams("")
|
||||
|
||||
n, _ := strconv.ParseUint(token, 10, 64)
|
||||
gConf.setToken(n)
|
||||
gConf.setShareBandwidth(0)
|
||||
n, err := strconv.ParseUint(token, 10, 64)
|
||||
if err == nil {
|
||||
gConf.setToken(n)
|
||||
}
|
||||
gLog.setLevel(LogLevel(logLevel))
|
||||
gConf.setShareBandwidth(bw)
|
||||
gLog.Println(LvINFO, "openp2p start. version: ", OpenP2PVersion)
|
||||
gLog.Println(LvINFO, "Contact: QQ: 477503927, Email: openp2p.cn@gmail.com")
|
||||
gLog.Println(LvINFO, "Contact: QQ group 16947733, Email openp2p.cn@gmail.com")
|
||||
gLog.Println(LvINFO, &gConf)
|
||||
|
||||
network = P2PNetworkInstance(&gConf.Network)
|
||||
|
||||
+1
-1
@@ -64,6 +64,7 @@ func P2PNetworkInstance(config *NetworkConfig) *P2PNetwork {
|
||||
}
|
||||
|
||||
func (pn *P2PNetwork) run() {
|
||||
go pn.readLoop()
|
||||
go pn.autorunApp()
|
||||
heartbeatTimer := time.NewTicker(NetworkHeartbeatTime)
|
||||
for pn.running {
|
||||
@@ -487,7 +488,6 @@ func (pn *P2PNetwork) init() error {
|
||||
err = errors.New("get local ip failed")
|
||||
break
|
||||
}
|
||||
go pn.readLoop()
|
||||
|
||||
pn.config.mac = getmac(pn.config.localIP)
|
||||
pn.config.os = getOsName()
|
||||
|
||||
@@ -20,6 +20,7 @@ require (
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/onsi/ginkgo v1.16.4 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/mobile v0.0.0-20221020085226-b36e6246172e // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
|
||||
Reference in New Issue
Block a user