Recently I decided to create flutter application I have only problem with one thing.
I wanted to create custom stream to detect unplug of headset to stop music playing.
This is my MainActivity.
package com.example.radio24
import android.content.BroadcastReceiver
import android.content.IntentFilter
import android.content.Context
import android.content.Intent
import android.media.AudioManager
import android.os.Bundle
import android.os.PersistableBundle
import io.flutter.embedding.android.FlutterActivity
import io.flutter.plugin.common.EventChannel
class MainActivity: FlutterActivity() {
private val HEADPHONES_LISTENER_CHANNEL = "com.radioanime24.dev/headphones"
lateinit var broadCastReceiver: BroadcastReceiver;
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
super.onCreate(savedInstanceState, persistentState)
EventChannel(flutterEngine?.dartExecutor?.binaryMessenger, HEADPHONES_LISTENER_CHANNEL).setStreamHandler(
object: EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
broadCastReceiver = object : BroadcastReceiver() {
override fun onReceive(contxt: Context?, intent: Intent?) {
when (intent?.action) {
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> {
events?.success("HEADPHONES_UNPLUGGED")
}
}
}
}
val filter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
registerReceiver(broadCastReceiver, filter);
}
override fun onCancel(arguments: Any?) {
unregisterReceiver(broadCastReceiver)
}
}
)
}
}
In dart I am trying to consume this stream with:
Stream headPhonesStateStream = EventChannel('com.radioanime24.dev/headphones').receiveBroadcastStream();
headPhonesStateStream.listen((event) {
if (event == 'HEADPHONES_UNPLUGGED') {
if (AudioService.playbackState.playing) {
AudioService.pause();
}
}
});
But I am receiving error:
MissingPluginException(No implementation found for method listen on channel com.radioanime24.dev/headphones)
How should I register eventchannel to omit this error?
I believe you should override the onCreate(savedInstanceState: Bundle?) method instead of onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) of the Activity.
Related
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class SplashScreen : AppCompatActivity() {
private lateinit var progressBar: ProgressBar
private val SPLASH_DISPLAY_LENGTH = 5000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.splash_screen)
progressBar = findViewById(R.id.progressBar)
GlobalScope.launch(Dispatchers.Main) {
delay(SPLASH_DISPLAY_LENGTH)
progressBar.visibility = View.VISIBLE
loadWebView()
}
}
private suspend fun loadWebView() {
withContext(Dispatchers.IO) {
delay(SPLASH_DISPLAY_LENGTH)
}
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
This is a Splash Screen. I got this error - None of the following functions can be called with the arguments supplied:public suspend fun delay(timeMillis: Long): Unit defined in kotlinx.coroutinespublic suspend fun delay(duration: Duration): Unit defined in kotlinx.coroutines. Can anybody help me please. Thanks in Advance.
I got it. I removed SPLASH_DISPLAY_LENGTH and added the duration directly like this- delay(5000). It worked --
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
#OptIn(DelicateCoroutinesApi::class)
#SuppressLint("CustomSplashScreen")
class SplashScreen1 : AppCompatActivity() {
private lateinit var progressBar: ProgressBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.splash_screen)
progressBar = findViewById(R.id.progrssBar2)
GlobalScope.launch(Dispatchers.Main) {
delay(3000)
progressBar.visibility = View.VISIBLE
loadWebView()
}
}
private suspend fun loadWebView() {
withContext(Dispatchers.IO) {
delay(3000)
}
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
It is another answer thanks to #Tenfour04. Comment
import android.content.Intent
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
class SplashScreen1 : AppCompatActivity() {
private lateinit var progressBar: ProgressBar
//Define the constant as long instead of int
private val SPLASH_DISPLAY_LENGTH = 5000L
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.splash_screen)
progressBar = findViewById(R.id.progress_circular)
GlobalScope.launch(Dispatchers.Main) {
delay(SPLASH_DISPLAY_LENGTH)
progressBar.visibility = View.VISIBLE
loadWebView()
}
}
private suspend fun loadWebView() {
withContext(Dispatchers.IO) {
delay(SPLASH_DISPLAY_LENGTH)
}
startActivity(Intent(this, MainActivity::class.java))
finish()
}
}
package com.example.asyntask
import android.content.ContentValues.TAG
import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnStart.setOnClickListener {
val tvCounter=findViewById<TextView>(R.id.tvCounter)
CountTask().execute(5)
}
}
}
class CountTask() : AsyncTask<Int, Int, Unit>() {
private val tag: String? = "Async"
override fun doInBackground(vararg params: Int?) {
Log.d(tag, "doInBackground: started")
val n: Int = params[0]!!
for (i in 0 until n) {
wait1Sec()
publishProgress(i)
}
}
private fun wait1Sec():Unit{
val start =System.currentTimeMillis()
while(System.currentTimeMillis()<start+1000){}
}
override fun onProgressUpdate(vararg values: Int?) {
super.onProgressUpdate(*values)
//WANT TO WRITE TEXT IN TEXT VIEW BUT HOW TO GET VIEW HERE
}
}
Please try to create the Callback with progressupdate from asynchtask to mainactivity
like:
Interface UpdateListener{
fun onProgressUpdate(progress:Int);
}
class CountTask(val listener:UpdateListener) : AsyncTask<Int, Int, Unit>() {
override fun onProgressUpdate(vararg values: Int?) {
super.onProgressUpdate(*values)
//WANT TO WRITE TEXT IN TEXT VIEW BUT HOW TO GET VIEW HERE
listener.onpreogressupdate(...)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnStart.setOnClickListener {
val tvCounter=findViewById<TextView>(R.id.tvCounter)
CountTask(object:listener:UpdateListener{
override fun onProgressUpdate(progress:Int){
//TODO update here
}
}).execute(5)
}
}
I created a new empty activity for my project but I am getting an error. The activity file as well as the layout file is shown in red color. I tried creating an intent object from MainActivity, in order to start this activity but received the following error
Classifier 'Details' does not have a companion object, and thus must
be initialized here
I've attached a screenshot of my android studio.
Code for new activity
package com.example.safetyapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class Details : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_details)
}
}
package com.example.safetyapp
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.firebase.ui.auth.AuthUI
import com.google.firebase.auth.FirebaseAuth
class MainActivity : AppCompatActivity() {
final val AUTH_REQUEST_CODE = 7192
lateinit var firebaseAuth:FirebaseAuth
lateinit var listener: FirebaseAuth.AuthStateListener
lateinit var providers: List<AuthUI.IdpConfig>
override fun onStart(){
super.onStart()
firebaseAuth.addAuthStateListener(listener)
}
override fun onStop(){
super.onStop()
if(listener!=null){
firebaseAuth.removeAuthStateListener(listener)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button2 = findViewById<Button>(R.id.button2)
val defence = findViewById<Button>(R.id.Defence)
button2.setOnClickListener{
val myintent = Intent(this, Details::class.java)
}
init()
}
private fun init() {
providers = arrayListOf(AuthUI.IdpConfig.PhoneBuilder().build(),
AuthUI.IdpConfig.EmailBuilder().build())
firebaseAuth = FirebaseAuth.getInstance()
listener = object:FirebaseAuth.AuthStateListener{
override fun onAuthStateChanged(p0: FirebaseAuth) {
val user = p0.currentUser
if(user!= null){
// Do something
}
else{
startActivityForResult(AuthUI.getInstance()
.createSignInIntentBuilder()
.setAvailableProviders(providers)
.setLogo(R.drawable.logo)
.build(),AUTH_REQUEST_CODE)
}
}
}
}
}
You didn't import the Details class, add this line between your MainActivity class imports
import com.example.safetyapp.Details
I am trying to run this BroadcastReceiver in a Service.
I register it in onStartCommand:
import android.app.Service
import android.content.*
import android.os.IBinder
import android.util.Log
import java.util.*
class CopyService : Service() {
private lateinit var mPasteReceiver: PasteReceiver
private val TAG = "COPYSERVICE"
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PASTE)
mPasteReceiver = PasteReceiver()
registerReceiver(mPasteReceiver, intentFilter)
return START_STICKY
}
override fun onDestroy() {
unregisterReceiver(mPasteReceiver)
super.onDestroy()
}
override fun onBind(intent: Intent?): IBinder? = null
inner class PasteReceiver: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.d(TAG,"Paste received.")
}
}
}
It does not work! :(
I should specify I am trying to get a clipboard paste event.
I have the following code of activity:
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Bundle
import android.os.Handler
import android.support.v7.app.AppCompatActivity
import com.mikhailovskii.androidacademytask8.R
import com.mikhailovskii.androidacademytask8.data.service.ProgressIntentService
import kotlinx.android.synthetic.main.activity_main.*
class ProgressActivity : AppCompatActivity() {
private val receiver = ActivityBroadcastReceiver(Handler())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv_progress.text="0"
val intentFilter = IntentFilter(ProgressIntentService.INTENT_ACTION)
registerReceiver(receiver, intentFilter)
btn_intent_service.setOnClickListener {
val intent = Intent(this, ProgressIntentService::class.java)
startService(intent)
}
btn_service.setOnClickListener {
}
}
override fun onDestroy() {
super.onDestroy()
unregisterReceiver(receiver)
}
//FIXME handler1 seems strange, but passing to constructor doesn't work
class ActivityBroadcastReceiver (handler1: Handler) : BroadcastReceiver() {
private val handler = handler1
override fun onReceive(context: Context?, intent: Intent?) {
val progress = intent?.getIntExtra(ProgressIntentService.EXTRA_KEY_OUT, 0)
handler.post { tv_progress.text = progress }
}
}
}
I need to change the text in tv_progress from BroadcastReceiver. For this purpose I added Handler here. But name of tv is highlighted in red and studio writes that
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch
So, what's the reason of this problem and how can I solve it? Thanks in advance!
Please check the name on broadcast in below line :
val intentFilter = IntentFilter(ProgressIntentService.INTENT_ACTION)