I have an Android application with lots of NFC and GPS functionality. I need to verify the location of a user with either gps or the scan of a NFC tag.
I created a use case to handle NFC but I would like to not have a reference to my activity in this class. Problem for me is that I need the activity to
The use case should have a start() function to start the NFC foreground dispatch. It should automatically stop the foreground dispatch after a scan (which needs the activity)
I thought about a class in between my activity and my NFC use case that holds the activity. I call this the InBetweenClass.
class InBetweenClass(val activity: AppCompatActivity) {
private var nfcAdapter: NfcAdapter = NfcAdapter.getDefaultAdapter(activity)
fun startNfc() {
val intent = Intent(activity, activity.javaClass)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE)
} else {
PendingIntent.getActivity(activity, 0, intent, 0)
}
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null)
}
fun stopNfc() {
try {
nfcAdapter.disableForegroundDispatch(activity)
} catch (ex: Exception) {
// tbd
}
}
}
Question: I now could handover a reference of the InBetweenClass to my NFC use case. But is this really better than having the activity in my use case? As I hold a reference to the InBetweenClass and this class holds the activity, it seems to me more or less the same as having the activity right in my NFC use case.
What pattern is best to decouple my use case from my activity? My app is a single activity app.
I have an Android application with lots of NFC and GPS functionality. I need to verify the location of a user with either gps or the scan of a NFC tag.
I created a use case to handle NFC but I would like to not have a reference to my activity in this class. Problem for me is that I need the activity to
The use case should have a start() function to start the NFC foreground dispatch. It should automatically stop the foreground dispatch after a scan (which needs the activity)
I thought about a class in between my activity and my NFC use case that holds the activity. I call this the InBetweenClass.
class InBetweenClass(val activity: AppCompatActivity) {
private var nfcAdapter: NfcAdapter = NfcAdapter.getDefaultAdapter(activity)
fun startNfc() {
val intent = Intent(activity, activity.javaClass)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_MUTABLE)
} else {
PendingIntent.getActivity(activity, 0, intent, 0)
}
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, null, null)
}
fun stopNfc() {
try {
nfcAdapter.disableForegroundDispatch(activity)
} catch (ex: Exception) {
// tbd
}
}
}
Question: I now could handover a reference of the InBetweenClass to my NFC use case. But is this really better than having the activity in my use case? As I hold a reference to the InBetweenClass and this class holds the activity, it seems to me more or less the same as having the activity right in my NFC use case.
What pattern is best to decouple my use case from my activity? My app is a single activity app.
Maybe change the signature from:
class InBetweenClass(val activity: AppCompatActivity)
to:
abstract class BaseNfcActivity : AppCompatActivity() /*, NfcAdapter.ReaderCallback */
and also:
class MainActivity : BaseNfcActivity()
Then you have your InBetweenClass
, without having to pass anything.
First of all, your activity also shouldn't interact with UseCase. Any business logic should pass through the ViewModel.
For now, let's find a solution to your question:
You can pass an activity as a param of your fun. In this case you won't keep reference anywhere.
Another way is to pass lambda as a param of fun and just invoke this lambda in the ViewModel, Usecase whatever. In this case, your activity reference will be only in activity class. Sometimes it looks not very elegant but at least you keep your UI and domain layers clear. And this is the only one approach for KMP projects.
enableReaderMode
instead ofenableForegroundDispatch
, while this still anActivity
reference to enable in theory I think people have got thecallback
method to work in a separate class with no Activity reference. This is better thanenableForegroundDispatch
which requires you to override the ActivitiesonNewIntent
method. – Andrew Commented Jan 2 at 18:49