android app almost done, start designing

This commit is contained in:
2023-09-23 10:54:55 +02:00
parent 0019b25244
commit 009cf4aaf0
9 changed files with 335 additions and 108 deletions

View File

@@ -21,6 +21,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ScannerActivity"
android:exported="true">
</activity>
</application>
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="true" />

View File

@@ -0,0 +1,108 @@
package com.janishutz.libreevent
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.InputStreamReader
import java.lang.Exception
import java.net.HttpURLConnection
import java.net.URL
class ApiClient {
fun authenticateUser(apiUrl: String, username: String, password: String): String {
try {
val url = URL("$apiUrl/app/authenticate")
println(url)
val connection = url.openConnection() as HttpURLConnection
// Set the request method to POST
connection.requestMethod = "POST"
// Set request headers (if needed)
connection.setRequestProperty("Content-Type", "application/json")
// Add other headers as needed
// Enable input and output streams for the connection
connection.doInput = true
connection.doOutput = true
// Create the JSON request body
val jsonRequest = "{\"username\":\"$username\",\"password\":\"$password\"}"
// Write the JSON data to the output stream
val outputStream = DataOutputStream(connection.outputStream)
outputStream.write(jsonRequest.toByteArray(Charsets.UTF_8))
outputStream.flush()
outputStream.close()
// Get the response code from the server
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
// Read and handle the response from the server
val reader = BufferedReader(InputStreamReader(connection.inputStream))
val response = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
response.append(line)
}
reader.close()
// Return the response as a String
return response.toString()
} else {
// Handle the error (e.g., authentication failed)
// You can also throw an exception here if needed
return "status-code-non-ok"
}
} catch (e: Exception) {
e.printStackTrace()
return "error"
}
}
fun checkTicket(apiUrl: String, username: String, password: String, ticket: String): String {
val url = URL("$apiUrl/app/ticketLookup")
val connection = url.openConnection() as HttpURLConnection
// Set the request method to POST
connection.requestMethod = "POST"
// Set request headers (if needed)
connection.setRequestProperty("Content-Type", "application/json")
// Add other headers as needed
// Enable input and output streams for the connection
connection.doInput = true
connection.doOutput = true
// Create the JSON request body
val jsonRequest = "{\"username\":\"$username\",\"password\":\"$password\",\"ticketID\":$ticket}"
// Write the JSON data to the output stream
val outputStream = DataOutputStream(connection.outputStream)
outputStream.write(jsonRequest.toByteArray(Charsets.UTF_8))
outputStream.flush()
outputStream.close()
// Get the response code from the server
val responseCode = connection.responseCode
if (responseCode == HttpURLConnection.HTTP_OK) {
// Read and handle the response from the server
val reader = BufferedReader(InputStreamReader(connection.inputStream))
val response = StringBuilder()
var line: String?
while (reader.readLine().also { line = it } != null) {
response.append(line)
}
reader.close()
// Return the response as a String
return response.toString()
} else {
// Handle the error (e.g., authentication failed)
// You can also throw an exception here if needed
return ""
}
}
}

View File

@@ -4,6 +4,9 @@ import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.app.AlertDialog
import com.janishutz.libreevent.ApiClient
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -11,13 +14,54 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
val loginButton = findViewById<Button>(R.id.loginButton)
val urlEditText = findViewById<EditText>(R.id.url)
val usernameEditText = findViewById<EditText>(R.id.username)
val passwordEditText = findViewById<EditText>(R.id.password)
loginButton.setOnClickListener {
login()
val url = urlEditText.text.toString()
val username = usernameEditText.text.toString()
val password = passwordEditText.text.toString()
login( url, username, password )
}
}
private fun login() {
val switchIntent = Intent(this, ScanActivity::class.java)
startActivity(switchIntent)
private fun login( url: String, username: String, password: String ) {
val res = ApiClient().authenticateUser( url, username, password )
println( res )
if ( res == "authOk" ) {
val switchIntent = Intent(this, ScannerActivity::class.java)
startActivity(switchIntent)
} else if ( res == "status-code-non-ok" ) {
val alertDialogBuilder = AlertDialog.Builder(this)
alertDialogBuilder.setTitle("Username or password incorrect")
alertDialogBuilder.setMessage("Please ensure that the values entered are correct and try again")
alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert)
alertDialogBuilder.setPositiveButton("OK") { dialog, _ ->
dialog.dismiss()
}
alertDialogBuilder.show()
} else if ( res == "error") {
val alertDialogBuilder = AlertDialog.Builder(this)
alertDialogBuilder.setTitle("Unable to connect")
alertDialogBuilder.setMessage("Please ensure that the url specified is correct.")
alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert)
alertDialogBuilder.setPositiveButton("OK") { dialog, _ ->
dialog.dismiss()
}
alertDialogBuilder.show()
} else if ( res == "wrong") {
val alertDialogBuilder = AlertDialog.Builder(this)
alertDialogBuilder.setTitle("Username or password incorrect")
alertDialogBuilder.setMessage("Please ensure that the values entered are correct and try again")
alertDialogBuilder.setIcon(android.R.drawable.ic_dialog_alert)
alertDialogBuilder.setPositiveButton("OK") { dialog, _ ->
dialog.dismiss()
}
alertDialogBuilder.show()
}
}
}

