ライブラリを使った方法
pubspec.yamlに以下を追加して
1
2
| dependencies:
receive_sharing_intent: ^1.3.1+1
|
インストール
AndroidManifest.xmlを以下のように変更(受け取るものに応じて要変更。使い方はこちら)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- ↓ こんな感じでintent filterを追加する -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
<!-- ↑ -->
</activity>
|
Flutter内は下記のように書くことで取得できる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // アプリがメモリ内の時
_intentDataStreamSubscription =
ReceiveSharingIntent.getTextStream().listen((String value) {
setState(() {
// valueがintentで受け取ったもの
_sharedText = value;
});
}, onError: (err) {
print("getLinkStream error: $err");
});
// アプリが閉じられている時
ReceiveSharingIntent.getInitialText().then((String value) {
setState(() {
// 上と同じくvalueがintentで受け取ったもの
_sharedText = value;
});
});
|
自分で実装する方法
プラットフォーム固有の処理を行う方法を知っておくために軽く見ておくと良いと思います。
* text/plainのみに対応させる形で実装してあるものです。画像等の処理は追加で記述する必要があります。
AndroidManifest.xmlはライブラリ使う時と同様の変更を行う。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| <activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
|
MainActivity.ktを下記のように変更する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| package com.example.shared;
import android.content.Intent
import android.os.Bundle
import io.flutter.app.FlutterActivity
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity : FlutterActivity() {
private var sharedText: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)
val intent = intent
val action = intent.action
val type = intent.type
// intentとmime typeの判定
if (Intent.ACTION_SEND == action && type != null) {
if ("text/plain" == type) {
handleSendText(intent)
}
}
MethodChannel(flutterView, "app.channel.shared.data").setMethodCallHandler { call, result ->
if (call.method.contentEquals("getSharedText")) {
result.success(sharedText)
sharedText = null
}
}
}
private fun handleSendText(intent: Intent) {
// 文字列を取り出してインスタンス変数に格納
sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
}
}
|
action_sendインテントを受け取り、typeがtext/plainの際に、インスタンス変数に受け取った文字列を保存できるようになっています。
MethodChannelを用いてDart側でgetSharedTextメソッドを呼び出すことで、インスタンス変数に格納した文字列を取得できるような作りです。
Flutter側の実装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
| import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(SampleApp());
}
class SampleApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Sample Shared App Handler',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SampleAppPage(),
);
}
}
class SampleAppPage extends StatefulWidget {
SampleAppPage({Key key}) : super(key: key);
@override
_SampleAppPageState createState() => _SampleAppPageState();
}
class _SampleAppPageState extends State<SampleAppPage> {
// 先程Kotlinで記述したメソッドを呼び出す準備
static const platform = const MethodChannel('app.channel.shared.data');
String dataShared = "No data";
@override
void initState() {
super.initState();
getSharedText();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Center(child: Text(dataShared)));
}
getSharedText() async {
// 先程Kotlinで記述したメソッドの呼び出し
// MainActivityのインスタンス変数に格納されている文字列を取り出している。
var sharedData = await platform.invokeMethod("getSharedText");
if (sharedData != null) {
setState(() {
dataShared = sharedData;
});
}
}
}
|
終わりに
Webの人なのでAndroid全然わからないのだが、PocketやInstapaperみたいに、保存時に画面遷移なくて通知(ToastやSnackbarみたいなもの)を表示する方法を知りたい。ServiceかIntentServiceを使えばできるのか?