Open Yatse from another app using API

Hello, I’m an Android developer who is creating an app interacting with a streaming service. I’d like to add an “open with” button to start playing from yatse.

I’ve tried using the APIs on https://yatse.tv/wiki/yatse-api but I can’t get it to work.

I already have a “share” button which let me select yatse and it’s already working.

I know the correct one should be

val intent = Intent().apply {
                action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
                putExtra("org.leetzone.android.yatsewidget.EXTRA_STRING_PARAMS", url)
            }

intent.startService(intent)

but the package is not found, I think because after deprecating the unlocker the correct package is org.leetzone.android.yatsewidget

Thisi s the code I’m using to test other explicit intents:

override fun onOpenWith(url: String) {
    val pm = requireContext().packageManager

    val intents: List<Intent> = listOf(
        pm.getLaunchIntentForPackage("org.leetzone.android.yatsewidgetfree")!!.apply {
            action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
            data = Uri.parse(url)
        },
        pm.getLaunchIntentForPackage("org.leetzone.android.yatsewidgetfree")!!.apply {
            action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
            putExtra("org.leetzone.android.yatsewidget.EXTRA_STRING_PARAMS", url)
        },
        Intent().apply {
            action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
            putExtra("org.leetzone.android.yatsewidget.EXTRA_STRING_PARAMS", url)
        },
        Intent().apply {
            action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
            data = Uri.parse(url)
        },
        Intent().apply {
            action = "org.leetzone.android.yatsewidgetfree.ACTION_MEDIA_PLAYURI"
            putExtra("org.leetzone.android.yatsewidget.EXTRA_STRING_PARAMS", url)
        },
        Intent().apply {
            action = "org.leetzone.android.yatsewidgetfree.ACTION_MEDIA_PLAYURI"
            data = Uri.parse(url)
        },
        Intent().apply {
            action = "org.leetzone.android.yatsewidgetfree.ACTION_MEDIA_PLAYURI"
            putExtra("org.leetzone.android.yatsewidgetfree.EXTRA_STRING_PARAMS", url)
        },
    )


    // Verify that the intent will resolve to an activity
    context?.let {
        intents.forEachIndexed { index, intent ->
            if (intent.resolveActivity(it.packageManager) != null) {
                it.showToast("yatseIntent $index")
                it.startService(intent)
            } else {
                if (index == intents.size - 1)
                    it.showToast(R.string.app_not_installed)
            }
        }
    }
}

The passed url is like “https://streaming.com/asdasd
When I use the action org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI I get the package not installed message (since the package is org.leetzone.android.yatsewidgetfree), if I use the yatsewidgetfree action it does not give errors but it also does not start playing

You are mixing a lot of different concepts and maybe need to read some more docs about them.

Action and extra are just raw strings unrelated to packages names.
If you are targeting Android 11 you may need to look into the new query stuff and package visibility https://developer.android.com/about/versions/11/privacy/package-visibility

In all cases you should use a https://developer.android.com/reference/android/content/ComponentName

org.leetzone.android.yatsewidgetfree/org.leetzone.android.yatsewidget.service.core.YatseCommandService

1 Like

Thanks! I tried different things because I could not get it to work following the APIs page.
With your tips, I made it work; if anyone needs it:

  fun onOpenWith(url: String) {
        val yatseIntent = Intent().apply {
            action = "org.leetzone.android.yatsewidget.ACTION_MEDIA_PLAYURI"
            component = ComponentName("org.leetzone.android.yatsewidgetfree", "org.leetzone.android.yatsewidget.service.core.YatseCommandService")
            putExtra("org.leetzone.android.yatsewidget.EXTRA_STRING_PARAMS", url)
        }

        // add this to your manifest queries
        val yatsePackage = requireContext().packageManager
            .getInstalledPackages(PackageManager.GET_META_DATA)
            .firstOrNull { it.packageName == "org.leetzone.android.yatsewidgetfree" }

        if (yatsePackage != null) {
            try {
                context?.startService(yatseIntent)
            } catch (e: IllegalStateException) {
               // android >= 8 has issues, this is a workaround not a solution
                e.printStackTrace()
                context?.showToast(R.string.limitations)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    context?.startForegroundService(yatseIntent)
                }
            }
        } else
            context?.showToast(R.string.app_not_installed)

    }

(showToast is just a kotlin extension to display toasts)

Sadly Android has some issues with calling services in the background. I need to test it more and decide if it works often enough -> https://developer.android.com/about/versions/oreo/background.html

startForegroundService is a solution :slight_smile:

Just use https://developer.android.com/reference/androidx/core/content/ContextCompat#startForegroundService(android.content.Context,%20android.content.Intent) as it’s meant to :wink:

Start to feel like Android teacher :stuck_out_tongue:

Nice, that’s shorter (but hey, it works the same). Maybe you could add a line about org.leetzone.android.yatsewidget.service.core.YatseCommandService in the API page since I definitely couldn’t guess it (unless I missed it somehow… totally possible)

Can you also give a hint about org.leetzone.android.yatsewidget.ACTION_APP_SHOW_HOME? I can’t seem to make it work with the same parameters

val yatseRemoteIntent = Intent().apply {
            action = "org.leetzone.android.yatsewidget.ACTION_APP_SHOW_HOME"
            component = ComponentName(
                "org.leetzone.android.yatsewidgetfree",
                "org.leetzone.android.yatsewidget.service.core.YatseCommandService")
}

ContextCompat.startForegroundService(requireContext(), yatseRemoteIntent)

What does “can’t seem to make it work” means ? :slight_smile:
Proper description and logs are better.

My bad, it simply does not do anything. It does not pop up to the front, but also there are no crashes so I don’t have a log.
The action ACTION_MEDIA_PLAYURI works with the code above (almost every time).
I tried opening yatse and putting it in the background so I know it’s still working but it did nothing.

There’s always logs no need for crash.