Skip to content

Commit

Permalink
Merge pull request #350 from thgoebel/use-local-activity
Browse files Browse the repository at this point in the history
Refactor: avoid using global activity reference
  • Loading branch information
simondankelmann authored Jan 30, 2025
2 parents c948c59 + 1634e93 commit 5b25258
Show file tree
Hide file tree
Showing 15 changed files with 254 additions and 291 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import de.simon.dankelmann.bluetoothlespam.databinding.ListItemAdvertisementList
import de.simon.dankelmann.bluetoothlespam.databinding.ListItemAdvertisementSetBinding


class AdvertisementSetCollectionExpandableListViewAdapter internal constructor(
class AdvertisementSetCollectionExpandableListViewAdapter internal constructor(
private val context: Context,
val advertisementSetLists: List<AdvertisementSetList>,
val dataList: HashMap<AdvertisementSetList, List<AdvertisementSet>>
Expand Down Expand Up @@ -52,25 +52,25 @@ class AdvertisementSetCollectionExpandableListViewAdapter internal constructor(
holder = convertView.tag as ItemViewHolder
}

var advertisementSet = getChild(listPosition, expandedListPosition) as AdvertisementSet
val advertisementSet = getChild(listPosition, expandedListPosition) as AdvertisementSet

var textColor = when(advertisementSet.currentlyAdvertising){
true -> AppContext.getActivity().resources.getColor(R.color.blue_normal, AppContext.getContext().theme)
false -> AppContext.getActivity().resources.getColor(R.color.text_color, AppContext.getContext().theme)
var textColor = when (advertisementSet.currentlyAdvertising) {
true -> context.resources.getColor(R.color.blue_normal, context.theme)
false -> context.resources.getColor(R.color.text_color, context.theme)
}

if(advertisementSet.currentlyAdvertising){
if(advertisementSet.advertisementState == AdvertisementState.ADVERTISEMENT_STATE_SUCCEEDED){
textColor = AppContext.getActivity().resources.getColor(R.color.log_success, AppContext.getContext().theme)
} else if(advertisementSet.advertisementState == AdvertisementState.ADVERTISEMENT_STATE_FAILED){
textColor = AppContext.getActivity().resources.getColor(R.color.log_error, AppContext.getContext().theme)
if (advertisementSet.currentlyAdvertising) {
if (advertisementSet.advertisementState == AdvertisementState.ADVERTISEMENT_STATE_SUCCEEDED) {
textColor = context.resources.getColor(R.color.log_success, context.theme)
} else if (advertisementSet.advertisementState == AdvertisementState.ADVERTISEMENT_STATE_FAILED) {
textColor = context.resources.getColor(R.color.log_error, context.theme)
}
} else {
textColor = AppContext.getActivity().resources.getColor(R.color.text_color, AppContext.getContext().theme)
textColor = context.resources.getColor(R.color.text_color, context.theme)
}

holder.label!!.text = advertisementSet.title
holder.label!!.setTextColor(textColor)
holder.label?.text = advertisementSet.title
holder.label?.setTextColor(textColor)
return convertView
}

Expand All @@ -90,7 +90,12 @@ class AdvertisementSetCollectionExpandableListViewAdapter internal constructor(
return listPosition.toLong()
}

override fun getGroupView(listPosition: Int, isExpanded: Boolean, view: View?, parent: ViewGroup): View {
override fun getGroupView(
listPosition: Int,
isExpanded: Boolean,
view: View?,
parent: ViewGroup
): View {
var convertView = view
val holder: GroupViewHolder

Expand All @@ -104,17 +109,15 @@ class AdvertisementSetCollectionExpandableListViewAdapter internal constructor(
holder = convertView.tag as GroupViewHolder
}

var advertisementSetList = getGroup(listPosition) as AdvertisementSetList
val advertisementSetList = getGroup(listPosition) as AdvertisementSetList

var textColor = when(advertisementSetList.currentlyAdvertising){
true -> AppContext.getActivity().resources.getColor(R.color.blue_normal, AppContext.getContext().theme)
false -> AppContext.getActivity().resources.getColor(R.color.text_color, AppContext.getContext().theme)
val textColor = when (advertisementSetList.currentlyAdvertising) {
true -> context.resources.getColor(R.color.blue_normal, context.theme)
false -> context.resources.getColor(R.color.text_color, context.theme)
}

val listTitle = advertisementSetList.title

holder.label!!.text = listTitle
holder.label!!.setTextColor(textColor)
holder.label?.text = advertisementSetList.title
holder.label?.setTextColor(textColor)

return convertView
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package de.simon.dankelmann.bluetoothlespam.Adapters

import android.annotation.SuppressLint
import android.app.Activity
import android.graphics.drawable.Drawable
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import de.simon.dankelmann.bluetoothlespam.AppContext.AppContext
import de.simon.dankelmann.bluetoothlespam.Enums.FlipperDeviceType
import de.simon.dankelmann.bluetoothlespam.Enums.SpamPackageType
import de.simon.dankelmann.bluetoothlespam.Models.FlipperDeviceScanResult
import de.simon.dankelmann.bluetoothlespam.Models.SpamPackageScanResult
import de.simon.dankelmann.bluetoothlespam.R

Expand All @@ -39,21 +34,25 @@ class SpamPackageScanResultListViewAdapter(private val context: Activity, var sp
}
*/

class SpamPackageScanResultListViewAdapter(var mList: MutableList<SpamPackageScanResult>) : RecyclerView.Adapter<SpamPackageScanResultListViewAdapter.ViewHolder>() {
class SpamPackageScanResultListViewAdapter(
var mList: MutableList<SpamPackageScanResult>,
private val context: Context,
) : RecyclerView.Adapter<SpamPackageScanResultListViewAdapter.ViewHolder>() {

// create new views
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
// inflates the card_view_design view
// that is used to hold list item
val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item_spam_package_scan_result, parent, false)
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.list_item_spam_package_scan_result, parent, false)
return ViewHolder(view)
}

// binds the list items to a view
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemsViewModel = mList[position]

val ItemsViewModel = mList[position]

holder.nameText.text = when(ItemsViewModel.spamPackageType){
holder.nameText.text = when (itemsViewModel.spamPackageType) {
SpamPackageType.UNKNOWN -> "Unknown Spam"
SpamPackageType.FAST_PAIRING -> "Fast Pairing"
SpamPackageType.CONTINUITY_NEW_AIRTAG -> "Continuity Airtag"
Expand All @@ -68,26 +67,27 @@ class SpamPackageScanResultListViewAdapter(var mList: MutableList<SpamPackageSca
SpamPackageType.LOVESPOUSE_STOP -> "Lovespouse Stop"
}

var spamPackageIcon:Drawable = when(ItemsViewModel.spamPackageType){
SpamPackageType.UNKNOWN -> AppContext.getActivity().resources.getDrawable(R.drawable.bluetooth, AppContext.getContext().theme)
SpamPackageType.FAST_PAIRING -> AppContext.getActivity().resources.getDrawable(R.drawable.ic_android, AppContext.getContext().theme)
SpamPackageType.CONTINUITY_NEW_AIRTAG -> AppContext.getActivity().resources.getDrawable(R.drawable.apple, AppContext.getContext().theme)
SpamPackageType.CONTINUITY_NEW_DEVICE -> AppContext.getActivity().resources.getDrawable(R.drawable.apple, AppContext.getContext().theme)
SpamPackageType.CONTINUITY_NOT_YOUR_DEVICE -> AppContext.getActivity().resources.getDrawable(R.drawable.apple, AppContext.getContext().theme)
SpamPackageType.CONTINUITY_ACTION_MODAL -> AppContext.getActivity().resources.getDrawable(R.drawable.apple, AppContext.getContext().theme)
SpamPackageType.CONTINUITY_IOS_17_CRASH -> AppContext.getActivity().resources.getDrawable(R.drawable.apple, AppContext.getContext().theme)
SpamPackageType.SWIFT_PAIRING -> AppContext.getActivity().resources.getDrawable(R.drawable.microsoft, AppContext.getContext().theme)
SpamPackageType.EASY_SETUP_WATCH -> AppContext.getActivity().resources.getDrawable(R.drawable.samsung, AppContext.getContext().theme)
SpamPackageType.EASY_SETUP_BUDS -> AppContext.getActivity().resources.getDrawable(R.drawable.samsung, AppContext.getContext().theme)
SpamPackageType.LOVESPOUSE_PLAY -> AppContext.getActivity().resources.getDrawable(R.drawable.heart, AppContext.getContext().theme)
SpamPackageType.LOVESPOUSE_STOP -> AppContext.getActivity().resources.getDrawable(R.drawable.heart, AppContext.getContext().theme)
val spamPackageIconId: Int = when (itemsViewModel.spamPackageType) {
SpamPackageType.UNKNOWN -> R.drawable.bluetooth
SpamPackageType.FAST_PAIRING -> R.drawable.ic_android
SpamPackageType.CONTINUITY_NEW_AIRTAG -> R.drawable.apple
SpamPackageType.CONTINUITY_NEW_DEVICE -> R.drawable.apple
SpamPackageType.CONTINUITY_NOT_YOUR_DEVICE -> R.drawable.apple
SpamPackageType.CONTINUITY_ACTION_MODAL -> R.drawable.apple
SpamPackageType.CONTINUITY_IOS_17_CRASH -> R.drawable.apple
SpamPackageType.SWIFT_PAIRING -> R.drawable.microsoft
SpamPackageType.EASY_SETUP_WATCH -> R.drawable.samsung
SpamPackageType.EASY_SETUP_BUDS -> R.drawable.samsung
SpamPackageType.LOVESPOUSE_PLAY -> R.drawable.heart
SpamPackageType.LOVESPOUSE_STOP -> R.drawable.heart
}
val spamPackageIcon =
ResourcesCompat.getDrawable(context.resources, spamPackageIconId, context.theme)

holder.icon.setImageDrawable(spamPackageIcon)


holder.addressText.text = ItemsViewModel.address
holder.rssiText.text = "${ItemsViewModel.rssi} dBm"
holder.addressText.text = itemsViewModel.address
holder.rssiText.text = "${itemsViewModel.rssi} dBm"
holder.deviceTypeText.text = ""
}

Expand All @@ -97,12 +97,13 @@ class SpamPackageScanResultListViewAdapter(var mList: MutableList<SpamPackageSca
}

// Holds the views for adding it to image and text
class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
val nameText = ItemView.findViewById(R.id.list_item_spam_package_scan_result_name) as TextView
val addressText = ItemView.findViewById(R.id.list_item_spam_package_scan_result_address) as TextView
val rssiText = ItemView.findViewById(R.id.list_item_spam_package_scan_result_rssi) as TextView
val deviceTypeText = ItemView.findViewById(R.id.list_item_spam_package_scan_result_deviceType) as TextView
val icon = ItemView.findViewById(R.id.list_item_spam_package_scan_result_icon) as ImageView

class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val nameText: TextView = itemView.findViewById(R.id.list_item_spam_package_scan_result_name)
val addressText: TextView =
itemView.findViewById(R.id.list_item_spam_package_scan_result_address)
val rssiText: TextView = itemView.findViewById(R.id.list_item_spam_package_scan_result_rssi)
val deviceTypeText: TextView =
itemView.findViewById(R.id.list_item_spam_package_scan_result_deviceType)
val icon: ImageView = itemView.findViewById(R.id.list_item_spam_package_scan_result_icon)
}
}
Original file line number Diff line number Diff line change
@@ -1,57 +1,32 @@
package de.simon.dankelmann.bluetoothlespam.Callbacks

import android.Manifest
import android.bluetooth.le.AdvertisingSet
import android.bluetooth.le.AdvertisingSetCallback
import android.util.Log
import de.simon.dankelmann.bluetoothlespam.AppContext.AppContext
import de.simon.dankelmann.bluetoothlespam.PermissionCheck.PermissionCheck


class GenericAdvertisingSetCallback() : AdvertisingSetCallback() {

private val _logTag = "GenericAdvertisingSetCallback"
override fun onAdvertisingSetStarted(advertisingSet: AdvertisingSet?, txPower: Int, status: Int) {

val context = AppContext.getActivity()

if (status==AdvertisingSetCallback.ADVERTISE_FAILED_ALREADY_STARTED)
//Toast.makeText(context, "ADVERTISE_FAILED_ALREADY_STARTED", Toast.LENGTH_SHORT).show();
Log.d(_logTag, "ADVERTISE_FAILED_ALREADY_STARTED")
else if (status==AdvertisingSetCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED)
//Toast.makeText(context, "ADVERTISE_FAILED_FEATURE_UNSUPPORTED", Toast.LENGTH_SHORT).show();
Log.d(_logTag, "ADVERTISE_FAILED_FEATURE_UNSUPPORTED")
else if (status==AdvertisingSetCallback.ADVERTISE_FAILED_DATA_TOO_LARGE)
//Toast.makeText(context, "ADVERTISE_FAILED_DATA_TOO_LARGE", Toast.LENGTH_SHORT).show();
Log.d(_logTag, "ADVERTISE_FAILED_DATA_TOO_LARGE")
else if (status==AdvertisingSetCallback.ADVERTISE_FAILED_INTERNAL_ERROR)
//Toast.makeText(context, "ADVERTISE_FAILED_INTERNAL_ERROR", Toast.LENGTH_SHORT).show();
Log.d(_logTag, "ADVERTISE_FAILED_INTERNAL_ERROR")
else if (status==AdvertisingSetCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS)
//Toast.makeText(context, "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS", Toast.LENGTH_SHORT).show();
Log.e(_logTag, "ADVERTISE_FAILED_TOO_MANY_ADVERTISERS")
else if (status==AdvertisingSetCallback.ADVERTISE_SUCCESS)
//Toast.makeText(context, "ADVERTISE_SUCCESS", Toast.LENGTH_SHORT).show();
Log.d(_logTag, "ADVERTISE_SUCCESS")


Log.d(_logTag, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: " + status)

if(advertisingSet != null){
if(PermissionCheck.checkPermission(Manifest.permission.BLUETOOTH_ADVERTISE, AppContext.getActivity())){
//advertisingSet!!.setScanResponseData(AdvertiseData.Builder().addServiceUuid(ParcelUuid(UUID.randomUUID())).build())
//Log.d(_logTag,"adverting set is not null")
}
} else {
Log.d(_logTag,"advertising set is null");

override fun onAdvertisingSetStarted(
advertisingSet: AdvertisingSet?,
txPower: Int,
status: Int
) {
Log.d(_logTag, "onAdvertisingSetStarted(): txPower=$txPower status=$status")

if (advertisingSet == null) {
Log.d(_logTag, "advertising set is null");
}
}

override fun onAdvertisingDataSet(advertisingSet: AdvertisingSet, status: Int) {
Log.d(_logTag, "onAdvertisingDataSet() :status:$status")
Log.d(_logTag, "onAdvertisingDataSet() status=$status")
}

override fun onScanResponseDataSet(advertisingSet: AdvertisingSet, status: Int) {
Log.d(_logTag, "onScanResponseDataSet(): status:$status")
Log.d(_logTag, "onScanResponseDataSet(): status=$status")
}

override fun onAdvertisingSetStopped(advertisingSet: AdvertisingSet) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.simon.dankelmann.bluetoothlespam.Handlers

import android.content.Context
import android.os.Handler
import android.os.Looper
import android.util.Log
Expand Down Expand Up @@ -47,7 +48,7 @@ class AdvertisementSetQueueHandler :IAdvertisementServiceCallback{
_advertisementService!!.addAdvertisementServiceCallback(this)
}

setInterval(QueueHandlerHelpers.getInterval())
setInterval(QueueHandlerHelpers.getInterval(AppContext.getContext()))
}

fun setAdvertisementQueueMode(advertisementQueueMode: AdvertisementQueueMode){
Expand Down Expand Up @@ -167,16 +168,16 @@ class AdvertisementSetQueueHandler :IAdvertisementServiceCallback{
}
}

fun deactivate(stopService: Boolean = false){
fun deactivate(context: Context, stopService: Boolean = false) {
_active = false

if(AppContext.getAdvertisementService() != null){
if (AppContext.getAdvertisementService() != null) {
AppContext.getAdvertisementService().stopAdvertisement()
}

if(stopService){
Log.d(_logTag, "Stopping Foreground Service")
AdvertisementForegroundService.stopService(AppContext.getActivity())
AdvertisementForegroundService.stopService(context)
}

_advertisementQueueHandlerCallbacks.forEach { it ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package de.simon.dankelmann.bluetoothlespam.Helpers

import android.content.Context
import androidx.preference.PreferenceManager
import de.simon.dankelmann.bluetoothlespam.AppContext.AppContext
import de.simon.dankelmann.bluetoothlespam.AppContext.AppContext.Companion.bluetoothAdapter
Expand All @@ -12,43 +13,42 @@ import de.simon.dankelmann.bluetoothlespam.Services.ModernAdvertisementService

class BluetoothHelpers {
companion object {
fun supportsBluetooth5():Boolean{
fun supportsBluetooth5(): Boolean {
var bluetoothAdapter = AppContext.getContext().bluetoothAdapter()
if(bluetoothAdapter != null){
if(bluetoothAdapter!!.isLe2MPhySupported
if (bluetoothAdapter != null) {
if (bluetoothAdapter!!.isLe2MPhySupported
&& bluetoothAdapter!!.isLeCodedPhySupported
&& bluetoothAdapter!!.isLeExtendedAdvertisingSupported
&& bluetoothAdapter!!.isLePeriodicAdvertisingSupported
){
) {
return true
}
}
return false
}

fun getAdvertisementService() : IAdvertisementService {

var useLegacyAdvertisementService = true // <-- DEFAULT
fun getAdvertisementService(context: Context): IAdvertisementService {
var useLegacyAdvertisementService = true

// Get from Settings, if present
val preferences = PreferenceManager.getDefaultSharedPreferences(AppContext.getContext()).all
val preferences = PreferenceManager.getDefaultSharedPreferences(context).all
val prefKey =
context.resources.getString(R.string.preference_key_use_legacy_advertising)
preferences.forEach {
if(it.key == AppContext.getActivity().resources.getString(R.string.preference_key_use_legacy_advertising)){
if (it.key == prefKey) {
useLegacyAdvertisementService = it.value as Boolean
}
}

val advertisementService = when (useLegacyAdvertisementService) {
return when (useLegacyAdvertisementService) {
true -> LegacyAdvertisementService()
else -> {
ModernAdvertisementService()
}
}

return advertisementService
}

fun getBluetoothLeScanService():IBluetoothLeScanService{
fun getBluetoothLeScanService(): IBluetoothLeScanService {
return BluetoothLeScanService()
}
}
Expand Down
Loading

0 comments on commit 5b25258

Please sign in to comment.