Add basic REST communication. Initial minimum viable product.
This commit is contained in:
parent
40962c9097
commit
5f04c74daa
7 changed files with 131 additions and 27 deletions
7
.idea/vcs.xml
Normal file
7
.idea/vcs.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
<mapping directory="$USER_HOME$/Documents/Dev/java/automfa" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -16,6 +16,7 @@
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.AutoMFA"
|
android:theme="@style/Theme.AutoMFA"
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<receiver android:name="net.femsci.automfa.SmsReceiver" android:exported="true"
|
<receiver android:name="net.femsci.automfa.SmsReceiver" android:exported="true"
|
||||||
android:permission="android.permission.BROADCAST_SMS">
|
android:permission="android.permission.BROADCAST_SMS">
|
||||||
|
@ -27,7 +28,6 @@
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/Theme.AutoMFA.NoActionBar">
|
android:theme="@style/Theme.AutoMFA.NoActionBar">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
|
@ -1,26 +1,93 @@
|
||||||
package net.femsci.automfa
|
package net.femsci.automfa
|
||||||
|
|
||||||
|
import android.util.JsonWriter
|
||||||
|
import java.io.OutputStreamWriter
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
import java.net.URI
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
import java.util.concurrent.FutureTask
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class AutoMFAGateway {
|
class AutoMFAGateway {
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var url: URL
|
lateinit var uri: URI
|
||||||
|
var connected: Boolean = false
|
||||||
|
|
||||||
|
private fun createClient(path: String, post: Boolean): HttpURLConnection {
|
||||||
|
val url = URL("${uri.scheme}://${uri.authority}$path")
|
||||||
|
val http = url.openConnection() as HttpURLConnection
|
||||||
|
|
||||||
|
if(post) {
|
||||||
|
http.requestMethod = "POST"
|
||||||
|
http.doOutput = true
|
||||||
|
} else {
|
||||||
|
http.requestMethod = "GET"
|
||||||
|
}
|
||||||
|
|
||||||
|
http.setRequestProperty("User-Agent", "AutoMFA v1.0.0E")
|
||||||
|
http.setRequestProperty("Content-Type", "application/json")
|
||||||
|
http.setRequestProperty("Accept", "application/json")
|
||||||
|
|
||||||
|
return http
|
||||||
|
}
|
||||||
|
|
||||||
fun connect(addr: String): Boolean
|
fun connect(addr: String): Boolean
|
||||||
{
|
{
|
||||||
return try {
|
val task = FutureTask {
|
||||||
url = URL(addr)
|
try {
|
||||||
println("url: $url")
|
uri = URI(addr)
|
||||||
val http = url.openConnection() as HttpURLConnection
|
val http = createClient("/ping", false)
|
||||||
http.requestMethod = "GET"
|
|
||||||
|
|
||||||
println("r: ${http.responseCode}")
|
println("r: ${http.responseCode}")
|
||||||
http.responseCode == 200
|
http.responseCode == 200
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val exe = Executors.newCachedThreadPool()
|
||||||
|
exe.submit(task)
|
||||||
|
return try {
|
||||||
|
val result = task.get(5, TimeUnit.SECONDS)
|
||||||
|
connected = result
|
||||||
|
result
|
||||||
|
} catch(_: Exception) {
|
||||||
|
connected = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun publish(message: MessageModel): Boolean
|
||||||
|
{
|
||||||
|
val task = FutureTask {
|
||||||
|
try {
|
||||||
|
val http = createClient("/data/publish", true)
|
||||||
|
|
||||||
|
val out = http.outputStream
|
||||||
|
val writer = OutputStreamWriter(out, "UTF-8")
|
||||||
|
val json = JsonWriter(writer)
|
||||||
|
json.beginObject().name("MessageRaw").value(message.messageRaw).name("Timestamp").value(message.timestamp).endObject().toString()
|
||||||
|
json.flush()
|
||||||
|
|
||||||
|
println("r: ${http.responseCode}")
|
||||||
|
http.responseCode == 200
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val exe = Executors.newCachedThreadPool()
|
||||||
|
exe.submit(task)
|
||||||
|
return try {
|
||||||
|
task.get(5, TimeUnit.SECONDS)
|
||||||
|
} catch(_: Exception)
|
||||||
|
{
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.widget.addTextChangedListener
|
|
||||||
import androidx.navigation.ui.AppBarConfiguration
|
import androidx.navigation.ui.AppBarConfiguration
|
||||||
import net.femsci.automfa.databinding.ActivityMainBinding
|
import net.femsci.automfa.databinding.ActivityMainBinding
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), MessageListener {
|
class MainActivity : AppCompatActivity(), MessageListener {
|
||||||
|
|
||||||
|
@ -22,13 +22,13 @@ class MainActivity : AppCompatActivity(), MessageListener {
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
binding.btnServer.setOnClickListener {
|
binding.btnServer.setOnClickListener {
|
||||||
val addr = binding.srvAddr.text.toString();
|
val addr = binding.srvAddr.text.toString()
|
||||||
|
|
||||||
if (AutoMFAGateway.connect(addr)) {
|
if (AutoMFAGateway.connect(addr)) {
|
||||||
binding.txtStatus.setTextColor(Color.GREEN);
|
binding.txtStatus.setTextColor(Color.GREEN)
|
||||||
binding.txtStatus.text = "Connection established."
|
binding.txtStatus.text = "Connection established."
|
||||||
} else {
|
} else {
|
||||||
binding.txtStatus.setTextColor(Color.RED);
|
binding.txtStatus.setTextColor(Color.RED)
|
||||||
binding.txtStatus.text = "Connection failed..."
|
binding.txtStatus.text = "Connection failed..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,5 +54,8 @@ class MainActivity : AppCompatActivity(), MessageListener {
|
||||||
|
|
||||||
override fun messageReceived(msg: String) {
|
override fun messageReceived(msg: String) {
|
||||||
Toast.makeText(this, "New msg: $msg", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "New msg: $msg", Toast.LENGTH_SHORT).show()
|
||||||
|
if (AutoMFAGateway.connected) {
|
||||||
|
AutoMFAGateway.publish(MessageModel(Instant.now().toEpochMilli(), msg))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
app/src/main/java/net/femsci/automfa/MessageModel.kt
Normal file
3
app/src/main/java/net/femsci/automfa/MessageModel.kt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package net.femsci.automfa
|
||||||
|
|
||||||
|
data class MessageModel(val timestamp: Long, val messageRaw: String)
|
|
@ -12,24 +12,48 @@
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/srvAddr"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="10"
|
|
||||||
android:inputType="textPersonName"
|
|
||||||
android:text="Address" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtStatus"
|
android:id="@+id/txtStatus"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/addrLabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Address:"
|
||||||
|
android:labelFor="@id/srvAddr"/>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/srvAddr"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="55dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="textPersonName"
|
||||||
|
android:text="http://10.0.0.40:8080" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btnServer"
|
android:id="@+id/btnServer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Set server" />
|
android:text="Set server" />
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/listLogs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="590dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -1,6 +1,6 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '7.4.0' apply false
|
id 'com.android.application' version '7.4.2' apply false
|
||||||
id 'com.android.library' version '7.4.0' apply false
|
id 'com.android.library' version '7.4.2' apply false
|
||||||
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
|
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
|
||||||
}
|
}
|
Loading…
Reference in a new issue