This commit is contained in:
2025-01-04 15:46:02 +01:00
parent 09b3ec6d68
commit d854b5ceec
9 changed files with 1008 additions and 951 deletions

View File

@@ -1,47 +1,47 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.oilcheckkotlin"> package="com.example.oilcheckkotlin">
<!-- for Android below 12 start --> <!-- for Android below 12 start -->
<uses-permission android:name="android.permission.BLUETOOTH" <uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" /> android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" /> android:maxSdkVersion="30" />
<!-- for Android below 12 end --> <!-- for Android below 12 end -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" /> <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<!-- android:icon="@mipmap/ic_launcher"--> <!-- android:icon="@mipmap/ic_launcher"-->
<!-- android:roundIcon="@mipmap/ic_launcher_round"--> <!-- android:roundIcon="@mipmap/ic_launcher_round"-->
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/draw_icon_blue" android:icon="@drawable/draw_icon_blue"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.OilCheckKotlin"> android:theme="@style/Theme.OilCheckKotlin">
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"> android:exported="true">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<service android:name=".BLEConnectionService"></service> <service android:name=".BLEConnectionService"></service>
<service android:name=".NLService" <service android:name=".NLService"
android:exported="true" android:exported="true"
android:enabled="true" android:enabled="true"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" > android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter> <intent-filter>
<action android:name="android.service.notification.NotificationListenerService" /> <action android:name="android.service.notification.NotificationListenerService" />
</intent-filter> </intent-filter>
</service> </service>
</application> </application>
</manifest> </manifest>

View File

@@ -1,209 +1,233 @@
package com.example.oilcheckkotlin package com.example.oilcheckkotlin
import android.app.Notification import android.app.Notification
import android.app.NotificationChannel import android.app.NotificationChannel
import android.app.NotificationManager import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.app.Service import android.app.Service
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color import android.graphics.Color
import android.location.LocationManager import android.location.LocationManager
import android.os.Build import android.os.Build
import android.os.IBinder import android.os.IBinder
import android.util.Log import android.util.Log
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.location.LocationManagerCompat import androidx.core.location.LocationManagerCompat
class BLEConnectionService : Service() { class BLEConnectionService : Service() {
val CHANNEL_DEFAULT_IMPORTANCE = "1" val CHANNEL_DEFAULT_IMPORTANCE = "1"
val ONGOING_NOTIFICATION_ID = 2 val ONGOING_NOTIFICATION_ID = 2
var bleController: BLEController? = null var bleController: BLEController? = null
var deviceAddress: String? = null var deviceAddress: String? = null
var nlService = NLService() var nlService = NLService()
private val myThread = Thread { private val myThread = Thread {
while (true){ while (true){
Log.d("Runnable", "Working") Log.d("Runnable", "Working")
if(bleController == null) { if(bleController == null) {
val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager val lm = getSystemService(Context.LOCATION_SERVICE) as LocationManager
if (!LocationManagerCompat.isLocationEnabled(lm)) { if (!LocationManagerCompat.isLocationEnabled(lm)) {
// Start Location Settings Activity, you should explain to the user why he need to enable location before. // Start Location Settings Activity, you should explain to the user why he need to enable location before.
startActivity(Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS)) startActivity(Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS))
} }
Log.d("Debug", "bleController null") Log.d("Debug", "bleController null")
// bleController = BLEController.getInstance(applicationContext) bleController = BLEController(applicationContext)
bleController = BLEController(applicationContext) if(!bleController!!.isConnected()){
bleController!!.init()
} else if(!bleController!!.isConnected()){ }
// not connected
Log.d("Debug", "bleController not null but not connected") } else if(!bleController!!.isConnected()){
bleController!!.init() // not connected
Log.d("Debug", "tried to init ble controller") Log.d("Debug", "bleController not null but not connected")
} else{ bleController!!.init()
// controller is connected Log.d("Debug", "tried to init ble controller")
Log.d("Debug", "BLE device connected") } else{
bleController!!.stopScanner() // controller is connected
Log.d("Debug", "BLE device connected")
bleController!!.stopScanner()
}
Thread.sleep(12000)
} }
} Thread.sleep(12000)
override fun onCreate() { }
super.onCreate() }
override fun onCreate() {
} super.onCreate()
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { }
if(intent?.action.equals("STARTService")){ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("DEBUG", "Startflag set") Log.d("DEBUG", "onStartCommand of BLE Connection Service")
myThread.start()
if(intent?.action.equals("STARTService")){
// setup ble connection Log.d("DEBUG", "Startflag set")
val channel_id = try {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ myThread.start()
createNotificationChannel("my_service", "My Background Service") }
} else { catch (e: Exception){
"" Log.d("DEBUG", "tried to start Thread, but failed :(")
} }
val serviceIntent: PendingIntent = Intent(this, BLEConnectionService::class.java).let { notificationIntent -> // setup ble connection
PendingIntent.getActivity(this, 0, notificationIntent, val channel_id =
PendingIntent.FLAG_IMMUTABLE) if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
} createNotificationChannel("my_service", "My Background Service")
val myIntent = Intent(this, MainActivity::class.java).apply { } else {
var flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK ""
} }
val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_IMMUTABLE) val serviceIntent: PendingIntent = Intent(this, BLEConnectionService::class.java).let { notificationIntent ->
val notification: Notification = Notification.Builder(this, channel_id) PendingIntent.getActivity(this, 0, notificationIntent,
.setContentTitle("Oil-Check") PendingIntent.FLAG_IMMUTABLE)
.setContentText("running") }
.setSmallIcon(R.drawable.icon) val myIntent = Intent(this, MainActivity::class.java).apply {
.setContentIntent(serviceIntent) var flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
// .setTicker(getText(R.string.ticker_text)) }
.build()
val activityIntent = Intent(this, MainActivity::class.java)
startForeground(101, notification)
// val contentIntent: PendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_IMMUTABLE)
// startService(Intent(this, NLService::class.java)
// .setAction("StartNLService") val contentIntent = PendingIntent.getActivity(this, 0, activityIntent, PendingIntent.FLAG_MUTABLE);
// ) // create stop button
val nlServiceIntent: PendingIntent = Intent(this, NLService::class.java).let { notificationIntent -> // val intent = Intent(this, BLEConnectionService::class.java)
PendingIntent.getActivity(this, 0, notificationIntent, // .setAction("STOPService")
PendingIntent.FLAG_IMMUTABLE) // val stopIntent = PendingIntent.getBroadcast(this, 0, intent, 0)
}
val nlNotification: Notification = Notification.Builder(this, channel_id)
.setContentTitle("Oil-Check") val notification: Notification = Notification.Builder(this, channel_id)
.setContentText("running") .setContentTitle("Oil-Check")
.setSmallIcon(R.drawable.icon) .setContentText("running")
.setContentIntent(nlServiceIntent) .setSmallIcon(R.drawable.icon)
// .setTicker(getText(R.string.ticker_text)) .setContentIntent(serviceIntent)
.build() // .setContentIntent(contentIntent)
startForeground(101, nlNotification) // .setTicker(getText(R.string.ticker_text))
// .addAction(R.drawable.icon, "Stop", contentIntent)
.build()
startForeground(101, notification)
// setup notification listener
// val nlServiceIntent: PendingIntent = Intent(this, NLService::class.java).let { notificationIntent -> // startService(Intent(this, NLService::class.java)
// PendingIntent.getActivity(this, 0, notificationIntent, // .setAction("StartNLService")
// PendingIntent.FLAG_IMMUTABLE) // )
// }
//
// val nlNotification: Notification = Notification.Builder(this, channel_id) val nlServiceIntent: PendingIntent = Intent(this, NLService::class.java).let { notificationIntent ->
// .setContentTitle("Oil-Check") PendingIntent.getActivity(this, 0, notificationIntent,
// .setContentText("running") PendingIntent.FLAG_IMMUTABLE)
// .setSmallIcon(R.drawable.icon) }
// .setContentIntent(nlServiceIntent)
//// .setTicker(getText(R.string.ticker_text)) val nlNotification: Notification = Notification.Builder(this, channel_id)
// .build() .setContentTitle("Oil-Check")
// startForeground(101, nlNotification) .setContentText("running")
.setSmallIcon(R.drawable.icon)
.setContentIntent(nlServiceIntent)
} else if (intent?.action.equals("STOPService")){ // .addAction(R.drawable.icon, "Stop", contentIntent)
Log.d("DEBUG", "Stopflag set") // .setTicker(getText(R.string.ticker_text))
stopForeground(true) .build()
stopSelfResult(101) startForeground(101, nlNotification)
stopSelf()
} else if (intent?.action.equals("StartNLService")) {
//
} // setup notification listener
else if(intent?.action.equals("Toggle")){ // val nlServiceIntent: PendingIntent = Intent(this, NLService::class.java).let { notificationIntent ->
try { // PendingIntent.getActivity(this, 0, notificationIntent,
bleController!!.sendData("X".toByteArray(Charsets.UTF_8)) // PendingIntent.FLAG_IMMUTABLE)
} // }
catch (e: Exception){ //
Log.d("Debug", "tried to toggle, but failed") // val nlNotification: Notification = Notification.Builder(this, channel_id)
} // .setContentTitle("Oil-Check")
} else if(intent?.action.equals("X")){ // .setContentText("running")
try { // .setSmallIcon(R.drawable.icon)
bleController!!.sendData("X".toByteArray(Charsets.UTF_8)) // .setContentIntent(nlServiceIntent)
} //// .setTicker(getText(R.string.ticker_text))
catch (e: Exception){ // .build()
Log.d("Debug", "Tried to send X, but connection failed") // startForeground(101, nlNotification)
}
} else if(intent?.action.equals("XX")){
try { } else if (intent?.action.equals("STOPService")){
bleController!!.sendData("XX".toByteArray(Charsets.UTF_8)) Log.d("DEBUG", "Stopflag set")
} stopForeground(true)
catch (e: Exception){ stopSelfResult(101)
Log.d("Debug", "Tried to send XX, but connection failed") stopSelf()
}
} else if(intent?.action.equals("XXX")){ } else if (intent?.action.equals("StartNLService")) {
try { //
bleController!!.sendData("XXX".toByteArray(Charsets.UTF_8)) }
} else if(intent?.action.equals("Toggle")){
catch (e: Exception){ try {
Log.d("Debug", "Tried to send XXX, but connection failed") bleController!!.sendData("XX".toByteArray(Charsets.UTF_8))
} }
} else if(intent?.action.equals("XXXX")){ catch (e: Exception){
try { Log.d("Debug", "tried to toggle, but failed")
bleController!!.sendData("XXXX".toByteArray(Charsets.UTF_8)) }
} } else if(intent?.action.equals("X")){
catch (e: Exception){ try {
Log.d("Debug", "Tried to send XXXX, but connection failed") bleController!!.sendData("X".toByteArray(Charsets.UTF_8))
} }
} else if(intent?.action.equals("OTA")) { catch (e: Exception){
try { Log.d("Debug", "Tried to send X, but connection failed")
bleController!!.sendData("U".toByteArray(Charsets.UTF_8)) }
} } else if(intent?.action.equals("XX")){
catch (e: Exception){ try {
Log.d("Debug", "Tried to update firmware, but connection failed") bleController!!.sendData("XX".toByteArray(Charsets.UTF_8))
} }
} catch (e: Exception){
else{ Log.d("Debug", "Tried to send XX, but connection failed")
Log.d("Debug", "Intent without arguments occured in service") }
} } else if(intent?.action.equals("XXX")){
try {
bleController!!.sendData("XXX".toByteArray(Charsets.UTF_8))
return START_STICKY }
} catch (e: Exception){
@RequiresApi(Build.VERSION_CODES.O) Log.d("Debug", "Tried to send XXX, but connection failed")
private fun createNotificationChannel(channelId: String, channelName: String): String{ }
val chan = NotificationChannel(channelId, } else if(intent?.action.equals("XXXX")){
channelName, NotificationManager.IMPORTANCE_NONE) try {
chan.lightColor = Color.BLUE bleController!!.sendData("XXXX".toByteArray(Charsets.UTF_8))
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE }
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager catch (e: Exception){
service.createNotificationChannel(chan) Log.d("Debug", "Tried to send XXXX, but connection failed")
return channelId }
} } else if(intent?.action.equals("OTA")) {
override fun onBind(p0: Intent?): IBinder? { try {
// TODO("Not yet implemented") bleController!!.sendData("U".toByteArray(Charsets.UTF_8))
return null; }
} catch (e: Exception){
Log.d("Debug", "Tried to update firmware, but connection failed")
override fun onDestroy() { }
super.onDestroy() }
this.myThread.interrupt() else{
Log.d("Debug", "Intent without arguments occured in service")
} }
return START_STICKY
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createNotificationChannel(channelId: String, channelName: String): String{
val chan = NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_NONE)
chan.lightColor = Color.BLUE
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
service.createNotificationChannel(chan)
return channelId
}
override fun onBind(p0: Intent?): IBinder? {
// TODO("Not yet implemented")
return null;
}
override fun onDestroy() {
super.onDestroy()
this.myThread.interrupt()
}
} }

View File

@@ -1,338 +1,380 @@
package com.example.oilcheckkotlin package com.example.oilcheckkotlin
import android.Manifest import android.Manifest
import android.bluetooth.BluetoothDevice import android.annotation.SuppressLint
import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothAdapter.LeScanCallback
import android.bluetooth.BluetoothGattCallback import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothGattCharacteristic import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothManager import android.bluetooth.BluetoothGattCallback
import android.bluetooth.BluetoothProfile import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.le.BluetoothLeScanner import android.bluetooth.BluetoothManager
import android.bluetooth.le.ScanCallback import android.bluetooth.BluetoothProfile
import android.bluetooth.le.ScanResult import android.bluetooth.le.BluetoothLeScanner
import android.content.Context import android.bluetooth.le.ScanCallback
import android.content.pm.PackageManager import android.bluetooth.le.ScanFilter
import android.os.Build import android.bluetooth.le.ScanResult
import android.util.Log import android.bluetooth.le.ScanSettings
import androidx.activity.result.contract.ActivityResultContracts import android.content.Context
import androidx.core.app.ActivityCompat import android.content.pm.PackageManager
import java.util.Locale import android.os.Build
import android.os.Handler
class BLEController(ctx: Context) : BLEControllerListener{ import android.os.Looper
companion object{ import android.util.Log
var instance: BLEController? = null import androidx.core.app.ActivityCompat
fun getInstance(ctx: Context?): BLEController? { import java.util.Locale
Log.d("BLEController", "called")
if (null == instance){
instance = BLEController(ctx!!) class BLEController(ctx: Context) : BLEControllerListener{
} companion object{
return instance var instance: BLEController? = null
} fun getInstance(ctx: Context?): BLEController? {
} Log.d("BLEController", "called")
private val SCAN_PERIOD: Long = 10000 if (null == instance){
instance = BLEController(ctx!!)
private var deviceAddress: String? = null }
return instance
var ctx: Context }
private var devices = hashMapOf<String, BluetoothDevice>() }
private var scanner: BluetoothLeScanner? = null private val SCAN_PERIOD: Long = 10000
var bluetoothManager: BluetoothManager? = null
private var btGattChar: BluetoothGattCharacteristic? = null private var deviceAddress: String? = null
private lateinit var bluetoothGatt: BluetoothGatt
private var device: BluetoothDevice? = null var ctx: Context
private val listeners: ArrayList<BLEControllerListener> = ArrayList<BLEControllerListener>() private var devices = hashMapOf<String, BluetoothDevice>()
private var connectionState = false private var scanner: BluetoothLeScanner? = null
var bluetoothManager: BluetoothManager? = null
fun stopScanner(){ private var btGattChar: BluetoothGattCharacteristic? = null
if (ActivityCompat.checkSelfPermission( private lateinit var bluetoothGatt: BluetoothGatt
ctx, private var device: BluetoothDevice? = null
Manifest.permission.BLUETOOTH_SCAN private val listeners: ArrayList<BLEControllerListener> = ArrayList<BLEControllerListener>()
) != PackageManager.PERMISSION_GRANTED private var connectionState = false
) { private var scanning = false
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding fun stopScanner(){
// public void onRequestPermissionsResult(int requestCode, String[] permissions, if (ActivityCompat.checkSelfPermission(
// int[] grantResults) ctx,
// to handle the case where the user grants the permission. See the documentation Manifest.permission.BLUETOOTH_SCAN
// for ActivityCompat#requestPermissions for more details. ) != PackageManager.PERMISSION_GRANTED
return ) {
} // TODO: Consider calling
try { // ActivityCompat#requestPermissions
scanner!!.stopScan(bleCallback) // here to request the missing permissions, and then overriding
} // public void onRequestPermissionsResult(int requestCode, String[] permissions,
catch (e: Exception){ // int[] grantResults)
Log.d("Debug", "Scanner seems to run, stopping") // to handle the case where the user grants the permission. See the documentation
} // for ActivityCompat#requestPermissions for more details.
} return
}
// constructor try {
init { scanner!!.stopScan(bleCallback)
Log.d("Debug", "constructor called") }
this.bluetoothManager = ctx.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager catch (e: Exception){
this.ctx = ctx Log.d("Debug", "Scanner seems to run, stopping")
} }
}
fun init(){
Log.d("Debug", "init") // constructor
this.devices?.clear() init {
Log.d("Debug", "get scanner") Log.d("Debug", "constructor called")
this.scanner = this.bluetoothManager?.adapter?.bluetoothLeScanner this.bluetoothManager = ctx.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
Log.d("Debug", "got scanner") this.ctx = ctx
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { }
if (ActivityCompat.checkSelfPermission(
ctx, fun init(){
Manifest.permission.BLUETOOTH_SCAN Log.d("Debug", "init")
) != PackageManager.PERMISSION_GRANTED this.devices?.clear()
) { Log.d("Debug", "get scanner")
// val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE) this.scanner = this.bluetoothManager?.adapter?.bluetoothLeScanner
// requestBluetooth.launch(enableBtIntent) Log.d("Debug", "got scanner")
Log.d("Debug", "permission needed") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// TODO: Consider calling if (ActivityCompat.checkSelfPermission(
// ActivityCompat#requestPermissions ctx,
// here to request the missing permissions, and then overriding Manifest.permission.BLUETOOTH_SCAN
// public void onRequestPermissionsResult(int requestCode, String[] permissions, ) != PackageManager.PERMISSION_GRANTED
// int[] grantResults) ) {
// to handle the case where the user grants the permission. See the documentation // val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
// for ActivityCompat#requestPermissions for more details. // requestBluetooth.launch(enableBtIntent)
return Log.d("Debug", "permission needed")
} else{ // TODO: Consider calling
Log.d("Debug", "permission granted") // ActivityCompat#requestPermissions
} // here to request the missing permissions, and then overriding
} // public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
Log.d("Debug", "try to scan") // to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
this.scanner?.startScan(bleCallback) return
} else{
} Log.d("Debug", "permission granted")
var bleCallback = object: ScanCallback(){ }
}
override fun onScanResult(callbackType: Int, result: ScanResult?) {
// Log.d("Debug", "onScanResult called") Log.d("Debug", "try to scan")
val device = result?.device
// Log.d("Debug", "device result exists") // this.scanner?.startScan(bleCallback)
if (!devices?.containsKey(device?.address)!! && isThisTheDevice(device)) { this.scanForDevice()
Log.d("Debug", "found the device") }
deviceFound(device!!)
Log.d("Debug", device.address) @SuppressLint("MissingPermission")
fun scanForDevice(){
Log.d("DEBUG", "SCAN for Device started")
} if(!scanning){
} Handler(Looper.getMainLooper()).postDelayed({
scanning = false
override fun onBatchScanResults(results: List<ScanResult?>?) { this.scanner?.stopScan(bleCallback)
Log.d("Debug", "onBatchScanResults called") }, SCAN_PERIOD)
for (sr in results!!) { Log.d("DEBUG", "nach Haendler")
val device = sr?.device scanning = true
if (!devices!!.containsKey(device!!.address) && isThisTheDevice(device)) {
deviceFound(device!!) val bleScanSettings =
} ScanSettings.Builder().setCallbackType((ScanSettings.CALLBACK_TYPE_FIRST_MATCH or ScanSettings.CALLBACK_TYPE_MATCH_LOST)).build()
}
} val filter = ScanFilter.Builder().setDeviceName("OilCheck").build()
//
override fun onScanFailed(errorCode: Int) {
Log.i("[BLE]", "scan failed with errorcode: $errorCode") val devFilter: MutableList<ScanFilter> = ArrayList()
} devFilter.add(filter)
}
private fun isThisTheDevice(device: BluetoothDevice?): Boolean { this.scanner?.startScan(devFilter, bleScanSettings, bleCallback)
try { }
if (ActivityCompat.checkSelfPermission( else{
ctx, scanning = false
Manifest.permission.BLUETOOTH_CONNECT this.scanner?.stopScan(bleCallback)
) != PackageManager.PERMISSION_GRANTED }
) { }
// TODO: Consider calling
// ActivityCompat#requestPermissions var bleCallback = object: ScanCallback(){
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions, override fun onScanResult(callbackType: Int, result: ScanResult?) {
// int[] grantResults) Log.d("Debug", "onScanResult called")
// to handle the case where the user grants the permission. See the documentation // val device = result?.device
// for ActivityCompat#requestPermissions for more details. val device = result?.getDevice()
return false // Log.d("Debug", "device result exists")
} if (!devices?.containsKey(device?.address)!! && isThisTheDevice(device)) {
Log.d("BLE", device!!.name) Log.d("Debug", "found the device")
} catch (e: Exception) { deviceFound(device!!)
Log.d("BLE", "Device with null-Name found") Log.d("Debug", device.address)
}
return null != device!!.name && device.name.startsWith("OilCheck")
} }
private fun deviceFound(device: BluetoothDevice) { }
Log.d("Debug", "deviceFound called")
// connectToDevice(device.address) override fun onBatchScanResults(results: List<ScanResult?>?) {
devices.put(device.address, device) Log.d("Debug", "onBatchScanResults called")
fireDeviceFound(device) for (sr in results!!) {
if (ActivityCompat.checkSelfPermission( val device = sr?.device
ctx, if (!devices!!.containsKey(device!!.address) && isThisTheDevice(device)) {
Manifest.permission.BLUETOOTH_SCAN deviceFound(device!!)
) != PackageManager.PERMISSION_GRANTED }
) { }
// TODO: Consider calling }
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding override fun onScanFailed(errorCode: Int) {
// public void onRequestPermissionsResult(int requestCode, String[] permissions, Log.i("[BLE]", "scan failed with errorcode: $errorCode")
// int[] grantResults) }
// to handle the case where the user grants the permission. See the documentation }
// for ActivityCompat#requestPermissions for more details. private fun isThisTheDevice(device: BluetoothDevice?): Boolean {
return try {
} if (ActivityCompat.checkSelfPermission(
scanner!!.stopScan(bleCallback) ctx,
} Manifest.permission.BLUETOOTH_CONNECT
private fun fireDeviceFound(device: BluetoothDevice) { ) != PackageManager.PERMISSION_GRANTED
// for (l in listeners) { ) {
if (ActivityCompat.checkSelfPermission( // TODO: Consider calling
ctx, // ActivityCompat#requestPermissions
Manifest.permission.BLUETOOTH_CONNECT // here to request the missing permissions, and then overriding
) != PackageManager.PERMISSION_GRANTED // public void onRequestPermissionsResult(int requestCode, String[] permissions,
) { // int[] grantResults)
// TODO: Consider calling // to handle the case where the user grants the permission. See the documentation
// ActivityCompat#requestPermissions // for ActivityCompat#requestPermissions for more details.
// here to request the missing permissions, and then overriding return false
// public void onRequestPermissionsResult(int requestCode, String[] permissions, }
// int[] grantResults) Log.d("BLE", device!!.name)
// to handle the case where the user grants the permission. See the documentation } catch (e: Exception) {
// for ActivityCompat#requestPermissions for more details. Log.d("BLE", "Device with null-Name found")
return }
} // return null != device!!.name && device.name.startsWith("OilCheck")
Log.d("Debug", "BLEDeviceFound called") // "94:B9:7E:C0:53:FE") debugger
BLEDeviceFound(device.name.trim { it <= ' ' }, device.address) // "30:83:98:00:89:86" KTM
// } return null != (device!!.address.startsWith("94:B9:7E:C0:53:FE")
} or device!!.address.startsWith("30:83:98:00:89:86"))
fun connectToDevice(address: String?) {
Log.d("Debug", "connectToDevice") }
this.device = devices[address!!] private fun deviceFound(device: BluetoothDevice) {
if (ActivityCompat.checkSelfPermission( Log.d("Debug", "deviceFound called")
ctx, // connectToDevice(device.address)
Manifest.permission.BLUETOOTH_SCAN devices.put(device.address, device)
) != PackageManager.PERMISSION_GRANTED fireDeviceFound(device)
) { if (ActivityCompat.checkSelfPermission(
// TODO: Consider calling ctx,
// ActivityCompat#requestPermissions Manifest.permission.BLUETOOTH_SCAN
// here to request the missing permissions, and then overriding ) != PackageManager.PERMISSION_GRANTED
// public void onRequestPermissionsResult(int requestCode, String[] permissions, ) {
// int[] grantResults) // TODO: Consider calling
// to handle the case where the user grants the permission. See the documentation // ActivityCompat#requestPermissions
// for ActivityCompat#requestPermissions for more details. // here to request the missing permissions, and then overriding
return // public void onRequestPermissionsResult(int requestCode, String[] permissions,
} // int[] grantResults)
scanner!!.stopScan(bleCallback) // to handle the case where the user grants the permission. See the documentation
try { // for ActivityCompat#requestPermissions for more details.
Log.i("[BLE]", "connect to device " + device!!.getAddress()) return
} catch (e: java.lang.Exception) { }
Log.d("Debug", "Connection to device failed :(") scanner!!.stopScan(bleCallback)
} }
this.bluetoothGatt = device!!.connectGatt(null, true, this.bleConnectCallback) private fun fireDeviceFound(device: BluetoothDevice) {
} // for (l in listeners) {
if (ActivityCompat.checkSelfPermission(
private val bleConnectCallback: BluetoothGattCallback = object : BluetoothGattCallback() { ctx,
val CHANNEL_ID = "ForegroundServiceChannel" Manifest.permission.BLUETOOTH_CONNECT
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { ) != PackageManager.PERMISSION_GRANTED
if (newState == BluetoothProfile.STATE_CONNECTED) { ) {
connectionState = true // TODO: Consider calling
Log.d("Debug", "connection state changed to connected") // ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
if (ActivityCompat.checkSelfPermission( // public void onRequestPermissionsResult(int requestCode, String[] permissions,
ctx, // int[] grantResults)
Manifest.permission.BLUETOOTH_CONNECT // to handle the case where the user grants the permission. See the documentation
) != PackageManager.PERMISSION_GRANTED // for ActivityCompat#requestPermissions for more details.
) { return
// TODO: Consider calling }
// ActivityCompat#requestPermissions Log.d("Debug", "BLEDeviceFound called")
// here to request the missing permissions, and then overriding BLEDeviceFound("device.name.trim { it <= ' ' }", device.address)
// public void onRequestPermissionsResult(int requestCode, String[] permissions, // }
// int[] grantResults) }
// to handle the case where the user grants the permission. See the documentation fun connectToDevice(address: String?) {
// for ActivityCompat#requestPermissions for more details. Log.d("Debug", "connectToDevice")
return this.device = devices[address!!]
} if (ActivityCompat.checkSelfPermission(
Log.i("[BLE]", "start service discovery " + bluetoothGatt.discoverServices()) ctx,
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) { Manifest.permission.BLUETOOTH_SCAN
connectionState = false ) != PackageManager.PERMISSION_GRANTED
) {
Log.d("Debug", "connection state changed to not connected") // TODO: Consider calling
btGattChar = null // ActivityCompat#requestPermissions
Log.w("[BLE]", "DISCONNECTED with status $status") // here to request the missing permissions, and then overriding
fireDisconnected() // public void onRequestPermissionsResult(int requestCode, String[] permissions,
} else { // int[] grantResults)
Log.i("[BLE]", "unknown state $newState and status $status") // to handle the case where the user grants the permission. See the documentation
} // for ActivityCompat#requestPermissions for more details.
} return
}
override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { scanner!!.stopScan(bleCallback)
if (null == btGattChar) { try {
for (service in gatt.services) { Log.i("[BLE]", "connect to device " + device!!.getAddress())
if (service.uuid.toString().uppercase(Locale.getDefault()) } catch (e: java.lang.Exception) {
.startsWith("00001811") Log.d("Debug", "Connection to device failed :(")
) { }
val gattCharacteristics = service.characteristics this.bluetoothGatt = device!!.connectGatt(null, true, this.bleConnectCallback)
for (bgc in gattCharacteristics) { }
if (bgc.uuid.toString().uppercase(Locale.getDefault())
.startsWith("00002A46") private val bleConnectCallback: BluetoothGattCallback = object : BluetoothGattCallback() {
) { val CHANNEL_ID = "ForegroundServiceChannel"
val chprop = bgc.properties override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
if (chprop and BluetoothGattCharacteristic.PROPERTY_WRITE or (chprop and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) { if (newState == BluetoothProfile.STATE_CONNECTED) {
btGattChar = bgc connectionState = true
Log.i("[BLE]", "CONNECTED and ready to send") Log.d("Debug", "connection state changed to connected")
fireConnected()
} if (ActivityCompat.checkSelfPermission(
} ctx,
} Manifest.permission.BLUETOOTH_CONNECT
} ) != PackageManager.PERMISSION_GRANTED
} ) {
} // TODO: Consider calling
} // ActivityCompat#requestPermissions
} // here to request the missing permissions, and then overriding
private fun fireDisconnected() { // public void onRequestPermissionsResult(int requestCode, String[] permissions,
for (l in listeners){ // int[] grantResults)
l.BLEControllerDisconnected() // to handle the case where the user grants the permission. See the documentation
} // for ActivityCompat#requestPermissions for more details.
device = null return
} }
fun isConnected():Boolean { Log.i("[BLE]", "start service discovery " + bluetoothGatt.discoverServices())
if(!connectionState){ } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
return false connectionState = false
}
return true Log.d("Debug", "connection state changed to not connected")
} btGattChar = null
fun sendData(data: ByteArray?) { Log.w("[BLE]", "DISCONNECTED with status $status")
btGattChar!!.value = data fireDisconnected()
if (ActivityCompat.checkSelfPermission( } else {
ctx, Log.i("[BLE]", "unknown state $newState and status $status")
Manifest.permission.BLUETOOTH_CONNECT }
) != PackageManager.PERMISSION_GRANTED }
) {
// TODO: Consider calling override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
// ActivityCompat#requestPermissions if (null == btGattChar) {
// here to request the missing permissions, and then overriding for (service in gatt.services) {
// public void onRequestPermissionsResult(int requestCode, String[] permissions, if (service.uuid.toString().uppercase(Locale.getDefault())
// int[] grantResults) .startsWith("00001811")
// to handle the case where the user grants the permission. See the documentation ) {
// for ActivityCompat#requestPermissions for more details. val gattCharacteristics = service.characteristics
return for (bgc in gattCharacteristics) {
} if (bgc.uuid.toString().uppercase(Locale.getDefault())
bluetoothGatt.writeCharacteristic(btGattChar) .startsWith("00002A46")
} ) {
private fun fireConnected() { val chprop = bgc.properties
for (l in listeners) { if (chprop and BluetoothGattCharacteristic.PROPERTY_WRITE or (chprop and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {
l.BLEControllerConnected() btGattChar = bgc
} Log.i("[BLE]", "CONNECTED and ready to send")
} fireConnected()
}
override fun BLEControllerConnected() { }
TODO("Not yet implemented") }
} }
}
override fun BLEControllerDisconnected() { }
TODO("Not yet implemented") }
} }
private fun fireDisconnected() {
override fun BLEDeviceFound(name: String?, address: String?) { for (l in listeners){
// log("Device $name found with address $address") l.BLEControllerDisconnected()
deviceAddress = address }
Log.d("Debug", "connectToDevice called") device = null
// btnConnect.setEnabled(true) }
connectToDevice(deviceAddress) fun isConnected():Boolean {
} if(!connectionState){
return false
}
return true
}
fun sendData(data: ByteArray?) {
btGattChar!!.value = data
if (ActivityCompat.checkSelfPermission(
ctx,
Manifest.permission.BLUETOOTH_CONNECT
) != PackageManager.PERMISSION_GRANTED
) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
bluetoothGatt.writeCharacteristic(btGattChar)
}
private fun fireConnected() {
for (l in listeners) {
l.BLEControllerConnected()
}
}
override fun BLEControllerConnected() {
TODO("Not yet implemented")
}
override fun BLEControllerDisconnected() {
TODO("Not yet implemented")
}
override fun BLEDeviceFound(name: String?, address: String?) {
deviceAddress = address
Log.d("Debug", "connectToDevice called")
// btnConnect.setEnabled(true)
connectToDevice(deviceAddress)
}
} }

View File

@@ -1,14 +1,14 @@
package com.example.oilcheckkotlin package com.example.oilcheckkotlin
/* /*
* (c) Matey Nenov (https://www.thinker-talk.com) * (c) Matey Nenov (https://www.thinker-talk.com)
* *
* Licensed under Creative Commons: By Attribution 3.0 * Licensed under Creative Commons: By Attribution 3.0
* http://creativecommons.org/licenses/by/3.0/ * http://creativecommons.org/licenses/by/3.0/
* *
*/ */
interface BLEControllerListener { interface BLEControllerListener {
fun BLEControllerConnected() fun BLEControllerConnected()
fun BLEControllerDisconnected() fun BLEControllerDisconnected()
fun BLEDeviceFound(name: String?, address: String?) fun BLEDeviceFound(name: String?, address: String?)
} }

View File

@@ -1,213 +1,213 @@
package com.example.oilcheckkotlin package com.example.oilcheckkotlin
import android.app.Notification import android.app.Notification
import android.content.Intent import android.content.Intent
import android.os.IBinder import android.os.IBinder
import android.service.notification.NotificationListenerService import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification import android.service.notification.StatusBarNotification
import android.util.Log import android.util.Log
import java.util.regex.Pattern import java.util.regex.Pattern
class NLService : NotificationListenerService() { class NLService : NotificationListenerService() {
// override fun onBind(intent: Intent?): IBinder? { // override fun onBind(intent: Intent?): IBinder? {
// return super.onBind(intent) // return super.onBind(intent)
// } // }
// //
// override fun onNotificationPosted(sbn: StatusBarNotification?) { // override fun onNotificationPosted(sbn: StatusBarNotification?) {
// // Implement what you want here // // Implement what you want here
// } // }
// //
// override fun onNotificationRemoved(sbn: StatusBarNotification?) { // override fun onNotificationRemoved(sbn: StatusBarNotification?) {
// // Implement what you want here // // Implement what you want here
// } // }
// //
// private final IBinder mBinder = new LocalBinder(); // private final IBinder mBinder = new LocalBinder();
override fun onBind(intent: Intent): IBinder? { override fun onBind(intent: Intent): IBinder? {
return super.onBind(intent) return super.onBind(intent)
} }
//returns the instance of the service //returns the instance of the service
// public class LocalBinder extends Binder{ // public class LocalBinder extends Binder{
// public NLService getServiceInstance(){ // public NLService getServiceInstance(){
// return NLService.this; // return NLService.this;
// } // }
// } // }
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
Log.d("Debug: ", "BLE service onStartCommand called") Log.d("Debug: ", "BLE service onStartCommand called")
// // String input = intent.getStringExtra("inputExtra"); // // String input = intent.getStringExtra("inputExtra");
// val input = "Text" // val input = "Text"
// createNotificationChannel() // createNotificationChannel()
// val notificationIntent = Intent(this, MainActivity::class.java) // val notificationIntent = Intent(this, MainActivity::class.java)
// val pendingIntent = PendingIntent.getActivity( // val pendingIntent = PendingIntent.getActivity(
// this, // this,
// 0, notificationIntent, 0 // 0, notificationIntent, 0
// ) // )
// val notification = NotificationCompat.Builder(this, CHANNEL_ID) // val notification = NotificationCompat.Builder(this, CHANNEL_ID)
// .setContentTitle("Oil Check") // .setContentTitle("Oil Check")
// .setContentText(input) //.setSmallIcon(R.drawable.ic_launcher_foreground) // .setContentText(input) //.setSmallIcon(R.drawable.ic_launcher_foreground)
// .setSmallIcon(R.drawable.icon) // .setSmallIcon(R.drawable.icon)
// .setContentIntent(pendingIntent) // .setContentIntent(pendingIntent)
// .build() // .build()
// startForeground(1, notification) // startForeground(1, notification)
// // NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); // // NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
//// notificationManager.notify(3, notification); //// notificationManager.notify(3, notification);
// try { // try {
// bleController = BLEController.getInstance(applicationContext) // bleController = BLEController.getInstance(applicationContext)
// Log.d("BLE", "bleController instance") // Log.d("BLE", "bleController instance")
// } catch (e: Exception) { // } catch (e: Exception) {
// Log.d("BLE", "bleController not available") // Log.d("BLE", "bleController not available")
// } // }
return START_NOT_STICKY return START_NOT_STICKY
} }
// private fun createNotificationChannel() { // private fun createNotificationChannel() {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// val serviceChannel = NotificationChannel( // val serviceChannel = NotificationChannel(
// CHANNEL_ID, // CHANNEL_ID,
// "Foreground Service Channel", // "Foreground Service Channel",
// NotificationManager.IMPORTANCE_DEFAULT // NotificationManager.IMPORTANCE_DEFAULT
// ) // )
// val manager = getSystemService( // val manager = getSystemService(
// NotificationManager::class.java // NotificationManager::class.java
// ) // )
// manager.createNotificationChannel(serviceChannel) // manager.createNotificationChannel(serviceChannel)
// } // }
// } // }
override fun onNotificationPosted(sbn: StatusBarNotification) { override fun onNotificationPosted(sbn: StatusBarNotification) {
Log.d("Debug", "NL Notification fired") Log.d("Debug", "NL Notification fired")
// Implement what you want here // Implement what you want here
if (sbn.packageName.contains("de.blitzer.plus")) { if (sbn.packageName.contains("de.blitzer.plus")) {
Log.d(sbn.packageName, "sbn.getTag()") Log.d(sbn.packageName, "sbn.getTag()")
Log.d("MyNotification", sbn.notification.toString()) Log.d("MyNotification", sbn.notification.toString())
// filter for digits // filter for digits
try { try {
val notification = val notification =
sbn.notification.extras.getCharSequence(Notification.EXTRA_TEXT).toString() sbn.notification.extras.getCharSequence(Notification.EXTRA_TEXT).toString()
// check of unit in m or km // check of unit in m or km
val unitM = "(.*)[\\d][m][\\s](.*)" val unitM = "(.*)[\\d][m][\\s](.*)"
val unitKm = "(.*)[\\d][k][m][\\s](.*)" val unitKm = "(.*)[\\d][k][m][\\s](.*)"
Log.d("Unit", unitM) Log.d("Unit", unitM)
if (notification.matches(unitM.toRegex())) { if (notification.matches(unitM.toRegex())) {
Log.d("Notification", "meter") Log.d("Notification", "meter")
Log.d("Notification", notification) Log.d("Notification", notification)
// notification in meters // notification in meters
// get digits // get digits
val pattern = Pattern.compile("[\\d]+[m][\\s]") val pattern = Pattern.compile("[\\d]+[m][\\s]")
val matcher = pattern.matcher(notification) val matcher = pattern.matcher(notification)
while (matcher.find()) { while (matcher.find()) {
Log.d("Matcher", "Match found") Log.d("Matcher", "Match found")
val start = matcher.start() val start = matcher.start()
val end = matcher.end() val end = matcher.end()
// Log.d("Start", ) // Log.d("Start", )
// end -2 (one for blank and one for unit(m)) // end -2 (one for blank and one for unit(m))
val digits = notification.substring(start, end - 2) val digits = notification.substring(start, end - 2)
Log.d("Matcher", digits) Log.d("Matcher", digits)
val distance = digits.toInt() val distance = digits.toInt()
Log.d("Distanz", digits) Log.d("Distanz", digits)
try { try {
if (distance > 500) { if (distance > 500) {
Log.d("Distanz", "groesser 500") Log.d("Distanz", "groesser 500")
val intent = Intent(this, BLEConnectionService::class.java) val intent = Intent(this, BLEConnectionService::class.java)
.setAction("X") .setAction("X")
startService(intent) startService(intent)
// bleController!!.sendData(String("X").toByteArray()) // bleController!!.sendData(String("X").toByteArray())
} else if (distance > 300) { } else if (distance > 300) {
Log.d("Distanz", "groesser 300") Log.d("Distanz", "groesser 300")
val intent = Intent(this, BLEConnectionService::class.java) val intent = Intent(this, BLEConnectionService::class.java)
.setAction("XX") .setAction("XX")
startService(intent) startService(intent)
} else if (distance > 150) { } else if (distance > 150) {
Log.d("Distanz", "groesser 150") Log.d("Distanz", "groesser 150")
val intent = Intent(this, BLEConnectionService::class.java) val intent = Intent(this, BLEConnectionService::class.java)
.setAction("XXX") .setAction("XXX")
startService(intent) startService(intent)
} else { } else {
Log.d("Distanz", "kleiner 100") Log.d("Distanz", "kleiner 100")
val intent = Intent(this, BLEConnectionService::class.java) val intent = Intent(this, BLEConnectionService::class.java)
.setAction("XXXX") .setAction("XXXX")
startService(intent) startService(intent)
} }
} catch (e: Exception) { } catch (e: Exception) {
// //
Log.d("DEBUG", "Send Data failed :(") Log.d("DEBUG", "Send Data failed :(")
} }
// end while loop after first match // end while loop after first match
break break
} }
} else if (notification.matches(unitKm.toRegex())) { } else if (notification.matches(unitKm.toRegex())) {
// notification in kilometers // notification in kilometers
// no need to differ, to much distance // no need to differ, to much distance
// bleController!!.sendData(String("X").toByteArray()) // bleController!!.sendData(String("X").toByteArray())
val intent = Intent(this, BLEConnectionService::class.java) val intent = Intent(this, BLEConnectionService::class.java)
.setAction("X") .setAction("X")
startService(intent) startService(intent)
} }
// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("nicht gefunden") || // else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("nicht gefunden") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("ungenau")){ // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("ungenau")){
// bleController.sendData(new String("XXXXX").getBytes()); // bleController.sendData(new String("XXXXX").getBytes());
// } // }
// else{ // else{
// bleController.sendData(new String("XXX").getBytes()); // bleController.sendData(new String("XXX").getBytes());
// } // }
} // old version not working anymore because of update of Blitzer.de } // old version not working anymore because of update of Blitzer.de
// try { // try {
// if (sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("1.0km") || // if (sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("1.0km") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("1000m")) { // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("1000m")) {
// bleController.sendData(new String("X").getBytes()); // bleController.sendData(new String("X").getBytes());
// } // }
// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("500m")){ // else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("500m")){
// bleController.sendData(new String("XX").getBytes()); // bleController.sendData(new String("XX").getBytes());
// } // }
// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("300m") || // else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("300m") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("200m")){ // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("200m")){
// bleController.sendData(new String("XXX").getBytes()); // bleController.sendData(new String("XXX").getBytes());
// } // }
// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("100m") || // else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("100m") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("90m") || // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("90m") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("80m") || // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("80m") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("70m") || // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("70m") ||
// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("50m")){ // sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("50m")){
// bleController.sendData(new String("XXXX").getBytes()); // bleController.sendData(new String("XXXX").getBytes());
// } // }
//// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("nicht gefunden") || //// else if(sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("nicht gefunden") ||
//// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("ungenau")){ //// sbn.getNotification().extras.getCharSequence(Notification.EXTRA_TEXT).toString().contains("ungenau")){
//// bleController.sendData(new String("XXXXX").getBytes()); //// bleController.sendData(new String("XXXXX").getBytes());
//// } //// }
//// else{ //// else{
//// bleController.sendData(new String("XXX").getBytes()); //// bleController.sendData(new String("XXX").getBytes());
//// } //// }
// } // }
catch (e: Exception) { catch (e: Exception) {
Log.d("DEBUG", "Send notification failed :(") Log.d("DEBUG", "Send notification failed :(")
} }
// try { // try {
// bleController.sendData(new String("X").getBytes()); // bleController.sendData(new String("X").getBytes());
// } // }
// catch(Exception e){ // catch(Exception e){
// //
// } // }
} }
// Log.d(sbn.getPackageName(), "packagename"); // Log.d(sbn.getPackageName(), "packagename");
} }
override fun onNotificationRemoved(sbn: StatusBarNotification) { override fun onNotificationRemoved(sbn: StatusBarNotification) {
// Implement what you want here // Implement what you want here
this.stopForeground(STOP_FOREGROUND_REMOVE) this.stopForeground(STOP_FOREGROUND_REMOVE)
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
Log.d("BLE:", "Service onDestory called") Log.d("BLE:", "Service onDestory called")
this.stopForeground(STOP_FOREGROUND_REMOVE) this.stopForeground(STOP_FOREGROUND_REMOVE)
stopForeground(true) stopForeground(true)
// stopSelf(); // stopSelf();
} }
companion object { companion object {
const val CHANNEL_ID = "ForegroundServiceChannel" const val CHANNEL_ID = "ForegroundServiceChannel"
} }
} }

View File

@@ -1,32 +1,32 @@
package com.example.oilcheckkotlin package com.example.oilcheckkotlin
import android.R import android.R
import android.app.Notification import android.app.Notification
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
class NotificationCreator { class NotificationCreator {
private val NOTIFICATION_ID = 1094 private val NOTIFICATION_ID = 1094
private val CHANNEL_ID = "Foreground Service Channel" private val CHANNEL_ID = "Foreground Service Channel"
private var notification: Notification? = null private var notification: Notification? = null
fun getNotification(context: Context?, intent: PendingIntent): Notification? { fun getNotification(context: Context?, intent: PendingIntent): Notification? {
if (notification == null) { if (notification == null) {
notification = NotificationCompat.Builder(context!!, CHANNEL_ID) notification = NotificationCompat.Builder(context!!, CHANNEL_ID)
.setContentTitle("Oil-Check") .setContentTitle("Oil-Check")
.setContentText("running") .setContentText("running")
.setSmallIcon(com.example.oilcheckkotlin.R.drawable.icon) .setSmallIcon(com.example.oilcheckkotlin.R.drawable.icon)
.setContentIntent(intent) .setContentIntent(intent)
.build() .build()
} }
return notification return notification
} }
fun getNotificationId(): Int { fun getNotificationId(): Int {
return NOTIFICATION_ID return NOTIFICATION_ID
} }
} }

View File

@@ -6,15 +6,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".MainActivity"> tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout <LinearLayout
android:layout_width="400dp" android:layout_width="400dp"
android:layout_height="257dp" android:layout_height="257dp"

View File

@@ -1,6 +1,6 @@
#Thu Aug 31 20:53:30 CEST 2023 #Thu Aug 31 20:53:30 CEST 2023
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

178
gradlew.bat vendored
View File

@@ -1,89 +1,89 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%" == "" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter. @rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1 exit /b 1
:mainEnd :mainEnd
if "%OS%"=="Windows_NT" endlocal if "%OS%"=="Windows_NT" endlocal
:omega :omega