Ich habe versucht, nativen Java / Objective-C-Code von Flutter aus aufzurufen

Ich möchte die native API von Flutter aus aufrufen

Probieren Sie native Codeaufrufe von Flutter nach Java (Android) und Objective-C (iOS) mit MethodChannel aus (https://api.flutter.dev/flutter/services/MethodChannel-class.html). Es war.

Ich habe versucht, den unter Schreiben von benutzerdefiniertem plattformspezifischem Code beschriebenen Beispielcode auszuführen. Notieren Sie sich daher den tatsächlichen Ablauf.

Klicken Sie hier für die Kotlin / Swift-Version Ich habe versucht, den nativen Kotlin / Swift-Code von Flutter - Qiita aus aufzurufen

Klicken Sie hier für eine Beispielquelle https://github.com/unsolublesugar/flutter-sample-custom-platform-specific-code-java-objc

Beispielprojekt erstellen

Erstellen Sie zunächst ein Beispielprojekt. Die Beispiel-App implementiert nativen Code, um den Akkuladestand zu ermitteln.

In Flutter v1.9.1 waren die Standard-Muttersprachen Kotlin und Swift. Erstellen Sie daher ein Projekt in Java / Objective-C mit Optionen. $ flutter create -i objc -a java batterylevel

Wenn Sie ein Projekt mit VSCode erstellen, können Sie die verwendete Sprache ändern, indem Sie in den Einstellungen [Erweiterungen] -> [Dart & Flutter] auswählen. Sie können auf die Einstellungen in einer Aufnahme zugreifen, indem Sie nach "Sprache zum Flattern erstellen" suchen. スクリーンショット 2019-11-07 14.18.38.png

Rufen Sie den Code auf der Flatter-Seite an

Fügen Sie die Implementierung des Beispielbildschirm-Widgets und die Methode zur Erfassung des Batteriestands hinzu. Unten ist die Datei "main.dart", die nur ein Auszug aus "MyMomeHagePageState" ist.

main.dart


import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
...
class _MyHomePageState extends State<MyHomePage> {
  static const platform = const MethodChannel('samples.flutter.dev/battery');

  String _batteryLevel = 'Unknown battery level.';

  Future<void> _getBatteryLevel() async {
    // Get battery level.
    String batteryLevel;
    try {
      final int result = await platform.invokeMethod('getBatteryLevel');
      batteryLevel = 'Battery level at $result % .';
    } on PlatformException catch (e) {
      batteryLevel = "Failed to get battery level: '${e.message}'.";
    }

    setState(() {
      _batteryLevel = batteryLevel;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            RaisedButton(
              child: Text('Get Battery Level'),
              onPressed: _getBatteryLevel,
            ),
            Text(_batteryLevel),
          ],
        ),
      ),
    );
  }
}

Die verbleibende Methode zur Erfassung des Batteriestands "getBatteryLevel", die von "MethodChannel" aufgerufen wird, ist auf der Java- bzw. der Objective-C-Seite definiert.

Native Code auf der Java-Seite (Android)

Schreiben wir nun den Java (Android) Code.

Fügen Sie den erforderlichen Import hinzu

Import zu MainActivity.java hinzugefügt.

MainActivity.java


import android.os.Bundle;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;

import io.flutter.app.FlutterActivity;
import io.flutter.plugins.GeneratedPluginRegistrant;
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;

Implementieren Sie getBatteryLevel

Definieren Sie "MethodChannel" in der "onCreate" -Methode von "MainActivity" und rufen Sie "setMethodCallHandler" auf.

MainActivity.java


public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "samples.flutter.dev/battery";

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        GeneratedPluginRegistrant.registerWith(this);

        new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                new MethodCallHandler() {
                    @Override
                    public void onMethodCall(MethodCall call, Result result) {
                    }
                });
    }
}

ここで定義したチャンネル名samples.flutter.dev/batteryを、Flutter側の呼び出しで使用します。

Fügen Sie Code hinzu, um den Akkuladestand Ihres Android-Geräts zu ermitteln.

MainActivity.java



  private int getBatteryLevel() {
    int batteryLevel = -1;
    if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
      BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
      batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
    } else {
      Intent intent = new ContextWrapper(getApplicationContext()).
          registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
      batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
          intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
    }

    return batteryLevel;
  }

Code zum Aufrufen von "getBatteryLevel ()" on "MethodChannel" hinzugefügt.

MainActivity.java


@Override
public void onMethodCall(MethodCall call, Result result) {
    // Note: this method is invoked on the main thread.
    if (call.method.equals("getBatteryLevel")) {
        int batteryLevel = getBatteryLevel();

        if (batteryLevel != -1) {
            result.success(batteryLevel);
        } else {
            result.error("UNAVAILABLE", "Battery level not available.", null);
        }
    } else {
        result.notImplemented();
    }
}

Jetzt können Sie den nativen Java-Code für Android aufrufen.

Auf Emulator ausführen

Wenn Sie den obigen Code auf dem Emulator ausführen, werden die Schaltfläche "Batteriestand abrufen" und der Text "Unbekannter Batteriestand" angezeigt.

batterylevel_objc_java.gif

Den verbleibenden Akkuladestand des Terminals erhalten Sie per Knopfdruck. Die Textanzeige wechselt.

