Open devmenezes opened 4 years ago
Some change?
Try Android Studio>File>Invalidate caches and restart
I am experiencing the same issue with the latest version of the Flutter master channel and it looks like it could be related to this. It looks like the Android platform of this plugin needs to be updated to implement both FlutterPlugin
and MethodCallHandler
in order to support the two different methods of plugin registration. I have been able to make a start on adding support for these two different methods of plugin registration, however I have unfortunately hit a blocker on the FlutterView
because it has since been deprecated.
package mt.innovation.screenshotshareimage;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StrictMode;
import android.util.Log;
import android.view.View;
import java.io.File;
import java.io.FileOutputStream;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar;
import io.flutter.view.FlutterView;
import android.widget.Toast;
/** ScreenshotShareImagePlugin */
public class ScreenshotShareImagePlugin implements ActivityAware, FlutterPlugin, MethodCallHandler {
private static final String TAG = "ScreenshotShareImagePlugin";
private Registrar registrar;
private Activity activity;
private FlutterView flutterView;
private MethodChannel channel;
private final int WRITE_ACCESS_REQUEST_ID = 12;
private ScreenshotShareImagePlugin(Registrar registrar, Activity activity, FlutterView flutterView, MethodChannel channel) {
this.registrar = registrar;
this.activity = activity;
this.flutterView = flutterView;
this.channel = channel;
this.channel.setMethodCallHandler(this);
setRequestPermissionListener();
}
public ScreenshotShareImagePlugin() {}
private void setRequestPermissionListener() {
registrar.addRequestPermissionsResultListener(new PluginRegistry.RequestPermissionsResultListener() {
@Override
public boolean onRequestPermissionsResult(int i, String[] strings, int[] ints) {
if (i == WRITE_ACCESS_REQUEST_ID) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (activity.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
takeScreenshot("screenshot");
return true;
} else {
activity.requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 11);
return false;
}
}
}
return false;
}
});
}
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
channel = new MethodChannel(binding.getBinaryMessenger(), "screenshot_share_image");
}
@Override
public void onDetachedFromEngine(FlutterPluginBinding binding) {}
@Override
public void onAttachedToActivity(ActivityPluginBinding binding) {
activity = binding.getActivity();
channel.setMethodCallHandler(this);
}
@Override
public void onDetachedFromActivityForConfigChanges() {
activity = null;
}
@Override
public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
activity = binding.getActivity();
}
@Override
public void onDetachedFromActivity() {
activity = null;
channel.setMethodCallHandler(null);
}
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
// plugin registration via this function while apps migrate to use the new Android APIs
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
//
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
// in the same class.
public static void registerWith(Registrar registrar) {
final MethodChannel channel = new MethodChannel(registrar.messenger(), "screenshot_share_image");
channel.setMethodCallHandler(new ScreenshotShareImagePlugin(registrar, registrar.activity(), registrar.view(), channel));
}
@Override
public void onMethodCall(MethodCall call, Result result) {
if (call.method.equals("takeScreenshotAndShare")) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activity.requestPermissions(new String[]{ android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_ACCESS_REQUEST_ID);
} else {
takeScreenshot("screenshot");
}
} else {
result.notImplemented();
}
}
private void takeScreenshot(String fileName) {
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/" + fileName + ".jpg";
Bitmap bitmap = flutterView.getBitmap();
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
e.printStackTrace();
}
}
private void openScreenshot(File imageFile) {
StrictMode.VmPolicy.Builder builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(imageFile);
intent.setDataAndType(uri, "image/*");
activity.startActivity(intent);
}
}
I was having the same error and in my case adding this to the application tag inside the manifest.xml file:
android:requestLegacyExternalStorage="true"
and this to the info.plist file:
`
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>`
solved it.
Throws it:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method takeScreenshotAndShare on channel screenshot_share_image)
Full stack if you need...
Performing hot restart... Syncing files to device ASUS X00TDB... Restarted application in 1,905ms. E/flutter ( 9891): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method takeScreenshotAndShare on channel screenshot_share_image) E/flutter ( 9891): #0 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:154:7) E/flutter ( 9891):
E/flutter ( 9891): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:329:12)
E/flutter ( 9891): #2 ScreenshotShareImage.takeScreenshotShareImage (package:screenshot_share_image/screenshot_share_image.dart:11:20)
E/flutter ( 9891): #3 ResultPage_State._botaoCompartilhar. (package:calculodeimc/result_page.dart:219:32)
E/flutter ( 9891): #4 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:14)
E/flutter ( 9891): #5 _InkResponseState.build. (package:flutter/src/material/ink_well.dart:862:36)
E/flutter ( 9891): #6 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter ( 9891): #7 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter ( 9891): #8 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter ( 9891): #9 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:236:7)
E/flutter ( 9891): #10 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:156:27)
E/flutter ( 9891): #11 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:222:20)
E/flutter ( 9891): #12 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter ( 9891): #13 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter ( 9891): #14 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter ( 9891): #15 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter ( 9891): #16 _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter ( 9891): #17 _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter ( 9891): #18 _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter ( 9891): #19 _invoke1 (dart:ui/hooks.dart:275:10)
E/flutter ( 9891): #20 _dispatchPointerDataPacket (dart:ui/hooks.dart:184:5)
E/flutter ( 9891):