如何在Android上使用React Native启动应用程序?

huangapple go评论141阅读模式
英文:

How to launch an app on Android using React Native?

问题

首先,我想澄清一下,我不认为这是android: React Native打开另一个应用程序的重复问题。我有一些下面的例子可以说明为什么不是重复问题。

我正在为一个应用程序编写一个插件,该插件将代码注入到另一个React Native应用程序中。我可以运行任何JavaScript代码,但无法修改Java代码或使用这样做的包,因为该应用程序已经编译完成。

插件的目标是在用户执行某些操作时启动另一个应用程序。我计划使用支持Schema URL的应用程序,但我还想打开那些不支持的应用程序。

目前,我只需要Android支持,但将来可能以其他方式添加iOS支持。

我认为Linking.sendIntent函数是我所需要的。问题是我找不到如何使用它来启动应用程序的文档。此外,我可以使用应用程序名称、包名称或任何其他信息。

我曾尝试向几个AI助手寻求帮助,他们建议使用Linking.openUrlintent://模式,但这根本不起作用。

英文:

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.

答案1

得分: 0

意图是一种全局发送的请求,可以发送给任何能够处理它的应用程序。这相当于呼救求助。如果你想从特定的人那里获得帮助,你需要喊出他们的名字。同样,如果你想打开一个特定的应用程序,你需要知道该应用程序将响应的意图。例如,如果你想要打开 WhatsApp:

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

或者:

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

每个应用程序都有一个启动意图。您需要检查这些并存储它们,以便可以直接调用它们。或者,您可以尝试使用packageManager获取已安装应用程序的信息,但是最近的SDK禁止您获取关于其他应用程序的信息,所以可能不起作用。

编辑:扩展上一个观点,您可以这样做:

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

但是,您需要指定要获取的查询类型(在这种情况下是启动意图),并且可能需要请求权限。这个答案有您需要的详细信息:

https://stackoverflow.com/questions/62345805/namenotfoundexception-when-calling-getpackageinfo-on-android-11

否则,您将不得不手动收集意图并将它们放入应用程序中。

英文:

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:

https://stackoverflow.com/questions/62345805/namenotfoundexception-when-calling-getpackageinfo-on-android-11

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

答案2

得分: 0

由于你要求在React Native中进行翻译,以下是已翻译的内容:

自从你询问如何在React Native中完成这个操作,那么:
我认为通过阅读react-navigation模块中的https://reactnavigation.org/docs/deep-linking/部分,该模块在处理React Native应用程序中的导航时非常流行,你将找到你的答案。

长话短说:
通过将以下链接注入到外部标签NavigationContainer中,如下所示

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>
  );
}

还要记得在你的AndroidManifest.xml中注册这个新的intent:

<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>

最后,你可以使用adb进行测试:

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

希望这对你有所帮助!

英文:

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!

huangapple
  • 本文由 发表于 2023年6月26日 05:28:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76552479.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定