when battery is low connect device when i connect device automatically dismiss alert dialog box from activities - dialog

This is my broadcast reciver fun in mainactivity.kt file
private val mPlugInReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val bm = context.getSystemService(Application.BATTERY_SERVICE) as BatteryManager
val batLevel:Int = bm.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
System.out.println("integerBatteryLevel ===="+batLevel)
if(batLevel < 20){
System.out.println("this is low battaroy below 20 % ===="+batLevel)
}else
{
System.out.println("this is nice battaroy more than 20 % ===="+batLevel)
}
when (intent.action) {
Intent.ACTION_POWER_CONNECTED -> {
Toast.makeText(context, "Power connected", Toast.LENGTH_SHORT).show()
openDialogForBatteryStatus(false)
}
Intent.ACTION_POWER_DISCONNECTED -> {
if(batLevel > 20){
openDialogForBatteryStatus(false)
}else
{
Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show()
openDialogForBatteryStatus(true)
}
}
}
}
}

This is My BaseActivity Calling Alert Dialog box
open class BaseActivity : AppCompatActivity() {
fun openDialogForBatteryLevel(show: Boolean){
val dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
val dialog = AlertDialog.Builder(this#BaseActivity)
dialog.setView(dialogView).setCancelable(false)
val d= dialog.create()
if(show){
if(d.isShowing)
d.show()
}else{
d.dismiss()
}
dialogView.txtViewDescription.text = "Your Phone Battery is low"
dialogView.txtViewOk.setOnClickListener{
this.finishAffinity()
}
d.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
fun openDialogForBatteryStatus(show: Boolean) {
val dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
val dialog = AlertDialog.Builder(this#BaseActivity)
dialog.setView(dialogView).setCancelable(false)
val d= dialog.create()
if(show){
if(d.isShowing)
d.show()
}else{
d.dismiss()
}
dialogView.txtViewDescription.text = "Please Remove charger"
dialogView.txtViewOk.setOnClickListener{
this.finishAffinity()
}
d.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
}
}

What you are doing is creating the new dialog everytime u call the method openDialogForBatteryLevel() and every time you try to dismiss you are dismissing the new object of dialog and not the one attached to the window . You should globally hold the object (preferably weak reference of the object) and initialize it only if it is not initialized and do the operation on it.

Again i change my BaseActivity than too Some red line it show in code
fun openDialogForBatteryLevel(show: Boolean, message : String): AlertDialog{
val dialog
val dialogView
var d
if(alertD == null){
dialog = AlertDialog.Builder(this#BaseActivity)
dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
dialog.setView(dialogView).setCancelable(false)
d = dialog.create()
}else{
d = alertD
}
if(show){
if(d.isShowing)
d.show()
}else{
d.dismiss()
}
dialogView.txtViewDescription.text = message
dialogView.txtViewOk.setOnClickListener{
this.finishAffinity()
}
d.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
return d
}

open class BaseActivity : AppCompatActivity() {
fun openDialogForBatteryLevel(){
val dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
val dialog = AlertDialog.Builder(this#BaseActivity)
.setView(dialogView).setCancelable(false)
.show()
dialogView.txtViewDescription.text = "Your Phone Battery is low"
dialogView.txtViewOk.setOnClickListener{
this.finishAffinity()
}
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialogView.txtViewOk.setOnClickListener {
dialog.dismiss()
}
}
fun openDialogForBatteryStatus(){
val dialogView = layoutInflater.inflate(R.layout.dialog_battery_low, null)
val dialog = AlertDialog.Builder(this#BaseActivity)
.setView(dialogView).setCancelable(false)
.show()
dialogView.txtViewDescription.text = "Please Remove charger"
dialogView.txtViewOk.setOnClickListener{
this.finishAffinity()
}
dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialogView.txtViewOk.setOnClickListener {
dialog.dismiss()
}
}
}

Related

Alert dialog before a new thread

I have the code.
After clicking on the button, an alertdialog of the download warning should appear. And request a json file from the server.
btnEnter = findViewById(R.id.btn_enter)
btnEnter.setOnClickListener {
val gson = Gson().toJson(authorization)
val message = gson.toByteArray(StandardCharsets.UTF_8)
val url = URL("my URL")
val responseServer: String?
val progressBar = AlertDialog.Builder(this)
progressBar.setCancelable(false)
progressBar.setView(R.layout.progress_bar)
dialog = progressBar.create()
dialog.show()
if (isOnline(this)) {
responseServer = sendJson(url, message)
if (responseServer != null){
responseAuthorization = Gson().fromJson(responseServer, ResponseAuthorization::class.java)
}else{
Toast.makeText(applicationContext, "Error", Toast.LENGTH_SHORT).show()
val vibration = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibration.vibrate(VibrationEffect.createOneShot(200, VibrationEffect.DEFAULT_AMPLITUDE))
}
} else {
AlertDialog.Builder(this)
.setTitle("No connection")
.setMessage("No connection")
.setPositiveButton("OK"){ _, _ -> finish() }.show()
}
}
and
private fun sendJson(url: URL, message: ByteArray): String?{
var str: String? = null
val t1 = Thread(Runnable {
try {
with(url.openConnection() as HttpURLConnection) {
doInput = true
doOutput = true
requestMethod = "POST"
setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded"
)
setRequestProperty("Accept", "application/json")
DataOutputStream(outputStream).write(message)
if (inputStream != null) {
str = BufferedReader(InputStreamReader(inputStream)).use {
it.readText()
}
}
}
} catch (ex: Exception) {
str = null
println(ex)
}
})
t1.start()
t1.join()
return str
}
Alert dialog appears after the thread is executed. How to make it appear before the thread

No adapter attached; skipping layout kotlin

It loads fine at startup but when I navigate to other fragments and go back to Home Fragment, the recycler view doesn't load anymore. It loads fine with other fragments when I navigate back to it, only the recycler view of Home Fragment doesn't show. There is no error showing in the logcat. Only this W/RecyclerView: No adapter attached; skipping layout. Anyone can help me? I don't know what's really wrong here. Thank you in advance guys.
Here is my code of HOME FRAGMENT
class HomeFragment : Fragment() {
private lateinit var homeViewModel: HomeViewModel
var recyclerView:RecyclerView?=null
lateinit var swipeUpToRefresh:SwipeRefreshLayout
private var viewPager:LoopingViewPager?=null
private var layoutAnimationController:LayoutAnimationController?=null
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
val key = requireArguments().getString("restaurant")
initView(root)
refreshPage()
//bind data
homeViewModel.getPopularList(key!!).observe(viewLifecycleOwner, {
val listData = it
val adapter = MyPopularCategoriesAdapter(requireContext(), listData)
recyclerView!!.adapter = adapter
recyclerView!!.layoutAnimation = layoutAnimationController
})
homeViewModel.getBestDealList(key).observe(viewLifecycleOwner, {
val adapter = MyBestDealsAdapter(requireContext(), it, false)
viewPager!!.adapter = adapter
})
return root
}
private fun refreshPage() {
val key = requireArguments().getString("restaurant")
swipeUpToRefresh.setOnRefreshListener {
//bind data
homeViewModel.getPopularList(key!!).observe(viewLifecycleOwner, {
val listData = it
val adapter = MyPopularCategoriesAdapter(requireContext(), listData)
recyclerView!!.adapter = adapter
recyclerView!!.layoutAnimation = layoutAnimationController
})
homeViewModel.getBestDealList(key).observe(viewLifecycleOwner, {
val adapter = MyBestDealsAdapter(requireContext(), it, false)
viewPager!!.adapter = adapter
})
swipeUpToRefresh.isRefreshing = false
}
}
private fun initView(root:View) {
swipeUpToRefresh = root.findViewById(R.id.refresh) as SwipeRefreshLayout
layoutAnimationController = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_item_from_left)
viewPager = root.findViewById(R.id.viewpager) as LoopingViewPager
recyclerView = root.findViewById(R.id.recycler_popular) as RecyclerView
recyclerView!!.setHasFixedSize(true)
recyclerView!!.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
}
override fun onResume() {
super.onResume()
viewPager!!.resumeAutoScroll()
}
override fun onPause() {
viewPager!!.pauseAutoScroll()
super.onPause()
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}}
I added this line of code to my HomeActivity in R.id.nav_home
val bundle = Bundle()
bundle.putString("restaurant",Common.currentRestaurant!!.uid)
navController.navigate(R.id.nav_home,bundle)
here Is my navView
navView!!.setNavigationItemSelectedListener { p0 ->
p0.isChecked = true
drawer!!.closeDrawers()
if (p0.itemId == R.id.nav_sign_out) {
signOut()
} else if (p0.itemId == R.id.nav_restaurant) {
if (menuItemClick != p0.itemId)
navController.popBackStack()
navController.navigate(R.id.nav_restaurant)
} else if (p0.itemId == R.id.nav_home) {
if (menuItemClick != p0.itemId) {
EventBus.getDefault().postSticky(MenuInflateEvent(true))
navController.popBackStack()
val bundle = Bundle()
bundle.putString("restaurant",Common.currentRestaurant!!.uid)
navController.navigate(R.id.nav_home,bundle)
}
} else if (p0.itemId == R.id.nav_cart) {
if (menuItemClick != p0.itemId) {
EventBus.getDefault().postSticky(MenuInflateEvent(true))
navController.popBackStack()
navController.navigate(R.id.nav_cart)
}
} else if (p0.itemId == R.id.nav_menu) {
if (menuItemClick != p0.itemId) {
EventBus.getDefault().postSticky(MenuInflateEvent(true))
navController.popBackStack()
navController.navigate(R.id.nav_menu)
}
} else if (p0.itemId == R.id.nav_view_order) {
if (menuItemClick != p0.itemId) {
EventBus.getDefault().postSticky(MenuInflateEvent(true))
navController.popBackStack()
navController.navigate(R.id.nav_view_order)
}
} else if (p0.itemId == R.id.nav_update_info) {
showUpdateDialog()
}
menuItemClick = p0.itemId
true
}
Try doing this
private fun initView(root:View) {
swipeUpToRefresh = root.findViewById(R.id.refresh) as SwipeRefreshLayout
layoutAnimationController = AnimationUtils.loadLayoutAnimation(context, R.anim.layout_item_from_left)
viewPager = root.findViewById(R.id.viewpager) as LoopingViewPager
recyclerView = root.findViewById(R.id.recycler_popular) as RecyclerView
//Here is where you need to initialize an adapter to the recyclerView
recylerView!!.adapter = MyPopularCategoriesAdapter(requireContext(), listData) //I'm not sure what is the second argument of your adapter. Feel free to change it as you like.
recyclerView!!.setHasFixedSize(true)
recyclerView!!.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
}

How can an App write and read file in Documents folder?

I wrote an App, in Kotlin with Android Studio that write some strings to a file.
All work, I can write and read inside the App, but I can't see the file looking in Documents folder.
How can I use the folder Documents as a storage space?
Thank you
These are the function I use:
fun saveTextFile(view: View, nomeFile: String, testo: String, contesto: Context){
var fileStream: FileOutputStream
try {
fileStream = contesto.openFileOutput(nomeFile, MODE_APPEND) // OK esegue append
fileStream.write(testo.toByteArray())
fileStream.close()
}catch (e: Exception){
e.printStackTrace()
}
}
fun readTextFile(view: View, nomeFile: String, contesto: Context): String{
var fileInputStream: FileInputStream? = null
fileInputStream = contesto.openFileInput(nomeFile)
var inputStreamReader: InputStreamReader = InputStreamReader(fileInputStream)
val bufferedReader: BufferedReader = BufferedReader(inputStreamReader)
val stringBuilder: StringBuilder = StringBuilder()
var text: String? = null
while ({ text = bufferedReader.readLine(); text }() != null) {
stringBuilder.append(text)
}
inputStreamReader.close();
return(stringBuilder.toString())
}
Thank you, Livio
For writing in Documents folder of your device , you just need to make use of MediaStore for the same. You can take input for this function anything that you want like String , bitmap , PdfDocument and other's too .
For Your UseCase you can do the following ,
Global Variable :
private var imageUri: Uri? = null
override suspend fun saveDocument(context : Context, text : String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "$date.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}")
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
}
val imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out -> out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
For Updating the already existing file , do the following . After creating file for the first time I have saved the imageUri in a global variable (If you want to store it permanently / or for a while you can use Jetpack Datastore / Shared Preference to save the same ):
suspend fun updateData(context: Context,text : String){
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
For Reading the File , Do the following :
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
This is how the final code looks like :
class MainActivity : AppCompatActivity() {
private lateinit var btn: Button
private var imageUri: Uri? = null
private lateinit var btn2: Button
private lateinit var btn3 : Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btn = findViewById(R.id.btnAdd)
btn2 = findViewById(R.id.getText)
btn3 = findViewById(R.id.updateText)
btn.setOnClickListener {
lifecycleScope.launch {
saveDocument(applicationContext, "Original ")
}
}
btn3.setOnClickListener {
lifecycleScope.launch {
updateData(applicationContext,"Appended")
}
}
btn2.setOnClickListener {
lifecycleScope.launch {
imageUri?.let { it1 ->
val data = read(applicationContext, it1)
Toast.makeText(applicationContext, "The data is $data ", Toast.LENGTH_LONG)
.show()
}
}
}
}
suspend fun saveDocument(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val date = System.currentTimeMillis()
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
imageUri = context.contentResolver.insert(collection, contentValues)
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "w").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun updateData(context: Context, text: String) {
withContext(Dispatchers.IO) {
try {
val collection =
MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val dirDest = File(
Environment.DIRECTORY_DOCUMENTS,
context.getString(R.string.app_name)
)
val fileName = "test.txt"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(
MediaStore.MediaColumns.RELATIVE_PATH,
"$dirDest${File.separator}"
)
put(MediaStore.Files.FileColumns.IS_PENDING, 1)
}
withContext(Dispatchers.IO) {
imageUri?.let { uri ->
context.contentResolver.openOutputStream(uri, "wa").use { out ->
out?.write(text.toByteArray())
}
contentValues.clear()
contentValues.put(MediaStore.Files.FileColumns.IS_PENDING, 0)
context.contentResolver.update(uri, contentValues, null, null)
}
}
} catch (e: FileNotFoundException) {
null
}
}
}
suspend fun read(context: Context, source: Uri): String = withContext(Dispatchers.IO) {
val resolver: ContentResolver = context.contentResolver
resolver.openInputStream(source)?.use { stream -> stream.readText() }
?: throw IllegalStateException("could not open $source")
}
private fun InputStream.readText(charset: Charset = Charsets.UTF_8): String =
readBytes().toString(charset)
I have three buttons . With the first I create a file , then the uri gets stored in the global variable . Then onClick of second button I add to the already existing file and then read the file using the third button using the same imageUri stored in the global variable
This is the demo for the same . Check when the buttons are being pressed and the output in the form of Toast at the bottom .

The step counter sensor is not working for my app. Could you please tell me what the problem is? I have been trying to debug this for days now

TYPE_STEP_COUNTER is not working with this code. Could anyone please tell me what is wrong.
My min sdk is 19 and target sdk is 30. I have also tried using TYPE_STEP_COUNTER instead number of 19 but it still does not work. Please help!!
I have been trying to debug this for hours now. I am using pixel 3 to test this and I see that the required sensor is here but for some reason this is not working.
class MainActivity : AppCompatActivity(), SensorEventListener, View.OnClickListener {
var running = false
private var sensorManager: SensorManager? = null
lateinit var sharebutton: Button
lateinit var goalnum: Button
lateinit var et: EditText
lateinit var tv: EditText
lateinit var progress: ProgressBar
lateinit var step2: EditText
var steps=0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.mainlayout)
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sharebutton = findViewById(R.id.share) as Button
tv = findViewById(R.id.tv) as EditText
sharebutton.setOnClickListener(this)
goalnum = findViewById(R.id.goalnum) as Button
goalnum.setOnClickListener(this)
val circularProgressBar = findViewById<CircularProgressBar>(R.id.progressBar)
val toolbar = findViewById(R.id.tbar) as Toolbar?
setSupportActionBar(toolbar)
getSupportActionBar()?.setTitle("");
//manualInc()
}
override fun onResume() {
//manualInc()
Toast.makeText(this, "I am in", Toast.LENGTH_SHORT).show()
super.onResume()
running = true;
var StepSensor = sensorManager?.getDefaultSensor(19)
if (StepSensor == null) {
Toast.makeText(this, "No Step Counter Sensor !", Toast.LENGTH_SHORT).show()
} else {
sensorManager?.registerListener(this, StepSensor, SensorManager.SENSOR_DELAY_UI)
}
}
fun manualInc(){
steps =100
var step2 = tv.getText().toString().toInt()
var steps3 = (step2 - steps)
tv_steps.setText("" + steps.toInt())
if (steps3 > 0) {
tv_steps2.setText("" + (steps3).toInt());
} else {
tv_steps2.setText("Goal Reached!");
}
val currentsteps = step2 - steps.toInt()
progressBar.apply{
setProgressWithAnimation(currentsteps.toFloat())
}
if(steps> step2) {
Toast.makeText(this, "GOAL REACHED!!! Amazing job!", Toast.LENGTH_LONG).show()
}
}
override fun onPause() {
super.onPause()
running = true;
var StepSensor = sensorManager?.getDefaultSensor(19)
if (StepSensor == null) {
Toast.makeText(this, "No Step Counter Sensor !", Toast.LENGTH_SHORT).show()
} else {
sensorManager?.registerListener(this, StepSensor, SensorManager.SENSOR_DELAY_UI)
}
}
override fun onClick(view: View?) {
when (view?.id) {
R.id.goalnum -> {
var goalcount = tv.getText().toString().toDouble()
userinput.setText("" + goalcount.toInt())
Toast.makeText(this, "Great goal!", Toast.LENGTH_LONG).show()
}
R.id.share -> {
val sendIntent: Intent = Intent().apply {
var goalcount = tv.getText().toString().toInt()
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
"I am on my way to reaching my goal of " + goalcount + " daily steps! Join me on Step Counter and Tracker"
)
type = "text/plain"
}
startActivity(Intent.createChooser(sendIntent, null))
}
}
}
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
}
override fun onSensorChanged(event: SensorEvent) {
Toast.makeText(this, "I am i", Toast.LENGTH_LONG).show()
if (running) {
val steps = (event.values[0])
var step2 = tv.getText().toString().toInt()
var steps3 = (step2 - steps)
tv_steps.setText("" + steps.toInt())
if (steps3 > 0) {
tv_steps2.setText("" + (steps3).toInt());
} else {
tv_steps2.setText("Goal Reached!");
}
val currentsteps = step2 - steps.toInt()
progressBar.apply{
setProgressWithAnimation(currentsteps.toFloat())
}
if(steps> step2) {
Toast.makeText(this, "GOAL REACHED!!! Amazing job!", Toast.LENGTH_LONG).show()
}}}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater: MenuInflater = menuInflater
inflater.inflate(R.menu.menu, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle presses on the action bar menu items
when (item.itemId) {
R.id.action_one -> {
val intent = Intent(this, MainActivity::class.java)
finishAffinity();
startActivity(intent)
}
R.id.action_two -> {
val intent = Intent(this, ExerciseHistory::class.java)
startActivity(intent)
}
R.id.action_three -> {
val intent = Intent(this, ViewListContents::class.java)
startActivity(intent)
}
R.id.action_four -> {
val intent = Intent(this, StepHistory::class.java)
startActivity(intent)
}
R.id.action_five -> {
val intent = Intent(this, Help::class.java)
startActivity(intent)
Toast.makeText(
this,
"Please leave feedback!",
Toast.LENGTH_SHORT
).show()
}
}
return super.onOptionsItemSelected(item)
}
}

how to fix conversion error when converting from java to kotlin

I am a student, new to kotlin, so I am converting java codes to kotlin to learn and see how it works, but I didnt understand what the error says.
private val _songs = ArrayList<SongInfo>()
internal lateinit var recyclerView: RecyclerView
internal lateinit var seekBar: SeekBar
internal lateinit var songAdapter: SongAdapter
internal var mediaPlayer: MediaPlayer? = null
private val myHandler = Handler()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView = findViewById(R.id.recyclerView) as RecyclerView
seekBar = findViewById(R.id.seekBar) as SeekBar
songAdapter = SongAdapter(this, _songs)
recyclerView.adapter = songAdapter
val linearLayoutManager = LinearLayoutManager(this)
val dividerItemDecoration = DividerItemDecoration(recyclerView.context,
linearLayoutManager.orientation)
recyclerView.layoutManager = linearLayoutManager
recyclerView.addItemDecoration(dividerItemDecoration)
songAdapter.setOnItemClickListener { b, view, obj, position ->
if (b.text == "Stop") {
mediaPlayer!!.stop()
mediaPlayer!!.reset()
mediaPlayer!!.release()
mediaPlayer = null
b.text = "Play"
} else {
val runnable = Runnable {
try {
mediaPlayer = MediaPlayer()
mediaPlayer!!.setDataSource(obj.songUrl)
mediaPlayer!!.prepareAsync()
mediaPlayer!!.setOnPreparedListener { mp ->
mp.start()
seekBar.progress = 0
seekBar.max = mediaPlayer!!.duration
Log.d("Prog", "run: " + mediaPlayer!!.duration)
}
b.text = "Stop"
} catch (e: Exception) {
}
}
myHandler.postDelayed(runnable, 100)
}
}
checkUserPermission()
val t = runThread()
t.start()
}
inner class runThread : Thread() {
override fun run() {
while (true) {
try {
Thread.sleep(1000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
Log.d("Runwa", "run: " + 1)
if (mediaPlayer != null) {
seekBar.post { seekBar.progress = mediaPlayer!!.currentPosition }
Log.d("Runwa", "run: " + mediaPlayer!!.currentPosition)
}
}
}
}
private fun checkUserPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 123)
return
}
}
loadSongs()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
123 -> if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
loadSongs()
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
checkUserPermission()
}
else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
private fun loadSongs() {
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
val selection = MediaStore.Audio.Media.IS_MUSIC + "!=0"
val cursor = contentResolver.query(uri, null, selection, null, null)
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
val name = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME))
val artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST))
val url = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA))
val s = SongInfo(name, artist, url)
_songs.add(s)
} while (cursor.moveToNext())
}
cursor.close()
songAdapter = SongAdapter(this#MainActivity, _songs)
}
}
}
This is the error:
"Error:(46, 44) Type mismatch: inferred type is (???, ???, ???, ???)
-> Any but SongAdapter.OnItemClickListener was expected Error:(46, 46) Cannot infer a type for this parameter. Please specify it explicitly."
Batch conversion to Kotlin is not the best way to learn the language. I suggest you to re-implement your Android component in Kotlin manually, to get the feeling of language.
The error you see says: "I can not understand how this lambda with 4 parameters can be an instance of SongAdapter.OnItemClickListener, please help". You can try anonymous class in this place.

Resources