💭

【Flutter】テキストやファイルを共有する方法

2025/02/27に公開

はじめに

アプリでシェア機能を実装する際、テキストだけでなく画像やファイルなど様々なコンテンツを共有できると便利です。個人開発アプリで取り入れるため、簡単にまとめておきます。

実装例

サンプルコード

https://github.com/muranakar/share_sample

ライブラリ

https://pub.dev/packages/share_plus

基本的なテキスト共有の実装

基本的なテキスト共有から実装です。メッセージを共有する場合によく使用されます。

static void shareText() {
  Share.share(
    'Flutter開発に関する情報はこちら https://example.com',
    subject: '興味深い記事を見つけました!',
  );
}
  • Share.shareメソッドを使用して簡単に共有できます
  • subjectパラメータは共有のタイトルとして表示されます。

ローカルファイルの共有機能

アプリ内で生成したファイルを共有する場合は、以下のような実装が必要です。

static Future<void> shareLocalFile() async {
  try {
    // アプリのドキュメントディレクトリのパスを取得
    final directory = await getApplicationDocumentsDirectory();
    final filePath = '${directory.path}/hello.txt';

    // ファイルを作成し、内容を書き込む
    final file = File(filePath);
    await file.writeAsString('Hello from Flutter!');

    // 共有用のXFileオブジェクトを作成
    final xFile = XFile(filePath);
    final result = await Share.shareXFiles(
      [xFile],
      text: 'テキストファイルを共有します',
    );
  } catch (e) {
    print('ファイル共有でエラーが発生しました: $e');
  }
}
  • getApplicationDocumentsDirectory()でアプリ固有のディレクトリを取得
  • Fileクラスを使用してファイルの作成と書き込みを行う
  • XFileオブジェクトに変換して共有する
XFile とは?
  • XFile は、Flutters cross-platform file representation(クロスプラットフォームのファイル表現)として設計されています。
  • iOS と Android で異なるファイルシステムの違いを抽象化し、統一的なインターフェースを提供します。

https://pub.dev/packages/cross_file

通信で取得した画像の共有実装

通信で取得した画像を共有する場合は、一度ダウンロードしてから共有する必要があります。

static Future<void> shareImage() async {
  try {
    // オンライン画像のダウンロード
    final imageUrl = 'https://example.com/image.jpg';
    final response = await http.get(Uri.parse(imageUrl));

    // 一時ディレクトリに画像を保存
    final directory = await getTemporaryDirectory();
    final imagePath = '${directory.path}/shared_image.jpg';
    final imageFile = File(imagePath);
    await imageFile.writeAsBytes(response.bodyBytes);

    // MIMEタイプを指定してXFileを作成
    final xFile = XFile(
      imagePath,
      mimeType: 'image/jpeg',
    );
    await Share.shareXFiles([xFile]);
  } catch (e) {
    print('画像共有でエラーが発生しました: $e');
  }
}
  • httpパッケージを使用して画像をダウンロード
  • 一時ディレクトリ(getTemporaryDirectory())を使用して画像を保存
  • 適切な MIME タイプを指定
MIME タイプとは?

https://www.tohoho-web.com/wwwxx015.htm

では以下の説明がありました。

Web の世界では拡張子という概念と、もうひとつ『MIME タイプ』という概念があります。MIME タイプとは「タイプ名/サブタイプ名」の形式の文字列で、WEB サーバーと WEB ブラウザの間はこの MIME タイプを用いてデータの形式を指定しています。例えば MIME タイプには以下のようなものがあります。

複数ファイルの共有機能

複数のファイルを一度に共有する実装方法です。

static Future<void> shareMultipleFiles() async {
  try {
    final directory = await getApplicationDocumentsDirectory();

    // テキストファイルの作成
    final textFile = File('${directory.path}/note.txt');
    await textFile.writeAsString('テキストメモ');

    // JSONファイルの作成
    final jsonFile = File('${directory.path}/data.json');
    await jsonFile.writeAsString('{"message": "JSONデータ"}');

    // 複数のXFileオブジェクトを作成
    final files = [
      XFile(textFile.path, mimeType: 'text/plain'),
      XFile(jsonFile.path, mimeType: 'application/json'),
    ];
    final result = await Share.shareXFiles(files);
  } catch (e) {
    print('複数ファイル共有でエラーが発生しました: $e');
  }
}
  • 各ファイルに適切な MIME タイプを設定する
  • 複数ファイルはリストとしてまとめて共有する

アプリ内アセットの共有機能

アプリに組み込まれた画像など、アセットファイルを共有する場合の実装です。

static Future<void> shareAssetImage() async {
  try {
    // アセットから画像データを読み込む
    final byteData = await rootBundle.load('assets/icon.jpeg');

    // 一時ディレクトリに画像を保存
    final directory = await getTemporaryDirectory();
    final imagePath = '${directory.path}/icon.jpeg';
    final imageFile = File(imagePath);
    await imageFile.writeAsBytes(byteData.buffer.asUint8List());

    // MIMEタイプを指定してXFileを作成
    final xFile = XFile(
      imagePath,
      mimeType: 'image/jpeg',
    );
    await Share.shareXFiles([xFile]);
  } catch (e) {
    print('アセット画像共有でエラーが発生しました: $e');
  }
}
  • rootBundleを使用してアセットにアクセス
  • バイトデータを一時ファイルとして保存
  • 適切な MIME タイプの指定を忘れずに

URL を共有

static Future<ShareResult> shareUri(
    Uri uri, {
    Rect? sharePositionOrigin,
  }) async {
    return Share.shareUri(
      uri,
      sharePositionOrigin: sharePositionOrigin,
    );
  }
  • URL を指定することによって、システムが HTML ページを取得し、アイコンを抽出して表示

以上になります。

Discussion