如何仅通过包名编程方式打开Flutter应用程序

7
我试图通过包名打开另一个Flutter应用程序,而不是进行深度链接,只是简单地打开已经安装在设备上的应用程序。同时还想分享一些数据并在Flutter应用程序中接收它们。
我的第一个(本地)应用程序调用了我的Flutter应用程序,并传递了一些文本数据:
var intent = context.packageManager.getLaunchIntentForPackage(packageName)
    if (intent == null) {
        intent = Intent(Intent.ACTION_VIEW)
        intent.data = Uri.parse("market://details?id=$packageName")
        val bundle = Bundle()
        bundle.putString("user_id", "1111")
        intent.putExtra("data", bundle)
        intent.setType("text/plain")
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    context.startActivity(intent)

我正在使用 method-channel 进行操作。
class _MyHomePageState extends State<MyHomePage> {

      static const methodChannel = MethodChannel("samples.flutter.dev/battery");
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              children: <Widget>[
                ElevatedButton(
                    onPressed: () async {
                      openApp();
                    },
                    child: Text("Please work this time"))
              ],
            ),
          ),
        );
      }
    
      static Future<bool?> openApp() async {
        return await methodChannel.invokeMethod<bool>("getOpenApp");
      }
    }

现在Activity类是这样的:-
class MainActivity : FlutterActivity() {
//private var sharedText: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val intent = intent
    val action = intent.action
    val type = intent.type
    if (Intent.ACTION_SEND == action && type != null) {
        if ("text/plain" == type) {
           // handleSendText(intent) // Handle text being sent
        }
    }
}
private val CHANNEL = "samples.flutter.dev/battery"

override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
    GeneratedPluginRegistrant.registerWith(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        .setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
            if (call.method.contentEquals("getOpenApp")) {
                var userId = "No data received"
                val bundle: Bundle? = intent.getBundleExtra("data");
                //val bundle = intent.getBundleExtra("data");
            
                if (bundle!=null){
                    userId = bundle.getString("user_id").toString()
                    Log.d("userid","is equals to: $userId")
                    System.out.print("userid ki value : $userId")
                }else{
                    Log.d("empty","is equals to: empty hai ")
                }
                result.success(200)
                //sharedText = null
            }
        }
}

请告诉我我在这里犯了什么错误,因为每次都会得到空的包裹。

如果这不起作用,您可以使用https://pub.dev/packages/external_app_launcher。 - Ruchit
如果我使用这个库,它不能满足要求。我无法通过意图传递任何数据。 - Devraj
你想通过Intent传递数据吗?Intent仅适用于Android而不适用于iOS。那么,你想要一个通用的代码来管理在两个操作系统上共享数据,还是你只需要适用于Android的代码? - Dharam Budh
@DharamBudh 是的,我想编写通用代码,因为我也必须在IOS上执行此操作。但是,由于我不确定在Dart中如何实现它,所以我正在使用本机语言进行操作。如果有任何通用的方法,将不胜感激。 - Devraj
4个回答

1
在我的案例中,我使用这个函数。
public void startNewActivity(Context context, String packageName) {
    Intent intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
    if (intent == null) {
        // Bring user to the market or let them choose an app?
        intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("market://details?id=" + packageName));
    }
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

当我设置标志Intent.FLAG_ACTIVITY_NEW_TASK时,它起作用了!

我使用了这段代码,但是没有起作用。 - Devraj

1
更加简单的方法是使用这个包。 https://pub.dev/packages/external_app_launcher
await LaunchApp.openApp(
              androidPackageName: 'net.pulsesecure.pulsesecure',
              iosUrlScheme: 'pulsesecure://',
              appStoreLink: 'itms-apps://itunes.apple.com/us/app/pulse-secure/id945832041',
              // openStore: false
            );

如果我们使用这个,能否通过意图从一个应用程序解析数据到另一个应用程序? - Devraj

0

在Android中,您可以使用adb命令行工具打开应用程序。

使用adb,您可以执行许多酷炫的操作,如端口转发、启动活动、安装、卸载等等。

但是要想打开此应用程序,您只需运行以下命令即可。

adb shell am start -n "<package name>/<path to your main activity class>" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER

在此命令中,我们使用shell进入移动设备的shell,然后使用am(活动管理器)启动新活动。

在我们的情况下,我们需要启动应用程序,因此每个应用程序都有一个启动器活动。我们只需启动它,就可以启动应用程序了。


1
请先仔细阅读问题并理解其所询问的内容。 - Devraj

0

这应该相对容易,

考虑你有两个应用程序,app1和app2,你必须从app1打开app2 1- 在app2中,在清单文件中指定自定义意图

<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="<your-custom-scheme>"
             # if accept any data from u can specify them in the host, 
             path and port(if u have specific ones)
             # android:host="<your-host>"
             # android:port="<your-port>"
             />
</intent-filter>

在您的app1中,您可以直接启动上述意图来打开您的app2。
  • 您可以使用本地代码来实现,或者更简单的方法是使用url_launcher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接