Flutter - Escribir código específico de Android

Flutter proporciona un marco general para acceder a funciones específicas de la plataforma. Esto permite al desarrollador ampliar la funcionalidad del marco Flutter utilizando código específico de la plataforma. Se puede acceder fácilmente a funciones específicas de la plataforma, como cámara, nivel de batería, navegador, etc., a través del marco.

La idea general de acceder al código específico de la plataforma es a través de un protocolo de mensajería simple. El código Flutter, el cliente y el código de la plataforma y el host se vinculan a un canal de mensajes común. El cliente envía un mensaje al anfitrión a través del canal de mensajes. El Anfitrión escucha en el Canal de Mensajes, recibe el mensaje y hace la funcionalidad necesaria y finalmente, devuelve el resultado al Cliente a través del Canal de Mensajes.

La arquitectura de código específica de la plataforma se muestra en el diagrama de bloques que se muestra a continuación:

El protocolo de mensajería utiliza un códec de mensajes estándar (clase StandardMessageCodec) que admite la serialización binaria de valores similares a JSON como números, cadenas, booleanos, etc. La serialización y deserialización funciona de forma transparente entre el cliente y el host.

Escribamos una aplicación simple para abrir un navegador usando el SDK de Android y entendamos cómo

  • Cree una nueva aplicación Flutter en Android Studio, flutter_browser_app

  • Reemplace el código main.dart con el siguiente código:

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(title: 'Flutter Demo Home Page'),
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: null, 
            ), 
         ), 
      ); 
   }
}
  • Aquí, hemos creado un nuevo botón para abrir el navegador y establecer su método onPressed como nulo.

  • Ahora, importe los siguientes paquetes:

import 'dart:async'; 
import 'package:flutter/services.dart';
  • Aquí, services.dart incluye la funcionalidad para invocar código específico de la plataforma.

  • Cree un nuevo canal de mensajes en el widget MyHomePage.

static const platform = const 
MethodChannel('flutterapp.tutorialspoint.com/browser');
  • Escriba un método, _openBrowser para invocar el método específico de la plataforma, el método openBrowser a través del canal de mensajes.

Future<void> _openBrowser() async { 
   try {
      final int result = await platform.invokeMethod(
         'openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         }
      ); 
   } 
   on PlatformException catch (e) { 
      // Unable to open the browser 
      print(e); 
   }
}

Aquí, hemos utilizado platform.invokeMethod para invocar openBrowser (explicado en los próximos pasos). openBrowser tiene un argumento, url para abrir una URL específica.

  • Cambie el valor de la propiedad onPressed de RaisedButton de nulo a _openBrowser.

onPressed: _openBrowser,
  • Abra MainActivity.java (dentro de la carpeta de Android) e importe la biblioteca requerida -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

import io.flutter.app.FlutterActivity; 
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.plugins.GeneratedPluginRegistrant;
  • Escriba un método, openBrowser para abrir un navegador

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = this; 
   if (activity == null) { 
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground 
      activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • Ahora, configure el nombre del canal en la clase MainActivity -

private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
  • Escriba el código específico de Android para configurar el manejo de mensajes en el método onCreate -

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( 
   new MethodCallHandler() { 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      String url = call.argument("url"); 
      if (call.method.equals("openBrowser")) {
         openBrowser(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
});

Aquí, hemos creado un canal de mensajes usando la clase MethodChannel y usamos la clase MethodCallHandler para manejar el mensaje. onMethodCall es el método real responsable de llamar al código específico de la plataforma correcta al verificar el mensaje. El método onMethodCall extrae la URL del mensaje y luego invoca openBrowser solo cuando la llamada al método es openBrowser. De lo contrario, devuelve el método notImplemented.

El código fuente completo de la aplicación es el siguiente:

main.dart

MainActivity.java

package com.tutorialspoint.flutterapp.flutter_browser_app; 

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant; 

public class MainActivity extends FlutterActivity { 
   private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser"; 
   @Override 
   protected 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) {
               String url = call.argument("url"); 
               if (call.method.equals("openBrowser")) { 
                  openBrowser(call, result, url); 
               } else { 
                  result.notImplemented(); 
               }
            }
         }
      ); 
   }
   private void openBrowser(MethodCall call, Result result, String url) {
      Activity activity = this; if (activity == null) {
         result.error(
            "ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null
         ); 
         return; 
      } 
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   }
}

main.dart

import 'package:flutter/material.dart'; 
import 'dart:async'; 
import 'package:flutter/services.dart'; 

void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget {
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   static const platform = const MethodChannel('flutterapp.tutorialspoint.com/browser'); 
   Future<void> _openBrowser() async {
      try {
         final int result = await platform.invokeMethod('openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         });
      }
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      } 
   }
   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar( 
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: _openBrowser, 
            ), 
         ),
      );
   }
}

Ejecute la aplicación y haga clic en el botón Abrir navegador y podrá ver que se inicia el navegador. La aplicación del navegador - La página de inicio es como se muestra en la captura de pantalla aquí -