Skip to content

Conversation

mauriziopinotti
Copy link

Changed all references to FlutterActivity to android.app.Activity.

This fixes the following issues: #287 #283 #281 #209

The solution of changing FlutterActivity to FlutterFragmentActivity has been proposed in various comments but it's not actually needed since the reference is only used to call runOnUiThread() so using android.app.Activity is enough and provides the best compatibility.

@mauriziopinotti
Copy link
Author

@AmolGangadhare @izzyaf @ahmadjehad anyone willing to review/merge this?

Copy link

@kalvarez2 kalvarez2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good clean up

jbpfeifer added a commit to jbpfeifer/flutter_barcode_scanner that referenced this pull request Jan 16, 2023
@mrprogramator
Copy link

Can anyone merge this PR please? this fix is critical for the lib to work in Android. Thanks!!!

@HasanBasheer
Copy link

Hi, the file does not have the change in all the necessary places and is still causing the issue.

This is how I changed it to work for me.

`package com.amolg.flutterbarcodescanner;

import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import com.google.android.gms.common.api.CommonStatusCodes;
import com.google.android.gms.vision.barcode.Barcode;

import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
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.ActivityResultListener;
import io.flutter.plugin.common.EventChannel.StreamHandler;
import io.flutter.embedding.engine.plugins.lifecycle.FlutterLifecycleAdapter;

/**

  • FlutterBarcodeScannerPlugin
    */
    public class FlutterBarcodeScannerPlugin implements MethodCallHandler, ActivityResultListener, StreamHandler, FlutterPlugin, ActivityAware {
    private static final String CHANNEL = "flutter_barcode_scanner";

    private static Activity activity;
    private static Result pendingResult;
    private Map<String, Object> arguments;

    private static final String TAG = FlutterBarcodeScannerPlugin.class.getSimpleName();
    private static final int RC_BARCODE_CAPTURE = 9001;
    public static String lineColor = "";
    public static boolean isShowFlashIcon = false;
    public static boolean isContinuousScan = false;
    static EventChannel.EventSink barcodeStream;
    private EventChannel eventChannel;

    /**

    • V2 embedding
    • @param activity
    • @param registrar
      */
      private MethodChannel channel;
      private FlutterPluginBinding pluginBinding;
      private ActivityPluginBinding activityBinding;
      private Application applicationContext;
      // This is null when not using v2 embedding;
      private Lifecycle lifecycle;
      private LifeCycleObserver observer;

    public FlutterBarcodeScannerPlugin() {
    }

    private FlutterBarcodeScannerPlugin(Activity activity, final PluginRegistry.Registrar registrar) {
    FlutterBarcodeScannerPlugin.activity = activity;
    }

    /**

    • Plugin registration.
      */
      public static void registerWith(final PluginRegistry.Registrar registrar) {
      if (registrar.activity() == null) {
      return;
      }
      Activity activity = registrar.activity();
      Application applicationContext = null;
      if (registrar.context() != null) {
      applicationContext = (Application) (registrar.context().getApplicationContext());
      }
      FlutterBarcodeScannerPlugin instance = new FlutterBarcodeScannerPlugin((Activity) registrar.activity(), registrar);
      instance.createPluginSetup(registrar.messenger(), applicationContext, activity, registrar, null);
      }

    @OverRide
    public void onMethodCall(@nonnull MethodCall call, @nonnull Result result) {
    try {
    pendingResult = result;

         if (call.method.equals("scanBarcode")) {
             if (!(call.arguments instanceof Map)) {
                 throw new IllegalArgumentException("Plugin not passing a map as parameter: " + call.arguments);
             }
             arguments = (Map<String, Object>) call.arguments;
             lineColor = (String) arguments.get("lineColor");
             isShowFlashIcon = (boolean) arguments.get("isShowFlashIcon");
             if (null == lineColor || lineColor.equalsIgnoreCase("")) {
                 lineColor = "#DC143C";
             }
             if (null != arguments.get("scanMode")) {
                 if ((int) arguments.get("scanMode") == BarcodeCaptureActivity.SCAN_MODE_ENUM.DEFAULT.ordinal()) {
                     BarcodeCaptureActivity.SCAN_MODE = BarcodeCaptureActivity.SCAN_MODE_ENUM.QR.ordinal();
                 } else {
                     BarcodeCaptureActivity.SCAN_MODE = (int) arguments.get("scanMode");
                 }
             } else {
                 BarcodeCaptureActivity.SCAN_MODE = BarcodeCaptureActivity.SCAN_MODE_ENUM.QR.ordinal();
             }
    
             isContinuousScan = (boolean) arguments.get("isContinuousScan");
    
             startBarcodeScannerActivityView((String) arguments.get("cancelButtonText"), isContinuousScan);
         }
     } catch (Exception e) {
         Log.e(TAG, "onMethodCall: " + e.getLocalizedMessage());
     }
    

    }

    private void startBarcodeScannerActivityView(String buttonText, boolean isContinuousScan) {
    try {
    Intent intent = new Intent(activity, BarcodeCaptureActivity.class).putExtra("cancelButtonText", buttonText);
    if (isContinuousScan) {
    activity.startActivity(intent);
    } else {
    activity.startActivityForResult(intent, RC_BARCODE_CAPTURE);
    }
    } catch (Exception e) {
    Log.e(TAG, "startView: " + e.getLocalizedMessage());
    }
    }

    /**

    • Get the barcode scanning results in onActivityResult
    • @param requestCode
    • @param resultCode
    • @param data
    • @return
      */
      @OverRide
      public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == RC_BARCODE_CAPTURE) {
      if (resultCode == CommonStatusCodes.SUCCESS) {
      if (data != null) {
      try {
      Barcode barcode = data.getParcelableExtra(BarcodeCaptureActivity.BarcodeObject);
      String barcodeResult = barcode.rawValue;
      pendingResult.success(barcodeResult);
      } catch (Exception e) {
      pendingResult.success("-1");
      }
      } else {
      pendingResult.success("-1");
      }
      pendingResult = null;
      arguments = null;
      return true;
      } else {
      pendingResult.success("-1");
      }
      }
      return false;
      }

    @OverRide
    public void onListen(Object o, EventChannel.EventSink eventSink) {
    try {
    barcodeStream = eventSink;
    } catch (Exception e) {
    }
    }

    @OverRide
    public void onCancel(Object o) {
    try {
    barcodeStream = null;
    } catch (Exception e) {

     }
    

    }

    /**

    • Continuous receive barcode
    • @param barcode
      */
      public static void onBarcodeScanReceiver(final Barcode barcode) {
      try {
      if (barcode != null && !barcode.displayValue.isEmpty()) {
      activity.runOnUiThread(new Runnable() {
      @OverRide
      public void run() {
      barcodeStream.success(barcode.rawValue);
      }
      });
      }
      } catch (Exception e) {
      Log.e(TAG, "onBarcodeScanReceiver: " + e.getLocalizedMessage());
      }
      }

    @OverRide
    public void onAttachedToEngine(FlutterPluginBinding binding) {
    pluginBinding = binding;
    }

    @OverRide
    public void onDetachedFromEngine(FlutterPluginBinding binding) {
    pluginBinding = null;
    }

    @OverRide
    public void onDetachedFromActivityForConfigChanges() {
    onDetachedFromActivity();
    }

    @OverRide
    public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
    onAttachedToActivity(binding);
    }

    /**

    • Setup method

    • Created after Embedding V2 API release

    • @param messenger

    • @param applicationContext

    • @param activity

    • @param registrar

    • @param activityBinding
      */
      private void createPluginSetup(
      final BinaryMessenger messenger,
      final Application applicationContext,
      final Activity activity,
      final PluginRegistry.Registrar registrar,
      final ActivityPluginBinding activityBinding) {

      this.activity = activity;
      eventChannel =
      new EventChannel(messenger, "flutter_barcode_scanner_receiver");
      eventChannel.setStreamHandler(this);

      this.applicationContext = applicationContext;
      channel = new MethodChannel(messenger, CHANNEL);
      channel.setMethodCallHandler(this);
      if (registrar != null) {
      // V1 embedding setup for activity listeners.
      observer = new LifeCycleObserver(activity);
      applicationContext.registerActivityLifecycleCallbacks(
      observer); // Use getApplicationContext() to avoid casting failures.
      registrar.addActivityResultListener(this);
      } else {
      // V2 embedding setup for activity listeners.
      activityBinding.addActivityResultListener(this);
      lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(activityBinding);
      observer = new LifeCycleObserver(activity);
      lifecycle.addObserver(observer);
      }
      }

    @OverRide
    public void onAttachedToActivity(ActivityPluginBinding binding) {
    activityBinding = binding;
    createPluginSetup(
    pluginBinding.getBinaryMessenger(),
    (Application) pluginBinding.getApplicationContext(),
    activityBinding.getActivity(),
    null,
    activityBinding);
    }

    @OverRide
    public void onDetachedFromActivity() {
    clearPluginSetup();
    }

    /**

    • Clear plugin setup
      */
      private void clearPluginSetup() {
      activity = null;
      activityBinding.removeActivityResultListener(this);
      activityBinding = null;
      lifecycle.removeObserver(observer);
      lifecycle = null;
      channel.setMethodCallHandler(null);
      eventChannel.setStreamHandler(null);
      channel = null;
      applicationContext.unregisterActivityLifecycleCallbacks(observer);
      applicationContext = null;
      }

    /**

    • Activity lifecycle observer
      */
      private class LifeCycleObserver
      implements Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {
      private final Activity thisActivity;

      LifeCycleObserver(Activity activity) {
      this.thisActivity = activity;
      }

      @OverRide
      public void onCreate(@nonnull LifecycleOwner owner) {
      }

      @OverRide
      public void onStart(@nonnull LifecycleOwner owner) {
      }

      @OverRide
      public void onResume(@nonnull LifecycleOwner owner) {
      }

      @OverRide
      public void onPause(@nonnull LifecycleOwner owner) {
      }

      @OverRide
      public void onStop(@nonnull LifecycleOwner owner) {
      onActivityStopped(thisActivity);
      }

      @OverRide
      public void onDestroy(@nonnull LifecycleOwner owner) {
      onActivityDestroyed(thisActivity);
      }

      @OverRide
      public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
      }

      @OverRide
      public void onActivityStarted(Activity activity) {
      }

      @OverRide
      public void onActivityResumed(Activity activity) {
      }

      @OverRide
      public void onActivityPaused(Activity activity) {
      }

      @OverRide
      public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
      }

      @OverRide
      public void onActivityDestroyed(Activity activity) {
      if (thisActivity == activity && activity.getApplicationContext() != null) {
      ((Application) activity.getApplicationContext())
      .unregisterActivityLifecycleCallbacks(
      this);
      }
      }

      @OverRide
      public void onActivityStopped(Activity activity) {

      }
      }
      }`

@itsAyyazdev
Copy link

itsAyyazdev commented Nov 25, 2023

use this forked version until the author merges the changes

flutter_barcode_scanner: git: url: https://github.com/itsAyyazdev/flutter_barcode_scanner.git

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants