Commit 3713c2ba authored by Andreas Schildbach's avatar Andreas Schildbach
Browse files

Implement rough cut of background job.

It currently flashes a rocket LED, but in future should update the card10 clock.
parent 540d73b6
......@@ -38,4 +38,5 @@ dependencies {
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.squareup.okhttp3:okhttp:4.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation 'androidx.work:work-runtime-ktx:2.1.0'
}
......@@ -23,14 +23,18 @@
package de.ccc.events.badge.card10
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import de.ccc.events.badge.card10.background.SetClockJob
import de.ccc.events.badge.card10.installer.InstallerFragment
import de.ccc.events.badge.card10.mood.MoodFragment
import de.ccc.events.badge.card10.scanner.ScannerFragment
import java.util.concurrent.TimeUnit
class MainActivity : AppCompatActivity() {
......@@ -67,10 +71,23 @@ class MainActivity : AppCompatActivity() {
if (intent.action == "application/x.card10.app")
fragment = InstallerFragment()
else
fragment = MoodFragment()
fragment = ScannerFragment()
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()
}
val workManager = WorkManager.getInstance()
if (!BluetoothAdapter
.getDefaultAdapter().bondedDevices.isEmpty()
) {
val setClockRequest =
PeriodicWorkRequestBuilder<SetClockJob>(1, TimeUnit.MINUTES)
.build()
workManager
.enqueue(setClockRequest)
} else {
// TODO cancel job
}
}
}
/*
* Copyright by the original author or authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package de.ccc.events.badge.card10.background
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Context
import androidx.work.Worker
import androidx.work.WorkerParameters
import de.ccc.events.badge.card10.CARD10_SERVICE_UUID
import de.ccc.events.badge.card10.ROCKETS_CHARACTERISTIC_UUID
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
class SetClockJob(context: Context, workerParameters: WorkerParameters) : Worker(context, workerParameters) {
private val bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
override fun doWork(): Result {
System.out.println("=== doWork() job started")
for (device in bluetoothAdapter.bondedDevices) {
System.out.println("=== doWork() ${device}")
var gatt: BluetoothGatt? = null
try {
val gattLatch = CountDownLatch(1);
var writeLatch: CountDownLatch? = null
var rocketsCharacteristic: BluetoothGattCharacteristic? = null
val callback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
System.out.println("=== doWork() onConnectionStateChange " + gatt + " / " + status + " / " + newState)
if (newState == BluetoothGatt.STATE_CONNECTED)
gatt.discoverServices()
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
System.out.println("=== doWork() onServicesDiscovered " + gatt + " / " + status)
val card10Service = gatt.getService(CARD10_SERVICE_UUID)
rocketsCharacteristic = card10Service.getCharacteristic(ROCKETS_CHARACTERISTIC_UUID)
gattLatch.countDown()
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic?,
status: Int
) {
writeLatch?.countDown()
}
}
val gatt = device.connectGatt(applicationContext, true, callback)
if (!gattLatch.await(1, TimeUnit.MINUTES))
return Result.retry()
// TODO at this point update the clock, rather than blinking the LED
rocketsCharacteristic?.value = ubyteArrayOf(0x00u, 0xffu).toByteArray()
if (gatt.writeCharacteristic(rocketsCharacteristic)) {
writeLatch = CountDownLatch(1)
if (!writeLatch.await(1, TimeUnit.MINUTES))
return Result.failure()
System.out.println("=== doWork() rocket flash on")
}
Thread.sleep(1000)
rocketsCharacteristic?.value = ubyteArrayOf(0x00u, 0x00u).toByteArray()
if (gatt.writeCharacteristic(rocketsCharacteristic)) {
writeLatch = CountDownLatch(1)
if (!writeLatch.await(1, TimeUnit.MINUTES))
return Result.failure()
System.out.println("=== doWork() rocket flash off")
}
} catch (x: Exception) {
x.printStackTrace()
} finally {
gatt?.close();
System.out.println("=== doWork() job finished")
}
}
return Result.success()
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment