Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 552 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I share an image on iOS and Android using Flutter?

#1
I would like to share an image using the standard share dialogs in iOS and Android. The code below is mostly from

[To see links please register here]

which I'm using as a starting point (only Dart and Objective-C below). It currently shares only text.

Instead of Image below which I'm not sure is the best approach, how would I convert the image to a byte stream in Dart and handle in iOS and Android.


Dart

static const _kShareChannel = const MethodChannel('example.test.com/share');
Future<Null> shareImage(Image image) {
assert(image != null);
return _kShareChannel.invokeMethod('shareImage', image);
}

Objective-C

static NSString *const PLATFORM_CHANNEL = @"example.test.com/share";

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];

FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;

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

[shareChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) {
if ([@"shareImage" isEqualToString:call.method]) {
[self share:call.arguments withController:[UIApplication sharedApplication].keyWindow.rootViewController];
result(nil);
} else {
result([FlutterError errorWithCode:@"UNKNOWN_METHOD"
message:@"Unknown share method called"
details:nil]);
}
}];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

- (void)share:(id)sharedItems withController:(UIViewController *)controller {
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[ sharedItems ]
applicationActivities:nil];
[controller presentViewController:activityViewController animated:YES completion:nil];
}
Reply

#2
If the image file is downloaded, I would recommend saving it to a temporary file in Dart.

await new File('${systemTempDir.path}/foo.jpg').create();

Then you can invoke `UIActivityViewController` with a URL representing the filename of the image file. Here's some [sample code][1] on how to do this in a non-Flutter app that should get you started.

If your image file is constructed dynamically (e.g. using the `Canvas` API), you may be wondering how to encode a [`ui.Image`][2] object into an image file. The Flutter engine doesn't currently provide a way to do that, it would be possible modify the engine to add that support. You can take a look at how [screenshot][3] support is implemented for inspiration, but it won't be trivial.

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

Reply

#3
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)][1]

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.

[To see links please register here]




main.dart

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

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"

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


[1]:

[To see links please register here]

Reply

#4
Thanks to @albert-lardizabal for the code above it works just perfect!! I had to translate it to Swift and Kotlin, so here's the code in case you guys need it:

Swift:

override 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:

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"))
}
Reply

#5
I would suggest using the following flutter plugin:

[To see links please register here]


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.
Reply

#6
We put that functionality into a plugin:

[To see links please register here]

.

Dart:
```
final ByteData bytes = await rootBundle.load('assets/image1.png');
await Share.file('esys image', 'esys.png', bytes.buffer.asUint8List(), 'image/png');
```



Reply

#7
Try using [wc_flutter_share][1].
<br/>
<br/>

[To see links please register here]

<br/>
<br/>
This plugin supports sharing image, text and subject. Unique thing about this plugin is that it also supports sharing image and text simultaneously which other plugins don't support at the time I am writing this answer.

[1]:

[To see links please register here]

Reply

#8
In 2021, you should use [share_plus](

[To see links please register here]

) , the official Share plugin. It's reliable and easy to use.

Import the library.

```
import 'package:share_plus/share_plus.dart';
```

Then invoke the static share method anywhere in your Dart code.

```
Share.share('check out my website

[To see links please register here]

');
```

The share method also takes an optional subject that will be used when sharing to email.

```
Share.share('check out my website

[To see links please register here]

', subject: 'Look what I made!');
```

To share one or multiple files invoke the static shareFiles method anywhere in your Dart code. Optionally you can also pass in text and subject.

```
Share.shareFiles(['${directory.path}/image.jpg'], text: 'Great picture');
Share.shareFiles(['${directory.path}/image1.jpg', '${directory.path}/image2.jpg']);
```
Reply

#9
We have two different cases:
1. The image is already saved in the device
2. The image is on the network like getting the image link from an API or having the image stored online.

For the first case, sharing it is simple using [share_plus][1] plugin like the following:

Share.shareFiles(['path_to_image']);

For the second case, we have to do the following:

- Read the image as bytes
- Write the image to a temporary file
- Share the created image using the method in 1.

The code uses [path_provider][2] to get the temporary directory and the File class used from dart:io so you have to add this to the start `import 'dart:io';`

The code will be like this:

// function to get the local path
Future<String> get _localPath async {
final directory = await getTemporaryDirectory();
return directory.path;
}
// create the file
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/image.jpeg');
}
// write the data to the file
Future<File> writeImage(List<int> bytes) async {
final file = await _localFile;
return file.writeAsBytes(bytes);
}
// the function that you send the link of the image to
shareNetworkImage(String url) async {
final path = await _localPath;
http.Response response = await http.get(url);
await writeImage(response.bodyBytes);
Share.shareFiles(['$path/image.jpg']);
}

It will be used like this:

shareNetworkImage('https://abdulrazakzakieh.com/images/abdul_razak_zakieh.jpg')



[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through