How to send and received data between Application module to Androidauto module - android

Any idea on how can to send and receive data between Application module to Androidauto. Also how can i put events/listener in Androidauto module if i received data from the application.

With BroadcastRecevier.
Use DefaultLifecycleObserver on your Screen or Session
class CarHomeScreen(carContext: CarContext) : Screen(carContext), DefaultLifecycleObserver {
private val someBroadcastReceiver = SomeBroadcastReceiver()
init {
lifecycle.addObserver(this)
}
override fun onGetTemplate(): Template {}
override fun onCreate(owner: LifecycleOwner) {
carContext.registerReceiver(someBroadcastReceiver, IntentFilter)
super.onCreate(owner)
}
override fun onDestroy(owner: LifecycleOwner) {
lifecycle.removeObserver(this)
carContext.unregisterReceiver(someBroadcastReceiver)
super.onDestroy(owner)
}
}

How about Local Broadcast Receiver?

Related

Use plugin directly inside flutter project without separating to another package or adding plugin field in pubspec.yaml

I want to create a plugin to use in my project. I wonder that how I can call or setup it for invoking from flutter application without specific it in pubspec.yaml (because I use some other packages which also use their owned plugins, if I specify my plugin inside pubspec.yaml, those plugins do not work) or separating to another package.
Here is my current code:
class DemoPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
private lateinit var channel: MethodChannel
private lateinit var context: Context
private lateinit var activity: Activity
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"demo" -> {
result.success("Demo")
}
}
}
override fun onAttachedToEngine(#NonNull flutterPluginBinding: FlutterPluginBinding) {
context = flutterPluginBinding.applicationContext
channel = MethodChannel(flutterPluginBinding.binaryMessenger, channelName)
channel.setMethodCallHandler(this)
}
override fun onDetachedFromEngine(binding: FlutterPluginBinding) {
channel.setMethodCallHandler(null)
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
activity = binding.activity
}
override fun onDetachedFromActivityForConfigChanges() {}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {}
override fun onDetachedFromActivity() {}
}
According to the docs of the FlutterPlugin Class you can do this in the MainActivity Class.
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
flutterEngine.plugins.add(DemoPlugin()) // add the plugin
}
}

StreamChannel don't send continuous data to flutter

Im trying to set a continuos broadcast from Kotlin to dart using an EventChannel, following this example: GITHUB REPO it uses an IntentFilter in order to notify the battery status.
What im trying to do is to return each second if possible a value that's stored on a sharedPreference, but it doesn't matter if I set the Intent to stream with action_send, flutter doesn't receive the value.
this is the current code.
private lateinit var streamChannel: EventChannel
private lateinit var statusValueStateChangeReceiver: BroadcastReceiver
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
streamChannel = EventChannel(
flutterEngine.dartExecutor.binaryMessenger, "continuous.stream.boolean/statusValue")
streamChannel.setStreamHandler(this)
}
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
statusValueStateChangeReceiver = createStatusValueStateChangeReceiver(events);
applicationContext.registerReceiver(
statusValueStateChangeReceiver, IntentFilter(Intent.ACTION_SEND));
}
override fun onCancel(arguments: Any?) {
applicationContext.unregisterReceiver(statusValueStateChangeReceiver);
}
private fun createStatusValueStateChangeReceiver(events: EventChannel.EventSink?): BroadcastReceiver {
return object : BroadcastReceiver() {
override fun onReceive(contxt: Context?, intent: Intent?) {
events?.success(intent?.let { MyClass().getStatusValue() })
}
}
}
how can I keep sending the data to dart in a persistent way? thanks in advance.

Proper way to unregister a callback from an Application class

I have implemented a custom Application class in my app which handles updating the app theme before the app start up.
I also registered a network callback to set a variable each time there is a connection change.
My application class is as such:
Application.kt
package com.th3pl4gu3.mes.ui
.....
class MesApplication : Application() {
companion object {
#Volatile
private var INSTANCE: MesApplication? = null
fun getInstance() =
INSTANCE ?: synchronized(this) {
INSTANCE
?: MesApplication().also { INSTANCE = it }
}
}
override fun onCreate() {
super.onCreate()
// Assigns 'this' to the singleton object
INSTANCE = this
// Updates the application's theme
updateAppTheme()
// Start a network callback to monitor internet connection
startNetworkCallback()
}
private fun startNetworkCallback(){
try{
val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val builder = NetworkRequest.Builder()
cm.registerNetworkCallback(builder.build(), object: ConnectivityManager.NetworkCallback(){
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.v("INTERNET_TEST", "AC: Network Available")
Global.isNetworkConnected = true
}
override fun onLost(network: Network) {
super.onLost(network)
Log.v("INTERNET_TEST", "AC: Network Lost")
Global.isNetworkConnected = false
}
})
Global.isNetworkConnected = false
}catch (e: Exception){
Global.isNetworkConnected = false
}
}
}
However, from the docs, they recommend to unregister this callback but the Application class lifecycle doesn't have any onPause or onDestroy function.
Is there any proper way to unregister this callback to not cause any memory leaks?
Also feel free to suggest any alternatives in case I am coding this wrong
In this case , you can use ActivityLifecycleCallbacks, to detect are any Activity of your is in Foreground?
ActivityLiveCycleListener
class ActivityLiveCycleListener(private val appStateListener: AppStateListener) : Application.ActivityLifecycleCallbacks {
companion object {
var foregroundActivities = 0
}
override fun onActivityPaused(p0: Activity) {
}
override fun onActivityStarted(p0: Activity) {
if(foregroundActivities == 0){
appStateListener.onAppForeGround()
}
foregroundActivities++
}
override fun onActivityDestroyed(p0: Activity) {
}
override fun onActivitySaveInstanceState(p0: Activity, p1: Bundle) {
}
override fun onActivityStopped(p0: Activity) {
foregroundActivities--
if(foregroundActivities == 0){
appStateListener.onAppBackground()
}
}
override fun onActivityCreated(p0: Activity, p1: Bundle?) {
}
override fun onActivityResumed(p0: Activity) {
}
}
And your interface can have two methods to indicate background/foreground state
interface AppStateListener{
fun onAppForeGround()
fun onAppBackground()
}
Now in Application onCreate(), register to ActivityLifeCycleListener
override fun onCreate(){
registerActivityLifecycleCallbacks(ActivityLiveCycleListener(object : AppStateListener{
override fun onAppForeGround() {
//start network listener
}
override fun onAppBackground() {
//remove network listener
}
}))
}

Pass data from BroadcastReceiver to ViewModel or Repository

I'm trying to send the data that I receive in the broadcast(registered in manifest) in the viewmodel or in the repository is not particularly important, I tried to do it both through the live date and through RxJava2, but there is data inside the broadcast class i can see, but it does not come to the viewmodel or repository, thank you.
class MyBroadcastReceiver : BroadcastReceiver() {
private val dataList = MutableLiveData<ArrayList<Words>>()
private var observer: Observable<ArrayList<Words>> = Observable.just(arrayListOf())
#SuppressLint("CheckResult")
override fun onReceive(context: Context?, intent: Intent?) {
val arrayObject =
intent?.extras?.getParcelableArrayList<Words>("KEY") as ArrayList<Words>?
dataList.postValue(arrayObject)
arrayObject.let { dataList.postValue(it) }
arrayObject.let { observer = Observable.just(it) }
observer = Observable.create { emitter: ObservableEmitter<ArrayList<Words>> ->
emitter.onNext(arrayObject!!)
emitter.onComplete()
}
}
fun getDataList() : LiveData<ArrayList<Words>> = dataList
fun getDataListRx() : Observable<ArrayList<Words>> = observer
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
ViewModel class:
class MyViewModel(
private val broadcastReceiver: MyBroadcastReceiver,
private val activity: DaggerActivity) : ViewModel() {
init {
test()
}
#SuppressLint("CheckResult")
private fun test() {
broadcastReceiver.getDataListRx()?.subscribe({
Log.d("WAS_INTENT", "DateRepSuccess")
},{
Log.d("WAS_INTENT", "DateRepError")
})
broadcastReceiver.getDataList().observe(activity, Observer {
Log.d("WAS_INTENT", "DateRepSuccessLiveData")
})
}}
After many attempts, I found out that the liveData works, so maybe someone will need it. RxJava still don`t , I don’t know why yet.

how to detect the closing of the app and take acction ? ( kotlin )

I want to disable the WiFi when the app is closed.
i know the code to disable WiFi using this line :
wifiManager!!.isWifiEnabled = false
but i don't know how to detect the closing of the app.
This exactly what lifecycles are used for. Any clean up work that needs to done should be done in onDestroy(). This is the final call you receive before your activity is destroyed. So in the activity where you want to disable wifi you can just do:
override func onDestroy() {
super.onDestroy();
wifiManager!!.isWifiEnabled = false;
}
You might check out this blog post. It described how to do it more detail than I could.
EDIT:
Important parts of blog post are:
1 - Create our interface that will be implemented by a custom Application class:
interface LifecycleDelegate {
fun onAppBackgrounded()
fun onAppForegrounded()
}
2 - Now we a class that is going to implement the ActivityLifecycleCallbacks and ComponentCallbacks2:
class AppLifecycleHandler(
private val lifeCycleDelegate: LifeCycleDelegate
) : Application.ActivityLifecycleCallbacks, ComponentCallbacks2
{
private var appInForeground = false
override fun onActivityResumed(activity: Activity?) {
if (!appInForeground) {
appInForeground = true
lifeCycleDelegate.onAppForegrounded()
}
}
override fun onTrimMemory(level: Int) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
appInForeground = false
lifeCycleDelegate.onAppBackgrounded()
}
}
// stub other methods
}
3 - We need to use that handler in our application class:
class App : Application(), LifeCycleDelegate {
override fun onCreate() {
super.onCreate()
val lifeCycleHandler = AppLifecycleHandler(this)
registerLifecycleHandler(lifeCycleHandler)
}
override fun onAppBackgrounded() {
Log.d("App", "App in background")
}
override fun onAppForegrounded() {
Log.d("App", "App in foreground")
}
private fun registerLifecycleHandler(lifeCycleHandler: AppLifecycleHandler) {
registerActivityLifecycleCallbacks(lifeCycleHandler)
registerComponentCallbacks(lifeCycleHandler)
}
}

Categories

Resources