How do I pass the value of a variable from a plugin to a project?

Viewed 235

I am creating a plugin for Android on Ionic/Angular. I don't know a way to pass the value of a variable from an android application (QRData from BroadcastReceiver) to the code of my project (call.resolve(ret)). Now the QR-code is scanned in the application and its decryption is displayed in the console of the Android Studio. And I want to work with this qr-code in the code of the angular-project / ionic-application (for example, based on the decoding of the QR - display information on it on the screen). The ionic application works on a "Sunmi L2" phone with a built-in infrared QR-code reader, so I am writing the ionic plugin myself.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.getcapacitor.PluginMethod;
import com.getcapacitor.annotation.CapacitorPlugin;

@CapacitorPlugin(name = "ScannerQR")
public class ScannerQRPlugin extends Plugin {

    BroadcastReceiver QRCODE_SUNMI = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Think of a way to pass 'call' to code; and so - everything works
            String QRData = intent.getStringExtra("data");
            Log.d("SCAN_QR", QRData);
            // TODO Need a way to pass QRData to the Angular-project code
        }
    };

    @PluginMethod
    public void echo(PluginCall call) {
        try {
            getContext().unregisterReceiver(QRCODE_SUNMI);
        } catch (Exception ex) {
            Log.i("unregisterReceiver", "Ignore Disabling Receiver");
        }
        getContext().registerReceiver(QRCODE_SUNMI, new IntentFilter("com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED"));

        JSObject ret = new JSObject();
        ret.put("value", "Any text from application to Angular-project");
        call.resolve(ret);
    }
}

Tell me how to do this?

2 Answers

You don't need to call call.resolve() or call.reject() immediately. You can just save this value and resolve/reject it later.

@CapacitorPlugin(name = "ScannerQR")
public class ScannerQRPlugin extends Plugin {
    private PluginCall savedCall;

    BroadcastReceiver QRCODE_SUNMI = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String QRData = intent.getStringExtra("data");
            JSObject ret = new JSObject();

            if (QRData != null && savedCall != null) {
                ret.put("value", QRData);
                call.resolve(ret);
            }
        }
    };

    @PluginMethod
    public void echo(PluginCall call) {
        try {
            getContext().unregisterReceiver(QRCODE_SUNMI);
        } catch (Exception ex) {
            Log.i("unregisterReceiver", "Ignore Disabling Receiver");
        }
        getContext().registerReceiver(QRCODE_SUNMI, new IntentFilter("com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED"));
        savedCall = call;
    }
}

All the same, I found the optimal solution for transferring data from the application to the project code. Used for this - Plugin Events. Code ScannerQRPlugin.java:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.getcapacitor.JSObject;
import com.getcapacitor.Plugin;
import com.getcapacitor.annotation.CapacitorPlugin;

@CapacitorPlugin(name = "ScannerQR")
public class ScannerQRPlugin extends Plugin {

    private final BroadcastReceiver QRCODE_SUNMI = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String QRData = intent.getStringExtra("data");
            notifyListeners("BroadcastReceiverEvent", new JSObject().put("result", QRData));
        }
    };

    @Override
    public void load() {
        super.load();

        try {
            getContext().unregisterReceiver(QRCODE_SUNMI);
        } catch (Exception ignored) {
        }
        getContext().registerReceiver(QRCODE_SUNMI, new IntentFilter("com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED"));
    }
}

Code definitions.ts:

import type { PluginListenerHandle } from '@capacitor/core';
export interface ScannerQRPlugin {
  addListener(eventName: 'BroadcastReceiverEvent', listenerFunc: (QRCode: { resultScan: string }) => void): PluginListenerHandle;
} 

Code index.ts:

import { registerPlugin } from '@capacitor/core';
import type { ScannerQRPlugin } from './definitions';
const ScannerQR = registerPlugin<ScannerQRPlugin>('ScannerQR', {
  web: () => import('./web').then(m => new m.ScannerQRWeb()),
});
export * from './definitions';
export { ScannerQR }; 

Code web.ts:

import { WebPlugin } from '@capacitor/core';
import type { ScannerQRPlugin } from './definitions';
export class ScannerQRWeb extends WebPlugin implements ScannerQRPlugin {
} 

Code home.page.ts:

import {Component} from '@angular/core';
import {ScannerQR} from 'sunmi';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss']
})
export class HomePage {
  result = null;
  valueFromPhone = 'пока не сканирован';
  myPluginEventListener: any;

  constructor() {
    this.initializeSunmiScanner();
  }

  async initializeSunmiScanner() {
    this.myPluginEventListener = await ScannerQR.addListener(
      'BroadcastReceiverEvent',
      (result: any) => {
        this.valueFromPhone = result.result;
        console.log(this.valueFromPhone);
      },
    );
  }
}

In variable this.valueFromPhone contains the required QR-Code.

Related