首页 > 解决方案 > 如何使用 Flutter 应用程序从文件管理器打开(音频)文件

问题描述

当用户尝试从他/她的文件管理器打开音频文件时,我想在以下“在哪个应用程序中打开此文件”弹出窗口中向他/她展示我的应用程序。在(s)他从弹出窗口中选择我的应用程序之后,我想将文件路径传递给状态变量(currentSong)。

我已经设法将以下 IntentFilter 添加到我的 AndroidManifest.xml 中。这应该在弹出窗口中正确地向用户显示我的应用程序:

<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="http" />
    <data android:scheme="content" />
    <data android:scheme="file" />
    <data android:mimeType="audio/*" />
    <data android:mimeType="application/ogg" />
    <data android:mimeType="application/x-ogg" />
    <data android:mimeType="application/itunes" />
</intent-filter>

但现在我只是一无所知。如何获取文件路径并将其保存到currentSongFlutter 中的状态变量中?

标签: androidflutter

解决方案


你需要使用ChannelPlatform来做到这一点:

1.安卓端:

   Handle onCreate + onNewIntent to get bundle data from File Viewer App that share audio file's path

2.颤振侧:

  get audio file's path and do something...

演示:

Demo 与 Flutter 共享文件 url

示例

安卓

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

class MainActivity : FlutterActivity() {
    private val CHANNEL = "tinyappsteam.flutter.dev/open_file"

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

扑:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
  static const platform =
      const MethodChannel('tinyappsteam.flutter.dev/open_file');

  String openFileUrl;

  @override
  void initState() {
    super.initState();
    getOpenFileUrl();
    // Listen to lifecycle events.
    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) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Text("Audio file: " + (openFileUrl != null ? openFileUrl : "Nothing!")),
      ),
    );
  }

  void getOpenFileUrl() async {
    dynamic url = await platform.invokeMethod("getOpenFileUrl");
    print("getOpenFileUrl");
    if (url != null && url != openFileUrl) {
      setState(() {
        openFileUrl = url;
      });
    }
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

推荐阅读