updated the sheet
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
<!-- ===== Application ===== -->
|
||||
<!-- usesCleartextTraffic was `true`, commented "allows http if any". There
|
||||
is no http:// endpoint left in the app: every host it talks to —
|
||||
api.doormile.com, queue.workolik.com, the OSM tile server and the OSRM
|
||||
api.doormile.com, the OSM tile server and the OSRM
|
||||
router — is https, and all of them present valid publicly trusted
|
||||
certificates.
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
the certificate bypass in MyHttpOverrides, which was the other half
|
||||
of the same hole. -->
|
||||
<application
|
||||
android:label="Doormile Rider"
|
||||
android:label="Miler"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:usesCleartextTraffic="false">
|
||||
|
||||
@@ -1,278 +1,232 @@
|
||||
package com.doormile.partner
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* BroadcastReceiver that triggers when shift end alarm fires
|
||||
* This works even when app is killed
|
||||
*
|
||||
* When app is killed, we directly call the API to create break log
|
||||
* since we can't reliably start Flutter engine
|
||||
*/
|
||||
class ShiftEndReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Log.d("ShiftEndReceiver", "🔔 Shift end alarm triggered at ${java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.US).format(java.util.Calendar.getInstance().time)}")
|
||||
|
||||
// ✅ CRITICAL: Acquire WakeLock to keep device awake during API call
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ShiftEndReceiver::WakeLock")
|
||||
wakeLock.acquire(60 * 1000L) // Hold for 60 seconds max
|
||||
|
||||
// Execute API call in background thread
|
||||
Thread {
|
||||
try {
|
||||
// Check if rider is still on duty
|
||||
val prefs: SharedPreferences = context.getSharedPreferences(
|
||||
"FlutterSharedPreferences",
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
|
||||
// ✅ Try multiple key formats (Flutter SharedPreferences uses "flutter." prefix)
|
||||
val onduty = prefs.getInt("flutter.onduty", 0)
|
||||
Log.d("ShiftEndReceiver", "Checking onduty: $onduty")
|
||||
|
||||
if (onduty != 1) {
|
||||
Log.d("ShiftEndReceiver", "Rider already offline (onduty=$onduty), skipping break log creation")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
// Get required IDs - try both flutter.userid and flutter.userId
|
||||
val userid = prefs.getInt("flutter.userid", 0).takeIf { it != 0 }
|
||||
?: prefs.getInt("flutter.userId", 0)
|
||||
val partnerid = prefs.getInt("flutter.partnerid", 0).takeIf { it != 0 }
|
||||
?: prefs.getInt("flutter.partnerId", 0)
|
||||
val shiftid = prefs.getInt("flutter.shiftid", 0).takeIf { it != 0 }
|
||||
?: prefs.getInt("flutter.shiftId", 0)
|
||||
val logid = prefs.getInt("flutter.logid", 0).takeIf { it != 0 }
|
||||
?: prefs.getInt("flutter.logId", 0)
|
||||
|
||||
Log.d("ShiftEndReceiver", "Retrieved IDs: userid=$userid, partnerid=$partnerid, shiftid=$shiftid, logid=$logid")
|
||||
|
||||
if (userid == 0) {
|
||||
Log.e("ShiftEndReceiver", "❌ Missing userid, cannot create break log. Available keys: ${prefs.all.keys}")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
// Get API base URL (check if live or dev)
|
||||
// ✅ Match homepage logic: use createbreaklog (not createbreakriderlog)
|
||||
val mainRoute = prefs.getString("flutter.mainRoute", "dev") ?: "dev"
|
||||
val isLive = mainRoute == "live"
|
||||
Log.d("ShiftEndReceiver", "API Route: $mainRoute (isLive=$isLive)")
|
||||
val baseUrl = if (isLive) {
|
||||
"https://jupiter.doormile.app/live/api/v2/partners/createbreaklog"
|
||||
} else {
|
||||
"https://jupiter.doormile.app/dev/api/v2/partners/createbreaklog"
|
||||
}
|
||||
|
||||
// Create break log payload
|
||||
val now = Calendar.getInstance()
|
||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
|
||||
val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.US)
|
||||
val breakdate = dateFormat.format(now.time)
|
||||
val breakstart = timeFormat.format(now.time)
|
||||
val localBreakId = (System.currentTimeMillis() % 900).toInt() + 100
|
||||
|
||||
// ✅ Compact JSON (no extra whitespace) - matches Flutter format
|
||||
val payload = """{"breakid":$localBreakId,"logid":$logid,"breakdate":"$breakdate","userid":$userid,"partnerid":$partnerid,"shiftid":$shiftid,"breakstart":"$breakstart","breakend":"","breakhours":0.0,"latitude":"0","longitude":"0"}"""
|
||||
|
||||
Log.d("ShiftEndReceiver", "📤 Sending break log request to: $baseUrl")
|
||||
Log.d("ShiftEndReceiver", "📦 Payload: $payload")
|
||||
|
||||
// Make API call
|
||||
val url = URL(baseUrl)
|
||||
val connection = url.openConnection() as HttpURLConnection
|
||||
connection.requestMethod = "POST"
|
||||
connection.setRequestProperty("Content-Type", "application/json")
|
||||
connection.setRequestProperty("Accept", "application/json")
|
||||
connection.doOutput = true
|
||||
connection.doInput = true
|
||||
connection.useCaches = false
|
||||
connection.connectTimeout = 15000 // Increased timeout
|
||||
connection.readTimeout = 15000
|
||||
|
||||
Log.d("ShiftEndReceiver", "🔌 Connecting to API...")
|
||||
|
||||
// Write payload
|
||||
val outputStream = connection.outputStream
|
||||
val writer = OutputStreamWriter(outputStream, "UTF-8")
|
||||
writer.write(payload)
|
||||
writer.flush()
|
||||
writer.close()
|
||||
|
||||
Log.d("ShiftEndReceiver", "📨 Request sent, waiting for response...")
|
||||
|
||||
val responseCode = connection.responseCode
|
||||
Log.d("ShiftEndReceiver", "📥 Break log API response: HTTP $responseCode")
|
||||
|
||||
// Read response body for debugging
|
||||
try {
|
||||
val responseStream = if (responseCode in 200..299) {
|
||||
connection.inputStream
|
||||
} else {
|
||||
connection.errorStream
|
||||
}
|
||||
if (responseStream != null) {
|
||||
val responseBody = responseStream.bufferedReader().use { it.readText() }
|
||||
Log.d("ShiftEndReceiver", "📄 Response body: $responseBody")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.w("ShiftEndReceiver", "Could not read response body: ${e.message}")
|
||||
}
|
||||
|
||||
if (responseCode in 200..299) {
|
||||
Log.d("ShiftEndReceiver", "✅ Break log created successfully (HTTP $responseCode)")
|
||||
|
||||
// Set offline locally
|
||||
prefs.edit()
|
||||
.putInt("flutter.onduty", 0)
|
||||
.putBoolean("flutter.online", false)
|
||||
.apply()
|
||||
|
||||
// Also update rider log to set onduty=0
|
||||
val updateUrl = if (isLive) {
|
||||
"https://jupiter.doormile.app/live/api/v2/partners/updateriderlog"
|
||||
} else {
|
||||
"https://jupiter.doormile.app/dev/api/v2/partners/updateriderlog"
|
||||
}
|
||||
|
||||
// ✅ Compact JSON (no extra whitespace)
|
||||
val updatePayload = """{"userid":$userid,"onduty":0,"latitude":"0","longitude":"0"}"""
|
||||
|
||||
Log.d("ShiftEndReceiver", "📤 Updating rider status to offline")
|
||||
|
||||
try {
|
||||
val updateConnection = URL(updateUrl).openConnection() as HttpURLConnection
|
||||
updateConnection.requestMethod = "POST"
|
||||
updateConnection.setRequestProperty("Content-Type", "application/json")
|
||||
updateConnection.doOutput = true
|
||||
updateConnection.connectTimeout = 5000
|
||||
updateConnection.readTimeout = 5000
|
||||
|
||||
val updateWriter = OutputStreamWriter(updateConnection.outputStream, "UTF-8")
|
||||
updateWriter.write(updatePayload)
|
||||
updateWriter.flush()
|
||||
updateWriter.close()
|
||||
|
||||
if (updateConnection.responseCode in 200..299) {
|
||||
Log.d("ShiftEndReceiver", "✅ Rider status updated to Offline")
|
||||
}
|
||||
updateConnection.disconnect()
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "Error updating rider status: ${e.message}")
|
||||
}
|
||||
} else {
|
||||
// Read error response for debugging
|
||||
try {
|
||||
val errorStream = connection.errorStream
|
||||
if (errorStream != null) {
|
||||
val errorResponse = errorStream.bufferedReader().use { it.readText() }
|
||||
Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode\nError: $errorResponse")
|
||||
} else {
|
||||
Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "❌ Failed to create break log: HTTP $responseCode (Error reading response: ${e.message})")
|
||||
}
|
||||
}
|
||||
|
||||
connection.disconnect()
|
||||
|
||||
// ✅ CRITICAL: Reschedule alarm for tomorrow (so it works every day automatically)
|
||||
// This ensures the alarm fires every day at shift end time even if app is killed
|
||||
try {
|
||||
val endTimeStr = prefs.getString("flutter.endtime", "") ?: ""
|
||||
val startTimeStr = prefs.getString("flutter.starttime", "") ?: ""
|
||||
Log.d("ShiftEndReceiver", "Rescheduling alarm - endTime: $endTimeStr, startTime: $startTimeStr")
|
||||
|
||||
if (endTimeStr.isNotEmpty()) {
|
||||
// Schedule alarm for tomorrow at the same time
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val intent = Intent(context, ShiftEndReceiver::class.java).apply {
|
||||
action = "com.doormile.partner.SHIFT_END_ALARM"
|
||||
}
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context,
|
||||
1001,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val timeParts = endTimeStr.split(":")
|
||||
if (timeParts.size >= 2) {
|
||||
val endHour = timeParts[0].toIntOrNull() ?: 0
|
||||
val endMinute = timeParts[1].toIntOrNull() ?: 0
|
||||
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
add(Calendar.DAY_OF_MONTH, 1) // Tomorrow
|
||||
set(Calendar.HOUR_OF_DAY, endHour)
|
||||
set(Calendar.MINUTE, endMinute)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
||||
if (alarmManager.canScheduleExactAlarms()) {
|
||||
alarmManager.setExactAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
|
||||
} else {
|
||||
alarmManager.setAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
alarmManager.setExactAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
alarmManager.setExact(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "Error rescheduling alarm: ${e.message}", e)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "❌ Error handling shift end: ${e.message}", e)
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
// ✅ CRITICAL: Release WakeLock in finally block
|
||||
try {
|
||||
if (wakeLock.isHeld) {
|
||||
wakeLock.release()
|
||||
Log.d("ShiftEndReceiver", "🔓 WakeLock released")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "Error releasing WakeLock: ${e.message}")
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
}
|
||||
package com.doormile.partner
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* BroadcastReceiver that triggers when shift end alarm fires
|
||||
* This works even when app is killed
|
||||
*
|
||||
* When app is killed, we directly call the API to create break log
|
||||
* since we can't reliably start Flutter engine
|
||||
*/
|
||||
class ShiftEndReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Log.d("ShiftEndReceiver", "🔔 Shift end alarm triggered at ${java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss", java.util.Locale.US).format(java.util.Calendar.getInstance().time)}")
|
||||
|
||||
// ✅ CRITICAL: Acquire WakeLock to keep device awake during API call
|
||||
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "ShiftEndReceiver::WakeLock")
|
||||
wakeLock.acquire(60 * 1000L) // Hold for 60 seconds max
|
||||
|
||||
// Execute API call in background thread
|
||||
Thread {
|
||||
try {
|
||||
// Check if rider is still on duty
|
||||
val prefs: SharedPreferences = context.getSharedPreferences(
|
||||
"FlutterSharedPreferences",
|
||||
Context.MODE_PRIVATE
|
||||
)
|
||||
|
||||
// ✅ Try multiple key formats (Flutter SharedPreferences uses "flutter." prefix)
|
||||
val onduty = prefs.getInt("flutter.onduty", 0)
|
||||
Log.d("ShiftEndReceiver", "Checking onduty: $onduty")
|
||||
|
||||
if (onduty != 1) {
|
||||
Log.d("ShiftEndReceiver", "Rider already offline (onduty=$onduty), skipping break log creation")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
// Get required IDs - try both flutter.userid and flutter.userId
|
||||
val userid = prefs.getInt("flutter.userid", 0).takeIf { it != 0 }
|
||||
?: prefs.getInt("flutter.userId", 0)
|
||||
|
||||
if (userid == 0) {
|
||||
Log.e("ShiftEndReceiver", "❌ Missing userid, cannot create break log. Available keys: ${prefs.all.keys}")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
// ── v1, with the session, and no ids in the body ──
|
||||
//
|
||||
// This block hand-posted two legacy routes over HttpURLConnection:
|
||||
// partners/createbreaklog and partners/updateriderlog, on
|
||||
// the retired pre-v1 backend,
|
||||
// with `userid`, `partnerid`, `shiftid` and `logid` in the body and
|
||||
// NO Authorization header — an unauthenticated write keyed on ids
|
||||
// read out of SharedPreferences.
|
||||
//
|
||||
// The v1 equivalents key on the bearer token instead: the server
|
||||
// knows which rider the session names, so the ids are neither sent
|
||||
// nor needed. Same two effects, one host, one auth model as the
|
||||
// rest of the app.
|
||||
//
|
||||
// No token means no shift to end. That is the correct outcome —
|
||||
// a signed-out handset must not be able to close somebody's duty.
|
||||
val token = prefs.getString("flutter.authtoken", "") ?: ""
|
||||
if (token.isEmpty()) {
|
||||
Log.e("ShiftEndReceiver", "No session token; cannot end shift")
|
||||
return@Thread
|
||||
}
|
||||
|
||||
val breakOk = callV1(
|
||||
path = "/miler/breaks/start",
|
||||
method = "POST",
|
||||
token = token,
|
||||
body = """{"breaktype":"Shift_End"}"""
|
||||
)
|
||||
|
||||
if (breakOk) {
|
||||
Log.d("ShiftEndReceiver", "Break log created successfully")
|
||||
|
||||
prefs.edit()
|
||||
.putInt("flutter.onduty", 0)
|
||||
.putBoolean("flutter.online", false)
|
||||
.apply()
|
||||
|
||||
// `PUT /miler/duty/end` takes no body and closes whichever duty
|
||||
// log is open for the token's rider.
|
||||
if (callV1("/miler/duty/end", "PUT", token, null)) {
|
||||
Log.d("ShiftEndReceiver", "Rider status updated to Offline")
|
||||
}
|
||||
} else {
|
||||
Log.e("ShiftEndReceiver", "Failed to create break log")
|
||||
}
|
||||
|
||||
// ✅ CRITICAL: Reschedule alarm for tomorrow (so it works every day automatically)
|
||||
// This ensures the alarm fires every day at shift end time even if app is killed
|
||||
try {
|
||||
val endTimeStr = prefs.getString("flutter.endtime", "") ?: ""
|
||||
val startTimeStr = prefs.getString("flutter.starttime", "") ?: ""
|
||||
Log.d("ShiftEndReceiver", "Rescheduling alarm - endTime: $endTimeStr, startTime: $startTimeStr")
|
||||
|
||||
if (endTimeStr.isNotEmpty()) {
|
||||
// Schedule alarm for tomorrow at the same time
|
||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val intent = Intent(context, ShiftEndReceiver::class.java).apply {
|
||||
action = "com.doormile.partner.SHIFT_END_ALARM"
|
||||
}
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context,
|
||||
1001,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
val timeParts = endTimeStr.split(":")
|
||||
if (timeParts.size >= 2) {
|
||||
val endHour = timeParts[0].toIntOrNull() ?: 0
|
||||
val endMinute = timeParts[1].toIntOrNull() ?: 0
|
||||
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
add(Calendar.DAY_OF_MONTH, 1) // Tomorrow
|
||||
set(Calendar.HOUR_OF_DAY, endHour)
|
||||
set(Calendar.MINUTE, endMinute)
|
||||
set(Calendar.SECOND, 0)
|
||||
set(Calendar.MILLISECOND, 0)
|
||||
}
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
||||
if (alarmManager.canScheduleExactAlarms()) {
|
||||
alarmManager.setExactAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
|
||||
} else {
|
||||
alarmManager.setAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
alarmManager.setExactAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
alarmManager.setExact(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
}
|
||||
Log.d("ShiftEndReceiver", "✅ Rescheduled alarm for tomorrow: ${calendar.time}")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "Error rescheduling alarm: ${e.message}", e)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "❌ Error handling shift end: ${e.message}", e)
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
// ✅ CRITICAL: Release WakeLock in finally block
|
||||
try {
|
||||
if (wakeLock.isHeld) {
|
||||
wakeLock.release()
|
||||
Log.d("ShiftEndReceiver", "🔓 WakeLock released")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "Error releasing WakeLock: ${e.message}")
|
||||
}
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* One authenticated call to the v1 backend. Returns true on 2xx.
|
||||
*
|
||||
* The single place this file talks to a network, so there is one base URL,
|
||||
* one auth model and one timeout policy rather than a copy per endpoint.
|
||||
*/
|
||||
private fun callV1(path: String, method: String, token: String, body: String?): Boolean {
|
||||
var connection: HttpURLConnection? = null
|
||||
return try {
|
||||
connection = URL(V1_BASE + path).openConnection() as HttpURLConnection
|
||||
connection.requestMethod = method
|
||||
connection.setRequestProperty("Content-Type", "application/json")
|
||||
connection.setRequestProperty("Accept", "application/json")
|
||||
connection.setRequestProperty("Authorization", "Bearer $token")
|
||||
connection.connectTimeout = 15000
|
||||
connection.readTimeout = 15000
|
||||
if (body != null) {
|
||||
connection.doOutput = true
|
||||
OutputStreamWriter(connection.outputStream, "UTF-8").use {
|
||||
it.write(body)
|
||||
it.flush()
|
||||
}
|
||||
}
|
||||
val code = connection.responseCode
|
||||
Log.d("ShiftEndReceiver", "$method $path -> HTTP $code")
|
||||
code in 200..299
|
||||
} catch (e: Exception) {
|
||||
Log.e("ShiftEndReceiver", "$method $path failed: ${e.message}")
|
||||
false
|
||||
} finally {
|
||||
connection?.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** The one backend this app talks to. */
|
||||
private const val V1_BASE = "https://api.doormile.com/api/v1"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user