skip to Main Content

First, I’d like to start by clarifying that I do not believe this is a duplicate of android: React native open an app from another app?. I have some examples of why not below.

I’m writing a plugin for an app that injects code into another React Native app. I can run any JavaScript code but cannot modify the Java or use packages that do so since the app is already compiled.

The goal of the plugin is to launch another app when the user does something. I plan on using Schema URLs for apps that support them, but I’d also like to open the apps that don’t have that.

Android support is all that I need currently, however I may add iOS support in the future some other way.

I think that the Linking.sendIntent function is what I need. The problem is that I have found no documentation on how to launch an app with this. Additionally, I can use either the app name, package name, really anything.

I did try asking a few AI assistants for help on this matter and they suggested to use Linking.openUrl with the intent:// schema, however this didn’t at all work.

2

Answers


  1. An intent is a petition sent globally, to any and all apps able to handle it. It is the equivalent of yelling for help. If you want to receive help from a particular person, you need to yell their name. Likewise, if you want to open an specific app, you need to know the intents that app will respond to. For example, if you want to open whatsapp:

    var url = "https://api.whatsapp.com/send?phone="+number
    var intent = Intent(Intent.ACTION_VIEW)
    i.setData(Uri.parse(url));
    startActivity(i);
    

    Or:

    await sendIntent('ACTION_VIEW',
      ['https://api.whatsapp.com/send?phone='+number],
    )
    

    Every app has a launch intent. You would need to check those and store them so you can invoke them directly. Alternatively, you may try to obtain data about the installed apps using the packageManager, but recent SDKs forbid you from getting info about other apps, so it may not work.

    Edit: Expanding the last point, you can do this:

    var packageManager = getPackageManager()
    Intent intent = Intent(Intent.ACTION_MAIN, null)
    var result = packageManager.queryIntentActivities(intent, 0)
    

    However, you will need to specify the query type (in this case, the launch intent) you want to get, and, likely, ask permission. This answer has the detail you need:

    NameNotFoundException when calling getPackageInfo on Android 11

    Otherwise, you will have to gather the intents manually and put them into the app.

    Login or Signup to reply.
  2. Since you asked how to do this within ReactNative, then:
    I think by reading this https://reactnavigation.org/docs/deep-linking/ section from the react-navigation module which is very popular for handling navigation in react-native apps, you will find your answer.

    Long story short:
    By injecting this linking to the outer tag NavigationContainer as shown below

        import * as Linking from 'expo-linking';
    
    const prefix = Linking.createURL('/');
    
    function App() {
      const linking = {
        prefixes: [prefix],
      };
    
      return (
        <NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
          {/* content */}
        </NavigationContainer>
      );
    }
    

    Also, remember to register this new intent to your AndroidManifest.xml:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="mychat" />
        </intent-filter>
    </activity>
    

    Finally, you can test it with adb:

    adb shell am start -W -a android.intent.action.VIEW -d [your deep link] [your android package name]
    

    Hope that might help!

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