How to Share an Image on iOS and Android using Flutter ??

· 6 min read
How to Share an Image on iOS and Android using Flutter
How to Share an Image on iOS and Android using Flutter

Sharing content has become very important nowadays. So in this article, we will go through how to Share an Image on iOS and Android using flutter.

How to Share an Image on iOS and Android using Flutter ??

The below will allow you to send a file specifically an image in this example using UIActivityViewController on iOS and as a share intent on Android.

FileProvider overview (Android)

Update pubspec.yaml to reference your image if local image.jpg in this example and to use the path_provider plugin in order to access the file system.

main.dart will have a code snippet like the below:

import 'dart:io';
import 'dart:typed_data';

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

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Share Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Share Demo Home Page'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _shareImage,
        tooltip: 'Share',
        child: new Icon(Icons.share),
      ),
    );
  }

  _shareImage() async {
    try {
      final ByteData bytes = await rootBundle.load('assets/image.jpg');
      final Uint8List list = bytes.buffer.asUint8List();

      final tempDir = await getTemporaryDirectory();
      final file = await new File('${tempDir.path}/image.jpg').create();
      file.writeAsBytesSync(list);

      final channel = const MethodChannel('channel:me.albie.share/share');
      channel.invokeMethod('shareFile', 'image.jpg');

    } catch (e) {
      print('Share error: $e');
    }
  }
}

AppDelegate.m will look like a below:

@implementation AppDelegate

static NSString *const SHARE_CHANNEL = @"channel:me.albie.share/share";

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [GeneratedPluginRegistrant registerWithRegistry:self];
    FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;

    FlutterMethodChannel *shareChannel =
    [FlutterMethodChannel methodChannelWithName:SHARE_CHANNEL
                                binaryMessenger:controller];

    [shareChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
        if ([@"shareFile" isEqualToString:call.method]) {
            [self shareFile:call.arguments
             withController:[UIApplication sharedApplication].keyWindow.rootViewController];
        }
    }];

    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)shareFile:(id)sharedItems withController:(UIViewController *)controller {
    NSMutableString *filePath = [NSMutableString stringWithString:sharedItems];
    NSString *docsPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *imagePath = [docsPath stringByAppendingPathComponent:filePath];
    NSURL *imageUrl = [NSURL fileURLWithPath:imagePath];
    NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
    UIImage *shareImage = [UIImage imageWithData:imageData];

    UIActivityViewController *activityViewController =
    [[UIActivityViewController alloc] initWithActivityItems:@[ shareImage ]
                                      applicationActivities:nil];
    [controller presentViewController:activityViewController animated:YES completion:nil];
}

@end

MainActivity.java

package com.example.share;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

import java.io.File;

import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;

import android.support.v4.content.FileProvider;

public class MainActivity extends FlutterActivity {

    private static final String SHARE_CHANNEL = "channel:me.albie.share/share";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);

        new MethodChannel(this.getFlutterView(), SHARE_CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
            public final void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
                if (methodCall.method.equals("shareFile")) {
                    shareFile((String) methodCall.arguments);
                }
            }
        });
    }

    private void shareFile(String path) {
        File imageFile = new File(this.getApplicationContext().getCacheDir(), path);
        Uri contentUri = FileProvider.getUriForFile(this, "me.albie.share", imageFile);
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("image/jpg");
        shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
        this.startActivity(Intent.createChooser(shareIntent, "Share image using"));
    }
}

AndroidManifest.xml

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="me.albie.share"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path name="images" path="/"/>
</paths>

build.gradle (app)

dependencies {
    ...
    implementation 'com.android.support:support-v4:27.1.1'
}

You can also try with Try using wc_flutter_share

This plugin supports sharing images, text, and subjects.

The unique thing about this plugin is that it also supports sharing images and text simultaneously which other plugins don’t support at the time I am writing this answer.

We can also do it in a Swift like a below:

verride func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
    ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)


    let shareChannelName = "channel:me.albie.share/share";
    let controller:FlutterViewController = self.window?.rootViewController as! FlutterViewController;
    let shareChannel:FlutterMethodChannel = FlutterMethodChannel.init(name: shareChannelName, binaryMessenger: controller);

    shareChannel.setMethodCallHandler({
        (call: FlutterMethodCall, result: FlutterResult) -> Void in
        if (call.method == "shareFile") {
            self.shareFile(sharedItems: call.arguments!,controller: controller);
        }
    });


    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

func shareFile(sharedItems:Any, controller:UIViewController) {
    let filePath:NSMutableString = NSMutableString.init(string: sharedItems as! String);
    let docsPath:NSString = (NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)[0]) as NSString;
    let imagePath = docsPath.appendingPathComponent(filePath as String);
    let imageUrl = URL.init(fileURLWithPath: imagePath, relativeTo: nil);
    do {
        let imageData = try Data.init(contentsOf: imageUrl);
        let shareImage = UIImage.init(data: imageData);
        let activityViewController:UIActivityViewController = UIActivityViewController.init(activityItems: [shareImage!], applicationActivities: nil);
        controller.present(activityViewController, animated: true, completion: nil);
    } catch let error {
        print(error.localizedDescription);
    }
}

Kotlin will have a code snippet like the below:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    GeneratedPluginRegistrant.registerWith(this)

    MethodChannel(flutterView,"channel:me.albie.share/share").setMethodCallHandler { methodCall, _ ->
        if (methodCall.method == "shareFile") {
            shareFile(methodCall.arguments as String)
        }
    }
}

private fun shareFile(path:String) {
    val imageFile = File(this.applicationContext.cacheDir,path)
    val contentUri = FileProvider.getUriForFile(this,"me.albie.share",imageFile)

    val shareIntent = Intent()
    shareIntent.action = Intent.ACTION_SEND
    shareIntent.type="image/jpg"
    shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri)
    startActivity(Intent.createChooser(shareIntent,"Compartir usando"))
}

You can also try by using the following flutter plugin:

https://pub.dartlang.org/packages/share

Text sharing is quite simple:

Share.share('Text I wish to share');

For image: Better convert an image to Base64 string and send as a string.

Conclusion:

Thanks for Reading !!! Don’t forget to leave your feedback below in the comments.

So in this article, we have learned how to share an image on iOS and Android using flutter.

Keep Learning !!! Keep Fluttering !!!

FlutterAgency.com is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget GuideFlutter ProjectsCode libs and etc.

FlutterAgency.com is one of the most popular online portals dedicated to Flutter Technology and daily thousands of unique visitors come to this portal to enhance their knowledge of Flutter.

Leave a Reply