Commit 4af23216 authored by Andreas Schildbach's avatar Andreas Schildbach
Browse files

UI for Mood selection.

Again, an extremely rough cut.
parent 5e7ffb78
/*
* Copyright by the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.ccc.events.badge.card10
import java.util.*
val GENERIC_ACCESS_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")
val DEVICE_NAME_CHARACTERISTIC_UUID = UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb")
val CARD10_SERVICE_UUID = UUID.fromString("0000f000-2342-2342-2342-234223422342")
val VIBRA_CHARACTERISTIC_UUID = UUID.fromString("0000f10f-2342-2342-2342-234223422342")
val ROCKETS_CHARACTERISTIC_UUID = UUID.fromString("0000f110-2342-2342-2342-234223422342")
val SINGLE_LED_CHARACTERISTIC_UUID = UUID.fromString("0000f111-2342-2342-2342-234223422342")
......@@ -17,82 +17,20 @@
package de.ccc.events.badge.card10
import android.Manifest
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
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.*
class MainActivity : AppCompatActivity() {
private val REMOTE_DEVICE_BLUETOOTH_MAC = "00:05:8B:44:02:02"
private val GENERIC_ACCESS_SERVICE_UUID = UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")
private val DEVICE_NAME_CHARACTERISTIC_UUID = UUID.fromString("00002a00-0000-1000-8000-00805f9b34fb")
private var gatt: BluetoothGatt? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val remoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_BLUETOOTH_MAC)
val callback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
System.out.println("===== onConnectionStateChange " + gatt + " / " + status + " / " + newState)
if (newState == BluetoothGatt.STATE_CONNECTED)
gatt.discoverServices()
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
System.out.println("===== onServicesDiscovered " + gatt + " / " + status)
val services = gatt.getServices()
for (service in services) {
System.out.println(service.uuid.toString() + " / " + service.type + " / " + service.characteristics)
}
val genericAccessService = gatt.getService(GENERIC_ACCESS_SERVICE_UUID)
System.out.println("===================== " + genericAccessService)
for (c in genericAccessService.characteristics) {
System.out.println(c.uuid.toString() + " / " + c.value + " / " + c.writeType + " / " + c.properties)
}
val deviceNameCharacteristic = genericAccessService.getCharacteristic(DEVICE_NAME_CHARACTERISTIC_UUID)
val init = gatt.readCharacteristic(deviceNameCharacteristic)
if (!init)
System.out.println("Failed to initiate reading GATT attribute")
}
override fun onCharacteristicRead(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
System.out.println("===== onCharacteristicRead " + characteristic.uuid.toString() + " / " + characteristic.getStringValue(0) + " / " + status)
characteristic.setValue("pink")
val init = gatt.writeCharacteristic(characteristic)
if (!init)
System.out.println("Failed to initiate writing GATT attribute")
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
System.out.println("===== onCharacteristicWrite " + characteristic.uuid.toString() + " / " + characteristic.value + " / " + status)
}
}
gatt = remoteDevice.connectGatt(this, false, callback)
val permission = ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
......@@ -116,11 +54,6 @@ class MainActivity : AppCompatActivity() {
}
}
override fun onDestroy() {
gatt?.close();
super.onDestroy()
}
fun permissionGranted() {
var fragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
if (fragment == null) {
......@@ -128,7 +61,7 @@ class MainActivity : AppCompatActivity() {
if (intent.action == "application/x.card10.app")
fragment = InstallerFragment()
else
fragment = ScannerFragment()
fragment = MoodFragment()
supportFragmentManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit()
......
/*
* Copyright by the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.ccc.events.badge.card10.mood
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothGattCharacteristic
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import de.ccc.events.badge.card10.CARD10_SERVICE_UUID
import de.ccc.events.badge.card10.R
import de.ccc.events.badge.card10.ROCKETS_CHARACTERISTIC_UUID
import kotlinx.android.synthetic.main.mood_fragment.*
import java.util.concurrent.CountDownLatch
class MoodFragment : Fragment() {
// TODO pick from list of paired card10s, possibly present selection
private val REMOTE_DEVICE_BLUETOOTH_MAC = "00:05:8B:44:02:03"
private lateinit var gatt: BluetoothGatt
private var rocketsCharacteristic: BluetoothGattCharacteristic? = null
private var writeLatch: CountDownLatch? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val callback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
System.out.println("===== onConnectionStateChange " + gatt + " / " + status + " / " + newState)
if (newState == BluetoothGatt.STATE_CONNECTED)
gatt.discoverServices()
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
System.out.println("===== onServicesDiscovered " + gatt + " / " + status)
val card10Service = gatt.getService(CARD10_SERVICE_UUID)
rocketsCharacteristic = card10Service.getCharacteristic(ROCKETS_CHARACTERISTIC_UUID)
}
override fun onCharacteristicWrite(
gatt: BluetoothGatt,
characteristic: BluetoothGattCharacteristic,
status: Int
) {
System.out.println("===== onCharacteristicWrite " + characteristic.uuid.toString() + " / " + characteristic.value + " / " + status)
writeLatch?.countDown();
}
}
val remoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(REMOTE_DEVICE_BLUETOOTH_MAC)
gatt = remoteDevice.connectGatt(activity, false, callback)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.mood_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mood_good.setOnClickListener({
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x00u, 0xffu).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x01u, 0x00u).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x02u, 0x00u).toByteArray())
})
mood_neutral.setOnClickListener({
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x00u, 0x00u).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x01u, 0xffu).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x02u, 0x00u).toByteArray())
})
mood_bad.setOnClickListener({
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x00u, 0x00u).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x01u, 0x00u).toByteArray())
writeGatt(rocketsCharacteristic!!, ubyteArrayOf(0x02u, 0xffu).toByteArray())
})
}
fun writeGatt(characteristic: BluetoothGattCharacteristic, values: ByteArray) {
characteristic.value = values
val init = gatt.writeCharacteristic(rocketsCharacteristic)
if (!init)
System.out.println("Failed to initiate writing GATT attribute")
writeLatch = CountDownLatch(1)
writeLatch!!.await();
}
override fun onDestroy() {
gatt.close();
super.onDestroy()
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:padding="16dp"
>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Mood"/>
<Button android:id="@+id/mood_good" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Good"/>
<Button android:id="@+id/mood_neutral" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Neutral"/>
<Button android:id="@+id/mood_bad" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="Bad"/>
</LinearLayout>
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