adds rest list receiver, adds local code storage
- rest class now receives a list as well as single messages - adds support for threaded singleton which takes care of continuous checking of the bump server to get the most up-to-date list of messages - adds local data class with tests to get locally saved code in preferences
This commit is contained in:
parent
7e4cfceab4
commit
734b64ce3b
@ -1,6 +1,8 @@
|
||||
package com.example.bump
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.internal.runner.InstrumentationConnection
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -28,6 +30,15 @@ class MessageProcessorTest {
|
||||
Assert.assertEquals(test, decrypted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun setCode() {
|
||||
val test = getRandomString(512)
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val local = LocalData(appContext)
|
||||
local.code = test
|
||||
Assert.assertEquals(local.code, test)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun decryptMessage(code: String, messageData: String): String {
|
||||
|
@ -68,9 +68,8 @@ class RestCryptTest{
|
||||
val lock = CountDownLatch(1)
|
||||
|
||||
|
||||
fun listTester(resultList: JSONObject) {
|
||||
fun listTester(messages: JSONArray) {
|
||||
val message = MessageProcessor(code)
|
||||
val messages: JSONArray = resultList.get("messages") as JSONArray
|
||||
|
||||
var messageEncoded = messages[0] as JSONObject
|
||||
var messageData = messageEncoded.get("data").toString()
|
||||
|
116
app/src/main/java/com/example/bump/BumpProcessor.kt
Normal file
116
app/src/main/java/com/example/bump/BumpProcessor.kt
Normal file
@ -0,0 +1,116 @@
|
||||
package com.example.bump
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.android.volley.toolbox.JsonObjectRequest
|
||||
import com.maenle.bump.MainActivity
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import javax.inject.Inject
|
||||
|
||||
class BumpProcessor constructor(context: Context) {
|
||||
|
||||
private var rest: RestSingleton = RestSingleton.getInstance(context)
|
||||
private var secret: String? = null
|
||||
private lateinit var log: JSONArray
|
||||
private lateinit var messenger: MessageProcessor
|
||||
|
||||
init {
|
||||
secret = getSecret(context)
|
||||
log = getLog(context)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE: BumpProcessor? = null
|
||||
fun getInstance(context: Context) =
|
||||
INSTANCE ?: synchronized(this) {
|
||||
INSTANCE ?: BumpProcessor(context).also {
|
||||
INSTANCE = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLog(context: Context, list: JSONArray) {
|
||||
for(i in 0 until list.length()) {
|
||||
var exists = false
|
||||
for(j in 0 until log.length()) {
|
||||
if (list[i] == log[j]) {
|
||||
exists = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
exists.let {
|
||||
log.put(list[i])
|
||||
addToLog(context, list[i] as JSONObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun hasSecret(): Boolean {
|
||||
secret?.let {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun getSecret(context: Context):String? {
|
||||
val secretFile = File(context.filesDir, ".bump_secrets")
|
||||
!secretFile.exists().let {
|
||||
secretFile.createNewFile()
|
||||
}
|
||||
for(line in secretFile.readLines()) {
|
||||
return line
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun startUpdateHandler(context: Context) {
|
||||
|
||||
val delay: Long = 30_000 //milliseconds
|
||||
val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
handler.postDelayed(object : Runnable {
|
||||
override fun run() {
|
||||
updateFromServer(context)
|
||||
handler.postDelayed(this, delay)
|
||||
}
|
||||
}, delay)
|
||||
}
|
||||
|
||||
private fun updateFromServer(context: Context) {
|
||||
rest.list(messenger.sender) {list -> updateLog(context, list)}
|
||||
}
|
||||
|
||||
private fun addToLog(context: Context, line: JSONObject) {
|
||||
val logFile = File(context.filesDir, ".bump_log")
|
||||
logFile.appendText(line.toString())
|
||||
}
|
||||
|
||||
fun addSecret(context: Context, newSecret: String) {
|
||||
if(!hasSecret()) {
|
||||
val secretFile = File(context.filesDir, ".bump_secrets")
|
||||
!secretFile.exists().let {
|
||||
secretFile.createNewFile()
|
||||
}
|
||||
secretFile.appendText(newSecret)
|
||||
}
|
||||
secret = getSecret(context)
|
||||
}
|
||||
|
||||
private fun getLog(context: Context): JSONArray {
|
||||
val logFile = File(context.filesDir, ".bump_log")
|
||||
val log = JSONArray()
|
||||
!logFile.exists().let {
|
||||
logFile.createNewFile()
|
||||
}
|
||||
for(line in logFile.readLines()) {
|
||||
log.put(JSONObject(line))
|
||||
}
|
||||
return log
|
||||
}
|
||||
|
||||
}
|
@ -31,9 +31,7 @@ import kotlin.math.min
|
||||
import android.view.WindowInsets
|
||||
|
||||
import android.graphics.Insets
|
||||
|
||||
|
||||
|
||||
import com.example.bump.BumpProcessor
|
||||
|
||||
|
||||
class CameraFragment: Fragment() {
|
||||
@ -182,6 +180,9 @@ class CameraFragment: Fragment() {
|
||||
.addOnSuccessListener { barcodes ->
|
||||
barcodes.forEach {
|
||||
Log.d(TAG, it.rawValue!!)
|
||||
val bump = BumpProcessor.getInstance(requireContext())
|
||||
bump.addSecret(requireContext(), it.rawValue!!)
|
||||
fragmentManager?.popBackStack()
|
||||
}
|
||||
}
|
||||
.addOnFailureListener {
|
||||
|
@ -6,8 +6,13 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.example.bump.BumpProcessor
|
||||
import com.example.bump.MessageProcessor
|
||||
import com.example.bump.RestSingleton
|
||||
import com.maenle.bump.databinding.FragmentFirstBinding
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
||||
@ -20,6 +25,11 @@ class FirstFragment : Fragment() {
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var rest: RestSingleton
|
||||
private lateinit var log: JSONArray
|
||||
|
||||
private val bump = BumpProcessor(requireContext())
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
@ -27,21 +37,20 @@ class FirstFragment : Fragment() {
|
||||
|
||||
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.buttonFirst.setOnClickListener {
|
||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||
if(bump.hasSecret()){
|
||||
binding.buttonFirst.visibility = View.GONE
|
||||
} else {
|
||||
binding.buttonFirst.setOnClickListener {
|
||||
findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
|
||||
}
|
||||
}
|
||||
|
||||
testDecryption()
|
||||
}
|
||||
|
||||
fun testDecryption() {
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
|
24
app/src/main/java/com/example/bump/LocalData.kt
Normal file
24
app/src/main/java/com/example/bump/LocalData.kt
Normal file
@ -0,0 +1,24 @@
|
||||
package com.example.bump
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Context.MODE_PRIVATE
|
||||
import android.content.SharedPreferences
|
||||
import com.maenle.bump.R
|
||||
|
||||
class LocalData(context: Context) {
|
||||
private val codeKey = context.getString(R.string.code_key)
|
||||
private val preferenceKey = context.getString(R.string.preference_file_key)
|
||||
|
||||
private val preferences: SharedPreferences =
|
||||
context.getSharedPreferences(preferenceKey, MODE_PRIVATE)
|
||||
|
||||
var code: String?
|
||||
get() {
|
||||
return preferences.getString(codeKey, null)
|
||||
}
|
||||
set(codeValue) {
|
||||
preferences.edit().putString(codeKey, codeValue).apply()
|
||||
}
|
||||
|
||||
// var messages: List<>
|
||||
}
|
@ -6,6 +6,7 @@ import android.content.Context
|
||||
// Not object class. AndroidManifest.xml error happen.
|
||||
class MainApplication : Application() {
|
||||
lateinit var rest : RestSingleton
|
||||
lateinit var bump : BumpProcessor
|
||||
|
||||
init {
|
||||
instance = this
|
||||
@ -25,7 +26,10 @@ class MainApplication : Application() {
|
||||
|
||||
// Use ApplicationContext.
|
||||
// example: SharedPreferences etc...
|
||||
val context: Context = MainApplication.applicationContext()
|
||||
val context: Context = applicationContext()
|
||||
rest = RestSingleton(context)
|
||||
// bump = BumpProcessor(context)
|
||||
|
||||
// bump.startUpdateHandler(context)
|
||||
}
|
||||
}
|
5
app/src/main/java/com/example/bump/Message.kt
Normal file
5
app/src/main/java/com/example/bump/Message.kt
Normal file
@ -0,0 +1,5 @@
|
||||
package com.example.bump
|
||||
|
||||
class Message {
|
||||
|
||||
}
|
@ -29,7 +29,7 @@ class RestSingleton constructor(context: Context){
|
||||
private const val URL = "http://192.168.68.127:4000/api/"
|
||||
}
|
||||
|
||||
fun list(sender: String, callback: (JSONObject) -> Unit){
|
||||
fun list(sender: String, callback: (JSONArray) -> Unit){
|
||||
val url = URL + "list/"
|
||||
val data = JSONObject()
|
||||
data.put("sender", sender)
|
||||
@ -38,10 +38,10 @@ class RestSingleton constructor(context: Context){
|
||||
data,
|
||||
{ response ->
|
||||
run {
|
||||
callback(response)
|
||||
callback(response.get("messages") as JSONArray)
|
||||
}
|
||||
} ,
|
||||
{callback(JSONObject())})
|
||||
{callback(JSONArray())})
|
||||
|
||||
requestQueue.add(jsonRequest)
|
||||
}
|
||||
|
@ -12,4 +12,6 @@
|
||||
<string name="current_sender">No Sender Added</string>
|
||||
<string name="scan_sender">Scan</string>
|
||||
<string name="camera_fragment_label">Camera Fragment</string>
|
||||
<string name="preference_file_key">code_file_key</string>
|
||||
<string name="code_key">code_key</string>
|
||||
</resources>
|
Loading…
Reference in New Issue
Block a user