How to get instance in Kotlin with Context.getSystemService(Class) - android

In Google Android Kotlin documentation,
Every now and then there is a below line present in android documentation that:
Instances of this class must be obtained using Context.getSystemService(Class)
For example:
Instances of this class must be obtained using Context.getSystemService(Class) with the argument AppOpsManager.class or Context.getSystemService(String) with the argument Context.APP_OPS_SERVICE.
Can someone please clarify what this is and how do I create a instance for class AppOpsManager.
Usually we can create instance like:
val use = AppOpsManager()
Please help and explain the above Context.getSystemService().
Thank You.

From Android Developer documentation:
AppOpsManager
API for interacting with "application operation" tracking.
This API is not generally intended for third party application
developers; most features are only available to system applications.
Instances of this class must be obtained using
Context.getSystemService(Class) with the argument
AppOpsManager.class or Context.getSystemService(String) with the
argument Context.APP_OPS_SERVICE.
To create an instance of this class you must use getSystemService from a context instance.
val appOpsManager: AppOpsManager? = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager?
If your minSdkVersion is 23 then you can use this code instead.
val appOpsManager: AppOpsManager? = getSystemService(AppOpsManager::class.java)

Use the following:
context.getSystemService(AppOpsManager::class.java)

val aom = getSystemService(context, AppOpsManager::class.java)

Related

kotlin- PaymentSessionConfiguration

Hello I am trying to update stripe but when I have to call PaymentSessionConfig my code blocks because the companion of the PaymentSessionConfig class is in private, I cannot modify the class because it is in read only, here is the line :
mPaymentSession = PaymentSession (activity = summaryActivity, config = PaymentSessionConfig)
and the error message I have :
Cannot access 'Companion': it is private in 'PaymentSessionConfig'
Type mismatch.
Required:
PaymentSessionConfig
Found:
PaymentSessionConfig.Companion
Can you share the details of what versions of the SDK you're updating from and to? The migration docs cover a lot of details changes for various versions.
Is it possible you mean to reference some paymentSessionConfig, or what is your config here?
See this example implementation using the PaymentSessionConfig.Builder() (github)

Passing custom object between activities

I'm following this tutorial on how to use MQTT with Android Studio. In it, they created an MQTTClient class that uses the MQTTAndroidClient library. I want to pass the MQTTClient class from one activity to another. Any suggestions how I might do this? I'm new to Android dev and I'm trying to negotiate serializable/parcelable tools without much know-how. Thanks!
P.S. I'm developing in Kotlin
Passing complex classes between activities is generally a bad idea. For that kind of usage you should use a Singleton and store it in your Application class or something like this.
I don't recommend you to pass the entire MQTTClient through Activities.
I'd suggest you to read this Dependency-Injection manual is more or less what you need, normally you'd use a dependency injection library/framework to do what you want but since is complex to set-up most of them I'd follow the link I've linked before.
Sample code :
// Container of objects shared across the whole app
class AppContainer {
val mqttClient = MQTTClient() //<-- Initialisation
}
Then create a custom Application
class MyApplication : Application() {
// Instance of AppContainer that will be used by all the Activities of the app
val appContainer = AppContainer()
}
Do not forget to add it to manifest.xml with the name attribute.
And then from your Activity you need this MQTTClient you use :
val appContainer = (application as MyApplication).appContainer
val mqttClient = appContainer.mqttClient
What #Ben-J suggested is also a good point, to create a Singleton in kotlin you can use the object keyboard.

Open Close Principle and Extension Functions