View File

@@ -5,14 +5,18 @@ import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ActivityCompat
import com.journeyapps.barcodescanner.BarcodeCallback
import com.journeyapps.barcodescanner.BarcodeResult
import com.journeyapps.barcodescanner.CaptureActivity
import com.journeyapps.barcodescanner.CaptureManager
import com.journeyapps.barcodescanner.DecoratedBarcodeView
class ScanActivity : AppCompatActivity() {
class ScannerActivity : CaptureActivity() {
private lateinit var barcodeView: DecoratedBarcodeView
private lateinit var captureManager: CaptureManager
private var lastScanned: String = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scanner)
@@ -32,6 +36,25 @@ class ScanActivity : AppCompatActivity() {
captureManager.initializeFromIntent(intent, null)
captureManager.decode()
barcodeView.decodeContinuous(object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult?) {
if (result != null) {
val scannedData = result.text // This is the scanned data (e.g., QR code content)
handleScanResult(scannedData)
}
}
override fun possibleResultPoints(resultPoints: List<com.google.zxing.ResultPoint>?) {
// Optional: Handle possible result points
}
})
}
private fun handleScanResult(result: String) {
if ( lastScanned != result ) {
println(result)
lastScanned = result
}
}
override fun onResume() {

View File

@@ -0,0 +1,73 @@
package com.janishutz.libreevent
import android.Manifest
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ActivityCompat
import com.journeyapps.barcodescanner.BarcodeCallback
import com.journeyapps.barcodescanner.CaptureManager
import com.journeyapps.barcodescanner.DecoratedBarcodeView
class ScannerActivity : AppCompatActivity() {
private lateinit var barcodeView: DecoratedBarcodeView
private lateinit var captureManager: CaptureManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_scanner)
barcodeView = findViewById(R.id.barcodeScannerView)
// Check for camera permission and request if not granted
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), CAMERA_PERMISSION_REQUEST)
} else {
setupScanner()
}
}
private fun setupScanner() {
captureManager = CaptureManager(this, barcodeView)
captureManager.initializeFromIntent(intent, null)
captureManager.decode()
}
private fun handleScanResult(result: String) {
// The `result` parameter contains the scanned data (e.g., QR code content)
// You can process it or send it as needed
}
override fun onResume() {
super.onResume()
captureManager.onResume()
}
override fun onPause() {
super.onPause()
captureManager.onPause()
}
// Pass savedInstanceState to onSaveInstanceState
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
captureManager.onSaveInstanceState(outState)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAMERA_PERMISSION_REQUEST) {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setupScanner()
} else {
// Handle permission denied
}
}
}
companion object {
private const val CAMERA_PERMISSION_REQUEST = 1
}
}

View File

@@ -20,7 +20,7 @@
app:layout_constraintVertical_bias="0.157" />
<EditText
android:id="@+id/editTextTextEmailAddress"
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="52dp"
@@ -30,10 +30,10 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editTextText" />
app:layout_constraintTop_toBottomOf="@+id/url" />
<EditText
android:id="@+id/editTextText"
android:id="@+id/url"
android:layout_width="302dp"
android:layout_height="48dp"
android:layout_marginTop="32dp"
@@ -46,7 +46,7 @@
app:layout_constraintTop_toBottomOf="@+id/textView2" />
<EditText
android:id="@+id/editTextTextPassword"
android:id="@+id/password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
@@ -56,7 +56,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editTextTextEmailAddress" />
app:layout_constraintTop_toBottomOf="@+id/username" />
<Button
android:id="@+id/loginButton"
@@ -66,7 +66,7 @@
android:text="Log in"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editTextTextPassword" />
app:layout_constraintTop_toBottomOf="@+id/password" />
<TextView
android:id="@+id/textView2"