update
This commit is contained in:
@@ -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>
|
||||||
@@ -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()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -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?)
|
||||||
}
|
}
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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"
|
||||||
|
|||||||
12
gradle/wrapper/gradle-wrapper.properties
vendored
12
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
178
gradlew.bat
vendored
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user