J'ai essayé d'appeler du code natif Java / Objective-C depuis Flutter

Je souhaite appeler l'API native de Flutter

Essayez les appels de code natif de Flutter vers Java (Android) et Objective-C (iOS) à l'aide de MethodChannel (https://api.flutter.dev/flutter/services/MethodChannel-class.html) C'était.

J'ai essayé d'exécuter l'exemple de code décrit dans Écriture de code personnalisé spécifique à la plate-forme, alors notez le flux réel.

Cliquez ici pour la version Kotlin / Swift J'ai essayé d'appeler le code natif de Kotlin / Swift depuis Flutter --Qiita

Cliquez ici pour la source de l'échantillon https://github.com/unsolublesugar/flutter-sample-custom-platform-specific-code-java-objc

Créer un exemple de projet

Commencez par créer un exemple de projet. L'exemple d'application implémente du code natif pour obtenir le niveau de batterie.

Dans Flutter v1.9.1, les langages natifs par défaut étaient Kotlin et Swift, créez donc un projet en Java / Objective-C avec des options. $ flutter create -i objc -a java batterylevel

Si vous créez un projet avec VSCode, vous pouvez changer la langue utilisée en sélectionnant [Extensions] -> [Dart & Flutter] dans les paramètres. Vous pouvez accéder aux paramètres d'un seul coup en recherchant "Flutter create language". スクリーンショット 2019-11-07 14.18.38.png

Indicatif d'appel côté Flutter

Ajoutez l'implémentation de l'exemple de widget d'écran et la méthode d'acquisition du niveau de batterie. Vous trouverez ci-dessous le fichier main.dart, qui est un extrait de seulement _MyHomePageState.

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),
          ],
        ),
      ),
    );
  }
}

La méthode d'acquisition du niveau de batterie restant getBatteryLevel appelée par MethodChannel est définie sur les côtés Java et Objective-C, respectivement.

Code natif côté Java (Android)

Écrivons maintenant le code Java (Android).

Ajouter l'importation requise

Ajout de l'importation à MainActivity.java.

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;

Implémenter getBatteryLevel

Définissez MethodChannel dans la méthode ʻonCreate de MainActivity et appelez setMethodCallHandler.

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側の呼び出しで使用します。

Ajoutez du code pour obtenir le niveau de batterie de votre appareil Android.

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;
  }

Ajout de code pour appeler getBatteryLevel () on MethodChannel.

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();
    }
}

Vous êtes maintenant prêt à appeler le code natif Java pour Android.

Exécuter sur l'émulateur

Si vous construisez exécutez le code ci-dessus sur l'émulateur, vous verrez le bouton "Obtenir le niveau de batterie" et le "Niveau de batterie inconnu." Texte.

batterylevel_objc_java.gif

Obtenez le niveau de batterie restant du terminal en appuyant simplement sur un bouton. L'affichage du texte change.

Code natif côté Objective-C (iOS)

Ensuite, j'écrirai le code pour Objective-C (iOS). Ouvrez le dossier ios dans le projet cible et ouvrez ʻAppDelegate.m sous le dossier Runner`.

Implémenter getBatteryLevel

Définit l'implémentation de MethodChannel comme dans 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

Ajout de la méthode d'acquisition du niveau de batterie getBatteryLevel avant @ end.

AppDelegate.m


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

Appelez getBatteryLevel avec setMethodCallHandler.

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);
    }
  }];

Lorsque vous lancez iOS Simulator, vous verrez des boutons et du texte comme Android. Lorsque vous appuyez sur le bouton, getBatteryLevel () est appelé via MethodChannel et le texte est mis à jour. batterylevel_objc.gif Étant donné que l'API de la batterie n'est pas prise en charge sur iOS Simulator, le message "Informations sur la batterie non disponibles" s'affiche. Vous pouvez maintenant voir que le code écrit du côté Objective-C fonctionne.

Flutter est génial avec une quantité terrifiante de documentation officielle.

Recommended Posts

J'ai essayé d'appeler du code natif Java / Objective-C depuis Flutter
J'ai essayé de frapper une méthode Java d'ABCL
J'ai essayé Drools (Java, InputStream)
J'ai essayé d'utiliser Java REPL
J'ai essayé l'analyse du code source
J'ai essayé la métaprogrammation avec Java
[JDBC] J'ai essayé d'accéder à la base de données SQLite3 depuis Java.
J'ai essayé d'interagir avec Java
J'ai essayé la communication UDP avec Java
J'ai essayé le framework Java "Quarkus"
J'ai essayé d'utiliser l'API Java8 Stream
J'ai essayé d'utiliser JWT en Java
J'ai essayé de résumer l'apprentissage Java (1)
Ce que j'ai appris en travaillant Java avec Visual Studio Code
J'ai essayé de résumer Java 8 maintenant
Exemple de code utilisant Minio de Java
J'ai essayé d'utiliser le mémo Java LocalDate
J'ai essayé d'utiliser Google HttpClient de Java
J'ai essayé d'utiliser l'API Elasticsearch en Java
J'ai essayé de migrer le traitement vers VS Code
J'ai essayé d'utiliser UICollectionViewListCell ajouté à partir de Xcode12.
J'ai essayé le mappeur d'objets de Cassandra pour Java
J'ai essayé de résumer les expressions Java lambda
Appeler java depuis C ++ sur Android NDK
J'ai essayé le nouveau yuan à Java
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
[Java] Flux du code source à l'exécution
Essayez d'appeler Nim depuis Java via JNI
J'ai essayé l'examen d'entrée de Google (non officiel) [java]
Ce que j'ai appris du calcul monétaire Java
Exécutez du code Java à partir de cpp sur cocos2dx
J'ai essayé de mettre facilement Java sur mon Mac
Exécuter R à partir de Java Je veux exécuter rJava
Utiliser les bibliothèques natives de Scala via Java CPP + Java
[Rails] J'ai essayé de faire passer la version de Rails de 5.0 à 5.2
java j'ai essayé de casser un simple bloc
Essayez d'appeler le service CORBA depuis Spring (Java)
[API] J'ai essayé d'utiliser l'API de recherche par code postal
J'ai essayé de sortir quatre-vingt-dix-neuf en Java
Je veux écrire rapidement de java vers sqlite
J'ai essayé de créer une compétence Alexa avec Java
J'ai essayé de casser le bloc avec java (1)
J'ai essayé d'exécuter Java dans un terminal Mac
J'ai essayé «Visual Studio Code Installer pour Java» qui peut créer immédiatement un environnement de développement Java