Reputation: 1805
When a user tries to open an audio file from his/her file manager I want to show him/her my app in the following "In which app to open this file" pop-up window. After (s)he selects my app from the pop-up window, I want to pass file path into a state variable (currentSong
).
I've already managed to add the following IntentFilter into my AndroidManifest.xml. This should correctly show the user my app in the pop-up window:
<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>
But now I'm just clueless. How to get the file path and save it into the state variable currentSong
in Flutter?
Upvotes: 6
Views: 3075
Reputation: 1678
You need using ChannelPlatform
to do that:
1. Android side:
Handle onCreate + onNewIntent to get bundle data from File Viewer App that share audio file's path
2. Flutter side:
get audio file's path and do something...
Demo:
Example:
Android
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
}
}
}
Flutter:
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();
}
Upvotes: 8