如何使用我的 Flutter 应用程序从另一个应用程序打开具有自定义文件扩展名的文件? [英] How to open a file with a custom file extension from another app with my Flutter app?

查看:54
本文介绍了如何使用我的 Flutter 应用程序从另一个应用程序打开具有自定义文件扩展名的文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将我的 Flutter 应用与文件类型 .foo 相关联.例如,如果用户打开他们的本地文件管理器,然后点击文件 bar.foo android 会提示他们使用我的 flutter 应用程序打开文件.

I need my Flutter app to be associated with the file type .foo. So that if a user opens their local file manager for example, and clicks on the file bar.foo android prompts them to open the file with my flutter app.

到目前为止,我了解到,这基本上是一个传入的 Android 意图,必须使用所谓的 intent-filter 进行注册,如下所述:创建打开自定义文件扩展名的应用.但更进一步,我不明白如何在 Kotlin 中处理它.

So far I understand, that this is basically an incoming Android intent which has to be registered with a so called intent-filter as described here: Creating app which opens a custom file extension. But further, I do not understand how to handle it in Kotlin.

因此,下一个合乎逻辑的事情是找出 传入意图如何在 Flutter 中工作.然而,该文档对我没有帮助,因为它仅在 Java 而不是 Kotlin.我完全没有使用 Java 的经验,无论如何我想坚持使用 Kotlin,因为我有其他平台特定的代码是用 Kotlin 编写的.

Therefore the next logical thing would be to find out how incoming intents work in Flutter. The documentation however doesn't help me, as it is explained only in Java and not Kotlin. I have no experience with Java at all and would like to stick to Kotlin anyway, because I have other platform specific code written in Kotlin.

在这篇文章中 Deep Shah 似乎有同样的问题,但没有分享解决方案:支持自定义文件扩展名在颤振应用程序中(在颤振中打开扩展名为 .abc 的文件).

In this post Deep Shah seems to have the same problem, but doesn't share the solution: Support custom file extension in a flutter app ( Open file with extension .abc in flutter ).

Shanks 的这篇帖子悄然逝去:打开使用 Flutter App 自定义文件扩展名.

This post by Shanks died quietly: Open custom file extension with Flutter App.

我希望找到相关资源的答案或指示.

I hope to find answers or pointers to relevant resources.

推荐答案

找到了适用于 android 的解决方案.这篇文章应该将所有重要的步骤捆绑在一起.以 YOUR_ 开头的内容取决于您.相应地更改它们.

I found a solution for android. This post should bundle all important steps into one. The things starting with YOUR_ are dependant on you. Change them accordingly.

首先,您必须在AndroidManifest.xml 中注册intent-filter.这将告诉 android 将您的应用列为可能的选项.

First, you have to register the intent-filter in the AndroidManifest.xml. This will tell android to list your app as a possible option.

<!-- TODO: CHANGE ICON AND LABEL HERE -->  
<intent-filter android:icon="YOUR_ICON_LOCATION"                  
               android:label="YOUR_APP_LABEL"
               android:priority="1">
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <data android:scheme="content" />
    <data android:scheme="http" />
    <data android:scheme="file" />
    <data android:mimeType="*/*" />
    <!-- TODO: CHANGE FILE EXTENSION -->  
    <data android:pathPattern=".*\\.YOUR_FILE_EXTENSION" />
</intent-filter>

接下来,设置您的 Android 方法频道.为此,在 Kotlin 中是这样完成的:

Next, set up your Android Method Channel. For this, in Kotlin it is done like so:

import io.flutter.embedding.android.FlutterActivity
import android.content.Intent
import android.os.Bundle
import androidx.annotation.NonNull
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant

class MainActivity : FlutterActivity() {
    // TODO: CHANGE METHOD CHANNEL NAME
    private val CHANNEL = "YOUR_CHANNEL_NAME"

    var openPath: String? = null
    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        GeneratedPluginRegistrant.registerWith(flutterEngine)
        val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
        channel.setMethodCallHandler { call, result ->
            when (call.method) {
                "getOpenFileUrl" -> {
                    result.success(openPath)
                }
                else -> result.notImplemented()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleOpenFileUrl(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleOpenFileUrl(intent)
    }

    private fun handleOpenFileUrl(intent: Intent?) {
        val path = intent?.data?.path
        if (path != null) {
            openPath = path
        }
    }
}

最后,在事物的 dart 方面设置一个处理程序.以下代码必须在绘制的 Widget 中.我把它放在我的 MainView 小部件中,因为它总是在应用启动时绘制,并且在小部件树中相对较高.(对我来说,它是 MaterialApp Widget 之外的第一个 Widget)

Finally, set up a handler on the dart side of things. The following code has to be in a drawn Widget. I placed it into my MainView widget, as it is always drawn on app startup and is relatively high up in the Widget tree. (For me it is the first Widget outside the MaterialApp Widget)

class MainView extends StatefulWidget {
  const MainView({Key key}) : super(key: key);

  @override
  _MainViewState createState() => _MainViewState();
}

class _MainViewState extends State<MainView> with WidgetsBindingObserver {
  // TODO: CHANGE CHANNEL NAME
  static const platform = const MethodChannel("YOUR_CHANNEL_NAME");
 
  @override
  void initState() {
    super.initState();
    getOpenFileUrl();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      getOpenFileUrl();
    }
  }

  @override
  Widget build(BuildContext context) {
    // TODO: Implement Build Method
  }

  void getOpenFileUrl() async {
    dynamic url = await platform.invokeMethod("getOpenFileUrl");

    if (url != null) {
      setState(() {
        // TODO: DO SOMETING WITH THE FILE URL
      });
    }
  }
}

在完全杀死并重新启动我的应用程序和外部应用程序(在我的情况下是文件管理器)后,它工作了.

After completely killing and restarting both my app and the external app (in my case the file manager) it worked.

这篇关于如何使用我的 Flutter 应用程序从另一个应用程序打开具有自定义文件扩展名的文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