I have learned that Open Close Principle is allowing extension to classes and restricting from modification. So in Kotlin, when we use extension function
Are we extending a class
Or are we modifying a class
Can extension functions in kotlin be an example for Open/Close Principle?
I assume extension means to apply inheritance and modification means to add or change code of existing class.
Thanks
The extenstion function is designed for situations where you want to add a function to a built-in or third-party class. You cannot do this by default because built-in functions are not modifiable.
An example implementation to add a toUnsigned method to the built-in Byte class:
fun Byte.toUnsigned(): Int {
return if (this < 0) this + 256 else this.toInt()
}
As Byte is a built-in class you cannot modify it directly. However, you can define an extension function as per above code. You can then call the extension function in the following way:
val x: Byte = -1
println(x.toUnsigned()) // Prints 255
Keep in mind that this is just syntactic sugar - you're not actually modifying the class or its instances. Therefore, you have to import an extension function/property wherever you want to use it (since it isn't carried along with the instances of the class).
Source : https://kotlinlang.org/docs/tutorials/kotlin-for-py/extension-functionsproperties.html
'Extension' in the context of the Open Closed Principle usually does not mean inheritance, it means somehow extending the class with new functionality. 'Modification' does refer to changing the code of the class, as you say.
The extension facility of Kotlin allows you to add a method to a class without editing the code of the class. This is perfectly in keeping with the Open Closed Principle -- the class is extended with new functionality without the class itself being changed.

LifecycleObserver produce exception with methods that use newer APIs

My ViewModel class implements LifecycleObserver.
When I call fragment.lifecycle.addObserver(this) it produces exception.
Caused by: java.lang.IllegalArgumentException: The observer class has some methods that use newer APIs which are not available in the current OS version. Lifecycles cannot access even other methods so you should make sure that your observer classes only access framework classes that are available in your min API level OR use lifecycle:compiler annotation processor.
Strange, that firstly it was working fine, but not long ago this exception has appeared. I've found, that audioFocusRequest is cause of this bug.
private val audioFocusRequest by lazy {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setOnAudioFocusChangeListener(this)
.build() else throw RuntimeException("Can't be done for Android API lower than 26")
}
Does anybody know how it can be fixed?
UPD
Tried to use annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version", but got compilation error:
(decided to paste screenshot, because whole logs are quite big)
UPD 2
At the end I've decided to delete audioFocusRequest field and to use old deprecated method - requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) instead of recommended requestAudioFocus(#NonNull AudioFocusRequest focusRequest)
It helped me to make code working again, so it can be solution. But I didn't find answer - why this problem had appeared. It strange because code used to be working before.
So problem has been solved but question still stays unanswered
Try to use kapt "androidx.lifecycle:lifecycle-compiler:2.0.0"
The class which implements LifecycleObserver has some method, which has parameters with type that only exist for higher APIs.
Your variables (i guess) and function parameters must exist on all APIs even function is not called (maybe this is requirement for classes who implement LifecycleObserver).
A possible solution is to change function parameter type to Any (kotlin) or Object (Java) and cast it to appropriate type inside function.
I have to remove this set method on SpinnerView: lifecycleOwner = viewLifecycleOwner
I was able to fix this by moving the offending methods into another class, but still called from my LifecycleObserver. After reading the error message again:
Caused by: java.lang.IllegalArgumentException: The observer class has some methods that use newer APIs which are not available in the current OS version. Lifecycles cannot access even other methods so you should make sure that your observer classes only access framework classes that are available in your min API level OR use lifecycle:compiler annotation processor.
It seems as though no methods or objects are allowed in the class extending LifecycleObserver if they don't exist in the device's OS, even if they are wrapped in an SDK version check and never accessed.

Is there better way for handle kotlinx serialization?

I use kotlinx.serialization on Kotlin native project, I a defined Super class for my models and all of the models extends from it.
I defined a function to called toJSON() for serialize variables and fields inside model that all of class models have it.
#Serializable
open class Model {
fun toJSON(): String = JSON.stringify(this);
}
And I created a subclass
class Me : Model() {
var name:String = "Jack";
}
but when I invoke JSON.stringify(this), IDE get a Warning to me:
This declaration is experimental and its usage must be marked with '#kotlinx.serialization.ImplicitReflectionSerializer' or '#UseExperimental(kotlinx.serialization.ImplicitReflectionSerializer::class)'
I paid attention and I used #ImplicitReflectionSerializer annotation while not worked.
Where is my problem?
This is discussed here. It's the particular overload you're using which is still experimental. So your options are either to use the other overload (which takes in a serializer) or to use one of the annotations mentioned in the error message. If you look at the answer to the question I linked (and the comments following it), you'll see it talks about using #UseExperimental and where it should be used.

Categories

Resources