Native Code auf der Objective-C-Seite (iOS)

Als nächstes werde ich den Code für Objective-C (iOS) schreiben. Öffnen Sie den ios-Ordner im Zielprojekt und öffnen Sie "AppDelegate.m" unter dem "Runner" -Ordner.

Implementieren Sie getBatteryLevel

Definiert die Implementierung von MethodChannel wie in Android.

AppDelegate.m


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

@implementation AppDelegate

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

  FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
                                          methodChannelWithName:@"samples.flutter.dev/battery"
                                          binaryMessenger:controller];

  [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
  }];


  [GeneratedPluginRegistrant registerWithRegistry:self];
  // Override point for customization after application launch.
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end

Die Methode zur Erfassung des Batteriestands getBatteryLevel wurde vor @ end hinzugefügt.

AppDelegate.m


- (int)getBatteryLevel {
  UIDevice* device = UIDevice.currentDevice;
  device.batteryMonitoringEnabled = YES;
  if (device.batteryState == UIDeviceBatteryStateUnknown) {
    return -1;
  } else {
    return (int)(device.batteryLevel * 100);
  }
}

Rufen Sie getBatteryLevel mit setMethodCallHandler auf.

AppDelegate.m


__weak typeof(self) weakSelf = self;
  [batteryChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
    if ([@"getBatteryLevel" isEqualToString:call.method]) {
      int batteryLevel = [weakSelf getBatteryLevel];

      if (batteryLevel == -1) {
        result([FlutterError errorWithCode:@"UNAVAILABLE"
                                  message:@"Battery info unavailable"
                                  details:nil]);
      } else {
        result(@(batteryLevel));
      }
    } else {
      result(FlutterMethodNotImplemented);
    }
  }];

Wenn Sie iOS Simulator starten, sehen Sie Schaltflächen und Text wie bei Android. Wenn Sie auf die Schaltfläche tippen, wird "getBatteryLevel ()" über MethodChannel aufgerufen und der Text aktualisiert. batterylevel_objc.gif Da die Batterie-API in iOS Simulator nicht unterstützt wird, wird die Meldung "Batterieinformationen nicht verfügbar" angezeigt. Jetzt können Sie sehen, dass der auf der Objective-C-Seite geschriebene Code funktioniert.

Flutter ist großartig mit einer erschreckenden Menge an offiziellen Unterlagen.

Recommended Posts

Ich habe versucht, nativen Java / Objective-C-Code von Flutter aus aufzurufen
Ich habe versucht, eine Java-Methode von ABCL zu verwenden
Ich habe Drools (Java, InputStream) ausprobiert.
Ich habe versucht, Java REPL zu verwenden
Ich habe versucht, den Quellcode zu analysieren
Ich habe versucht, Metaprogrammierung mit Java
[JDBC] Ich habe versucht, von Java aus auf die SQLite3-Datenbank zuzugreifen.
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, UDP mit Java zu kommunizieren
Ich habe das Java-Framework "Quarkus" ausprobiert.
Ich habe versucht, die Java8 Stream API zu verwenden
Ich habe versucht, JWT in Java zu verwenden
Ich habe versucht, das Java-Lernen zusammenzufassen (1)
Was ich aus Java gelernt habe, funktioniert mit Visual Studio Code
Ich habe jetzt versucht, Java 8 zusammenzufassen
Beispielcode mit Minio aus Java
Ich habe versucht, Java Memo LocalDate zu verwenden
Ich habe versucht, Google HttpClient von Java zu verwenden
Ich habe versucht, die Elasticsearch-API in Java zu verwenden
Ich habe versucht, Processing auf VS Code zu migrieren
Ich habe versucht, UICollectionViewListCell zu verwenden, das von Xcode12 hinzugefügt wurde.
Ich habe Cassandras Object Mapper für Java ausprobiert
Ich habe versucht, Java-Lambda-Ausdrücke zusammenzufassen
Rufen Sie Java von C ++ auf Android NDK auf
Ich habe das neue Yuan-Problem in Java ausprobiert
Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
[Java] Fluss vom Quellcode zur Ausführung
Versuchen Sie, Nim von Java über JNI aufzurufen
Ich habe Googles Aufnahmeprüfung (inoffiziell) [Java] ausprobiert.
Was ich aus der Java-Geldberechnung gelernt habe
Führen Sie Java-Code von cpp auf cocos2dx aus
Ich habe versucht, Java einfach auf meinen Mac zu bringen
R von Java ausführen Ich möchte rJava ausführen
Verwenden Sie native Bibliotheken von Scala über Java CPP + Java
[Rails] Ich habe versucht, die Version von Rails von 5.0 auf 5.2 zu erhöhen
Java Ich habe versucht, einen einfachen Block zu brechen
Versuchen Sie, den CORBA-Dienst von Spring (Java) aus aufzurufen.
[API] Ich habe versucht, die Postleitzahlensuch-API zu verwenden
Ich habe versucht, neunundneunzig in Java auszugeben
Ich möchte schnell von Java nach SQLite schreiben
Ich habe versucht, Alexa-Fähigkeiten mit Java zu erstellen
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, Java in einem Mac-Terminal auszuführen
Ich habe "Visual Studio Code Installer für Java" ausprobiert, mit dem sofort eine Java-Entwicklungsumgebung erstellt werden kann