skip to Main Content

I have the following function pinAppWidget which I am using in MainActivity but I would need to be able to use it also in ConfigurableWidgetConfigureActivity to not have a duplicate of the function I would like to create a class that contains them.

But I’m having some problems.

Code original:

    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )

            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@MainActivity,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@MainActivity, MyWidget::class.java)


            val pinnedWidgetCallbackIntent = Intent(this@MainActivity, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@MainActivity, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

Class function:


import android.app.Activity
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.content.ComponentName
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.Toast

class function : Activity() {
    fun pinAppWidget(text: String?) {
        val urlCode = extractLinks(text)
        if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val mAppWidgetManager = getSystemService(
                AppWidgetManager::class.java
            )
            if (!mAppWidgetManager.isRequestPinAppWidgetSupported) {
                Toast.makeText(
                    this@function,
                    "Pin app widget is not supported",
                    Toast.LENGTH_SHORT
                ).show()
                return
            }

            val myProvider = ComponentName(this@function, MyWidget::class.java)
            val pinnedWidgetCallbackIntent = Intent(this@function, MyWidget::class.java)
            val successCallback = PendingIntent.getBroadcast(
                this@function, 0,
                pinnedWidgetCallbackIntent, PendingIntent.FLAG_IMMUTABLE
            )
            mAppWidgetManager.requestPinAppWidget(myProvider, Bundle(), successCallback)
        }
    }

    fun extractLinks(text: String?): String {
        val index = text!!.lastIndexOf("/")
        return text.substring(index + 1)
    }

}

When I call inside the MainActivity function I get the following problem:

enter image description here

How can I do it, can you help me?

3

Answers


  1. you could put pinAppWidget method into an object, so you can easy call it in both Activity:

    class function : Activity() {
        fun pinAppWidget(text: String?){}
    }
    
    //convert to
    object function {
        fun pinAppWidget(text: String?, activity: Activity){}
    }
    

    Another way, you could create BaseActivity and put pinAppWidget into it. Then make your MainActivity extend BaseActivity, you can easy call pinAppWidget from here

    class BaseActivity : AppCompatActivity() {
       fun pinAppWidget (){}
    }
    
    class MainActivity : BaseActivity() {
       //call pinAppWidget()
    }
    
    Login or Signup to reply.
  2. You can pass the Context object as a parameter to the pinAppWidget function in the function class.

    import android.app.PendingIntent
    import android.appwidget.AppWidgetManager
    import android.content.ComponentName
    import android.content.Context
    import android.content.Intent
    import android.os.Build
    import android.os.Bundle
    import android.widget.Toast
    
    class MyWidgetFunction {
        fun pinAppWidget(context: Context, text: String?) {
            val urlCode = extractLinks(text)
            if (urlCode != "" && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val mAppWidgetManager = context.getSystemService(
                    AppWidgetManager::class.java
                )
                // Rest of your code...
            }
        }
    
        private fun extractLinks(text: String?): String {
            val index = text!!.lastIndexOf("/")
            return text.substring(index + 1)
        }
    }
    

    Now you can use the MyWidgetFunction class in both MainActivity and ConfigurableWidgetConfigureActivity. When calling the pinAppWidget function, make sure to pass the appropriate Context object.

    In MainActivity:

    val myWidgetFunction = MyWidgetFunction()
    myWidgetFunction.pinAppWidget(this, text)
    

    In ConfigurableWidgetConfigureActivity:

    val myWidgetFunction = MyWidgetFunction()
    myWidgetFunction.pinAppWidget(this, text)
    

    Note: Make sure to replace MyWidget with the actual name of your widget class.

    Login or Signup to reply.
  3. This questions covers at least two things: architecture decision and android platform limitations.

    From software architecture perspective you could:

    • create a common parent class and put this and the rest common logic inside; other activities will extend this class and inherit its behaviour.
    • create utility class to encapsulate common logic and instantiate this class within each activity.
    • inner classes (aka object: in kotlin) could be an alternative to this two options.
    • kotlin also provide such things as extensions which could a fourth way to achieve your task.

    From Android platform perspective component code should be called only from component (Activity, Service, BroadcastReceiver, ContentProvder). Your function uses component code (mAppWidgetManager.requestPinAppWidget(...)) and it would be good to keep it within component and do not put outside. Although, it is still possible to put it into a separate class and pass a context to run this code.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search