Search code examples
androidkotlinandroid-jetpack-composemanifestwordpress-jetpack

Launching another Android app after button click in Kotlin Jetpack Compose


I am new to Android development. I would like to ask a question, this code works to open the settings app once I click on the button. I would like to the same for the following demo app https://github.com/Picovoice/porcupine/tree/master/demo/android/Activity installed in my phone. Why doesnt it open? Do I need to add something to my manifest file? Thanks a lot in advance.

This is the code that works without issues for package name "com.android.settings" but does not work for "com.android.youtube"

package com.example.jkfdsjlk

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.example.jkfdsjlk.ui.theme.JkfdsjlkTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            JkfdsjlkTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    MyApp(
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
}

@Composable
fun OpenAppButton() {
    val context = LocalContext.current

    // Create a launcher for activity result
    val launcher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult()
    ) { }

    Button(
        onClick = {
            // Intent to open another app
            val intent = context.packageManager.getLaunchIntentForPackage("ai.picovoice.porcupine.demo")

            // Check if the intent is not null and launch the app
            intent?.let {
                launcher.launch(intent)
            }
        },
        modifier = Modifier
            .padding(16.dp)
            .fillMaxWidth(),
        content = {
            Text(text = "Open Another App")
        }
    )
}

@Composable
fun MyApp(modifier: Modifier) {
    Surface(color = MaterialTheme.colorScheme.background) {
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(16.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            OpenAppButton()
        }
    }
}

Solution

  • If you call methods on PackageManager like getLaunchIntentForPackage(), you need to consider what changes you may need in your manifest to comply with package visibility rules on Android 11 and higher.

    In your case, declaring your specific package name should work:

    <queries>
        <package android:name="ai.picovoice.porcupine.demo" />
    </queries>